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

@yaag/extension

v0.27.0

Published

The yaag pi extension: run Orchestration Programs from a pi session.

Readme

@yaag/extension

The yaag pi extension: run Orchestration Programs from a pi session.

It is loaded by pi through jiti, in Node, and bridges to the yaag CLI, which runs on Bun (ADR-0005, ADR-0015).

Docs

The package ships the user and agent docs in docs/:

Prerequisites

Bun is required. The extension itself runs in pi's Node process, but every Orchestration Program runs on Bun. Bun must be on PATH, or at ~/.bun/bin/bun:

curl -fsSL https://bun.sh/install | bash

A missing Bun is reported once, when the extension loads, naming what to install — never as an ENOENT at the first tool call.

Install

pi install ./packages/extension     # from the monorepo root

Pi records the local path without copying, so the workspace:* dependency on the CLI resolves through the monorepo's node_modules. No publish, no bundle, no version bump.

For a throwaway session instead: pi -e ./packages/extension.

What it provides

yaag_run

| Parameter | Type | Meaning | |---|---|---| | file | string? | Path to the Orchestration Program file | | script | string? | Orchestration Program source text (Inline Program) | | args | string? | The program's arguments, as a JSON object string | | background | boolean? | Start the Run in the background and return its Run id | | record | string? | Write this Run's Cassette artifact to this path | | resume | string? | Replay a matching Cassette prefix, then continue live; alone it resumes a stored Inline Program |

Give file or script, and not both; a violation is a parameter error raised before any process starts. A script program can import @yaag/runtime and typebox only (ADR-0033). The source travels to the CLI on a descriptor, and never through the process argument list (ps, /proc/<pid>/cmdline), which every local user can read. The durable Run record keeps the source, so the record directory is 0700 and each record file is 0600. To resume an inline Run, give resume and give no file and no script: yaag reads the source back from the Run record whose Checkpoint path matches, and gives it to the CLI again, so the program identity check keeps its meaning (ADR-0033). Give script again only to change the program. A Cassette that you ask for with record also embeds the source, and it is written owner-only, with mode 0600 (ADR-0021).

Blocking by default: the call returns when the Run ends, and its content is the Run's return value. With background: true it returns at once with a short Run id (r1, r2, …) and the result arrives later as a follow-up message that triggers a turn. Background Runs may overlap; each has its own id and stop handle.

The model sees only the Run's value (or the id). The user additionally sees the Run Summary — program, Agents, Asks settled, cost — refreshed after every Lifecycle Event. Blocking completion and yaag_stop report token usage on pi's nested-usage channel. Natural background completion is the exception: pi custom follow-ups have no usage field, so their summaries remain available for rendering without changing Host Session token or cost totals.

yaag_describe

| Parameter | Type | Meaning | |---|---|---| | file | string | Path to the Orchestration Program file | | exportName | string | Describe this named export as an Agent Definition instead of the program |

With exportName it returns the Definition's declared metadata, any name deviation, and any entry-level finding. A finding is reported in the result and is not a failure.

Returns the program's declared { name, description, args } contract verbatim. Use it to discover a known program's arguments before calling yaag_run; it does not execute the Run or enumerate programs.

yaag_setup_workspace

| Parameter | Type | Meaning | |---|---|---| | dir | string? | Workspace root; omitted uses pi's current working directory |

Use this when an Orchestration Program author sees missing @yaag/runtime editor/type resolution in their workspace. dir is optional and defaults to pi's current working directory. Normally run setup once for that workspace, and rerun it when an upgrade needs to refresh generated declarations. Its content is the CLI's verbatim per-artifact written/skipped report. Setup is not a Run: it has no Run id, summary, progress, usage, cassette, or follow-up behavior.

yaag_stop

| Parameter | Type | Meaning | |---|---|---| | id | string | The Run id to stop, as returned by yaag_run |

Reaps the Run's Agents and reports what it got through and what it spent: program, Agents seen, Asks settled, cost and tokens. Costs are reported as "at least" when the Summary is incomplete.

/yaag

Opens the yaag menu in the TUI: Programs, Status, Settings. Programs lists the Runs of this session, and a selected Run opens its interactive tree as the next level. esc goes up one level and closes the menu at the root, which is the reliable exit. ctrl+c closes the menu from any level, but it is a help only: pi gives ctrl+c to app.clear at app level, and can thus take the byte first. ctrl+q and m in the Run tree open the Run Control Menu. The menu lists only the actions that the Run permits at that moment: Pause, Stop, Resume or Reattach, and Cancel. A Run that permits no action shows no menu, and its footer shows no [m] hint. A live Run keeps running after you leave the menu.

