npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@beyland/piper

v0.2.0

Published

A meta-harness for designing durable loops that prompt coding agents

Readme

Piper

Piper is a meta-harness for designing loops that prompt coding agents.

It does not replace Pi, Claude, Codex, Copilot, Cursor, or other coding agent harnesses. It coordinates them through explicit roles, prompts, artifacts, evaluators, policies, retries, feedback, and stopping conditions.

Install

pnpm add -D @beyland/piper
npm install --save-dev @beyland/piper

The package provides:

  1. A TypeScript SDK for defining reusable agent loops
  2. A piper CLI for running, previewing, generating, and inspecting loop files

At a glance

Piper aims to give coding-agent work the structure that meta-frameworks give web applications.

In the same way Svelte provides reactive rendering primitives and SvelteKit adds the application harness around those primitives (routing, data loading, mutation flows, deployment assumptions, and conventions for how work moves through the system), Piper plays a similar role for coding agents by providing orchestration, artifacts, quality checks, retries, and handoffs.

In a filename.piper.ts file, you can create declarative, structured, reproducible loops that define agent based workflows.

import { agent, artifact, evaluate, loop, repeat, step } from "@beyland/piper";

const plan = artifact("plan", "plan");

export default loop(
	{
		objective: "Implement OAuth login safely",
		agents: [
			agent("planner", { harness: "copilotcli" }),
			agent("implementer", { harness: "copilotcli" }),
		],
	},
	step({
		role: "planner",
		goal: "Create an OAuth implementation plan",
		produces: plan,
	}),
	repeat(
		{ maxAttempts: 3, until: ["pnpm test"] },
		step({
			role: "implementer",
			goal: "Implement or revise the OAuth change",
			context: [plan],
		}),
		evaluate({
			name: "tests pass",
			using: "pnpm test",
			feedback: "Tests failed; revise the implementation using the failure output.",
		}),
	),
);

Artifacts persist by default to ~/.piper/runs/<run-id>/artifacts.json. Each run records artifacts, feedback, events, and a summary.

Use artifact objects in context rather than raw strings when a value should come from a prior step. Plain strings in context are treated as literal context, while produces accepts either an artifact object or an artifact name.

const plan = artifact("plan", "plan");

step({ goal: "Create a plan", harness: "copilotcli", produces: plan });
step({ goal: "Implement the plan", harness: "copilotcli", context: [plan] });

Core primitives

  • loop — top-level objective, agents, child nodes, and stop conditions
  • agent — named role with harness/model preferences, capabilities, instructions, and constraints
  • artifact — named durable output passed between steps; the optional type label is descriptive metadata
  • step — one role-bound agent action with context, expected output, and validations
  • evaluate — command, predicate, or runtime quality check
  • repeat — explicit iteration until checks pass or attempts are exhausted
  • parallel — concurrent investigation or decomposition branches; use failureMode: "collect" to wait for all branches before reporting failures
  • policy — guardrails for constraints and protected files
  • runtimeValue — structured runtime data; step context resolution is reported before the harness starts so expensive runtime values are visible and cancellable

Composition with TypeScript functions

Piper supports two levels of composition:

  1. Core primitives such as step, parallel, repeat, policy, and evaluate
  2. Functions that package reusable orchestration patterns without hiding control flow

Teams define reusable loop pieces as normal TypeScript functions. See examples/composition-functions.piper.ts for a larger example.

import { artifact, evaluate, loop, repeat, step, type LoopTree } from "@beyland/piper";

const plan = artifact("plan", "plan");

function sharedPlan({ goal, children }: { goal: string; children: LoopTree }) {
	return loop(
		step({
			role: "planner",
			goal,
			produces: plan,
		}),
		children,
	);
}

function repairUntilTestsPass({ command, children }: { command: string; children: LoopTree }) {
	return repeat(
		{ maxAttempts: 3, until: [command] },
		children,
		evaluate({
			name: "tests pass",
			using: command,
			feedback: "Revise only the changes from this loop.",
		}),
	);
}

export default sharedPlan({
	goal: "Plan the checkout reliability change",
	children: repairUntilTestsPass({
		command: "pnpm test -- checkout",
		children: step({
			role: "implementer",
			goal: "Implement the planned checkout change",
			context: [plan],
		}),
	}),
});

Composition functions remain transparent: they return the same loop tree as core primitives, preserve artifacts and policies, and can be previewed by the CLI.

Runtime values can be created with either a compact resolver form or an object form when dependencies and descriptions improve readability.

runtimeValue({
	description: "read package metadata",
	dependencies: [],
	resolve: async ({ workspacePath }) => `${workspacePath}/package.json`,
});

Run with the CLI

piper examples/simple-loop.piper.ts --workspace .
piper examples/simple-loop.piper.ts --dry-run
piper examples/simple-loop.piper.ts --print-compiled

Generate an inspectable loop file from a prompt:

piper "Plan and implement a small bug fix" --workspace . --output generated.piper.ts
piper "Draft a release train loop" --save-only
piper "Fix failing tests" --dry-run-generated
piper "Fix failing tests" --execute

Use --harness <name> to choose the authoring harness. It defaults to copilotcli.

AHP providers

Piper executes agent work through Agent Host Protocol (AHP). Harness names in loop files are AHP provider names, and the CLI registers one provider by default: copilotcli.

pnpm exec piper examples/simple-loop.piper.ts --workspace .
PIPER_AHP_PROVIDER=copilotcli pnpm exec piper examples/simple-loop.piper.ts --workspace .

Use PIPER_AHP_ADDRESS to connect to an existing Agent Host, PIPER_AHP_CODE_COMMAND to choose the VS Code command used for auto-start, and PIPER_AHP_AUTO_START=0 to require an explicit Agent Host address.

SDK usage

import { AhpHarness, PiperOrchestrator, loop, step } from "@beyland/piper";

const orchestrator = new PiperOrchestrator({
	workspacePath: process.cwd(),
	harnesses: [new AhpHarness({ provider: "copilotcli" })],
});

const summary = await orchestrator.execute(
	loop(
		{ objective: "Run an AHP-backed loop" },
		step({ goal: "Produce a result", harness: "copilotcli", produces: "result" }),
	),
);

console.log(summary.artifacts.result);

SDK hooks expose run events, step progress, retries, feedback, and summaries so Piper can integrate into local tooling, CI, or product surfaces.

Guardrails

Policies pass constraints and protected files to harnesses and enforce protected-file checks after step attempts.

policy(
	{
		name: "safe migration boundary",
		protectedFiles: ["infra/production.tf"],
		constraints: ["do not deploy or rotate secrets"],
	},
	step({ goal: "Prepare migration plan", harness: "copilotcli" }),
);

For architecture details, read ARCHITECTURE.md.