Status shows the resolved bun executable and CLI entry point, then the counts of the live, the settled, and the restored Runs. Settings has one entry, Setup workspace: it creates or refreshes editor type support under .yaag/ in pi's current working directory and shows the per-artifact written/skipped report in the pane. It is the user-facing counterpart of yaag_setup_workspace, not a Run: it has no Run id, summary, progress, usage, cassette, or follow-up behavior.

Where Orchestration Programs live

By convention, in a .yaag/ directory in your project — but nothing enforces that location, and file accepts any path. Run yaag_setup_workspace once to create .yaag/tsconfig.json and refresh .yaag/types/. The CLI vendors its runtime and TypeBox declarations there, so editors and type checkers work without installing workspace dependencies; execution separately uses the runtime shipped with the CLI. Setup creates no program scaffold: authored programs remain yours, separate from its generated declarations. In this monorepo the convention is examples/. A program is a user-authored TypeScript file whose default export is defineRun({ run }). Use file tools to find a known program, then use yaag_describe({ file }) to discover its declared contract and arguments.

A worked example

.yaag/review.ts:

import { defineRun, prompt } from "@yaag/runtime";

export default defineRun({
  name: "review",
  description: "Review the working tree from one angle.",
  run: async (ctx) => {
    const agent = await ctx.spawn({
      name: "reviewer",
      model: ["anthropic/claude-opus-4:medium", "anthropic/claude-haiku-4"],
      thinking: (model) => (model.includes("haiku") ? "low" : "high"),
      tools: ["read", "grep"],
      disallowedTools: ["yaag_run"],
      skills: ["review"],
      disallowedSkills: [],
    });
    return agent.ask(
      prompt`
        Audit this repo for issues.
        Report the top three.
      `,
      {
        maxTurns: 4,
        maxToolCalls: 12,
        maxDurationMs: 60_000,
        wrapUpPrompt: "Give the findings now.",
      },
    );
  },
});

Program author controls

prompt\…`dedents static prompt text while preserving interpolated values.tools/disallowedToolsandskills/disallowedSkillsare spawn-level restrictions: a skill is a portable name, never aSKILL.md` path. Tool allowlists are applied before denylists; explicit empty allowlists disable flag-controllable items.

maxTurns, maxToolCalls, and maxDurationMs are per-Ask soft limits. They steer an Agent to wrap up, then abort only after grace; an ASK_LIMIT rejection is recoverable and the Handle can be asked again. wrapUpPrompt replaces the default steering message. This is intentionally different from timeoutMs, the destructive fallback that rejects with ASK_TIMEOUT and closes the Agent.

model takes one pattern, an ordered list, or a function of the failures so far; thinking takes a level or a function of the settled model. A pattern can end with a thinking suffix ("opus-5:medium"), and the suffix wins over thinking. The fallback rules — trigger classes, retry, termination — are stated on the types in <program dir>/.yaag/types/runtime/index.d.ts and in the root README.md; the sequences are in ../../docs/architecture.md §4 and §6.

The tool call:

{ "file": ".yaag/review.ts", "args": "{\"focus\":\"security\"}" }

For this blocking call, what comes back:

  • content — the Run's return value, the reviewer's report (this is what the model reads)
  • details — the Run Summary, rendered for the user
  • usage — the token breakdown: input, output, cache read, cache write, total

The background variant:

{ "file": ".yaag/review.ts", "background": true }

returns Run r1 started in the background. immediately; progress keeps streaming into the fold, and when the Run ends a follow-up message arrives with its value and final Run Summary in non-model-visible details. Pi's custom follow-up API has no nested-usage field, so natural completion does not alter Host Session token or cost totals. yaag_stop({ "id": "r1" }) ends it early and reports its nested usage through the stop tool result.

Both entry points, one execution path

bun apps/yaag/src/cli.ts run .yaag/review.ts

and yaag_run are the same execution path. The extension spawns exactly this CLI as a child — bun cli.ts run <file> --events-fd 3 --args <json> — and reads structured Lifecycle Events from descriptor 3 while the CLI's own stderr format stays unchanged. An Inline Program adds one inbound channel: the extension writes the source to descriptor 4, closes it, and names it as --eval-fd 4. What you debug in a terminal is what the session runs.

How stopping works

One ladder, taken by every route: pressing Esc during a blocking Run, calling yaag_stop on a background Run, or closing the session.

  1. stdin EOF — the extension closes the child's stdin; the CLI unwinds through the runtime's own Agent reap ladder.
  2. SIGTERM — if the CLI is still there.
  3. group SIGKILL — only if the CLI ignored both.

It is the runtime's Agent reap ladder (ADR-0008), one process level up.

Docs

Provided tools: yaag_run, yaag_describe, yaag_setup_workspace, yaag_stop. Provided commands: /yaag.