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

@tduyng/pi-subagent

v0.0.5

Published

Cheap delegation: a child session reads docs, logs, and source, returns one answer, and its context is thrown away. Scout profile bundled.

Readme

@tduyng/pi-subagent

A subagent that stays small on purpose. It reads docs, logs and source on a cheap model, returns one answer, and leaves none of that reading in the parent's context.

A session spends most of its tokens reading. A question about which files build a retry policy has a paragraph for an answer and 40 KB of source behind it, and the parent carries that 40 KB into every later turn. The child's context dies with the task, so the cost of a delegation is bounded by its answer.

Fanning four edit-capable children over one change is the case this is not for. Every child builds its own system prompt and tool list, and their edits still have to be reconciled.

379 tokens a request for the tool, which asks the provider for a schema-shaped call: 4 of the 24 recorded calls failed to parse as JSON and cost their turn, every one of them carrying a nested schema. After the change, two live calls carrying the same shape parsed: one task with a nested schema, and two tasks with a schema each. The bulk-read guard and the log reducer are event handlers, so they add no schema and no prompt text.

The tool

subagent(task: "Which files construct the retry policy? Return path:line for each.", agent: "scout")

One task or up to 8, at most 4 running at once.

| Field | Meaning | | --- | --- | | task | What the child does | | agent | Profile name, scout by default | | cwd | Working directory for the child | | isolation | worktree to give the child its own git checkout | | schema | Ask for structured output | | context | fork to replay the parent's history into the child | | resume | Task id, or all, to continue a stopped child |

Scout

agents/scout.md is bundled, so agent: "scout" works with no setup and no profile. It is also the default when no agent is named, so the cheap read-only child is what a plain call gets.

Scout carries tools: read, grep, find, ls, inheritSkills: false, and thinking: low. It never edits, never runs a command, never reaches the network, and answers in a fixed STATUS / FINDING / NEXT shape with file:line evidence.

Override it with a copy in ~/.pi/agent/agents/scout.md or .pi/agents/scout.md. A project file shadows a user file, and both shadow the bundled one.

The child inherits the parent's model unless told otherwise, which defeats the point. Set it once in ~/.pi/agent/subagent.json:

{
  "model": "claude/claude-haiku-5-5",
  "thinking": "low"
}

.pi/subagent.json overrides either field per project. A model on the profile wins over the file, so a judgment role such as verifier can opt out and ask for a strong model.

A stopped child is resumable

A child that hits its turn budget is told to wrap up and gets a fresh budget in the same session, so a cap never turns work into a failure. If it still stops early, its last text comes back marked [partial answer], recovered by walking the whole transcript, so a child stopped mid tool-burst still returns what it wrote.

Every failed task prints a resume: id. Passing it back continues where the child stopped instead of paying for the investigation again. Failed sessions are kept 30 minutes and completed ones 5.

Every run writes run.json under <agent-dir>/subagents/<session-id>/<run-id>/ with the task, model, tools and the path to each child session. Reopening the session reads it back: a child interrupted less than ten minutes ago is resumed from its saved session and its answer arrives as a subagent-durable message, and older interruptions are listed with their resume ids. resume therefore works after a restart.

Worktrees, schemas, forks

isolation: "worktree" runs each child in its own git worktree on a branch named pi-task-<id>, so concurrent children never edit the same checkout and a commit the child makes outlives it. The result names the branch. This is also the answer to two sessions committing in one repository, which no path reservation covers.

schema asks the child to call structured_output exactly once, and the parsed payload comes back in the task result. A child that finishes without calling it is re-prompted in the same session up to three times, so the investigation is not paid for twice. If it still refuses, the text answer stands and the task completes marked partial. If a provider rejects the schema tool, the extension removes it and retries once as plain text.

context: "fork" replays the parent's conversation history into the child as context entries.

Two guards on the parent

Bulk read. The guard blocks a read of a file above BULK_READ_MIN_LINES lines (default 350), and blocks cat, less or more that would dump a large file. The block names outline first, so the model fetches a map of declarations rather than the text. The second call for the same path passes, and so does a read that returns fewer lines than the threshold, whether from a limit, an offset, a small file, or head and tail on their 10-line default.

Log reducer. The reducer replaces a build or test log above 4,096 bytes from a diagnostic command with a short receipt of quoted lines. It verifies every quote byte for byte against the archived original, and if validation fails the full log reaches the model untouched. It runs on tool_result, so the swap happens before the result enters history, and the raw log is archived next to the session.

Both are what stop a delegation from being undone by the next cat.

Profiles and the widget

A profile is a markdown file with YAML frontmatter in ~/.pi/agent/agents/, .pi/agents/, or bundled. It sets the tool list, model, thinking level, limits, an optional color, inheritProjectContext and inheritSkills, and systemPromptMode: replace to swap the default system prompt rather than append to it.

/agents lists them with their tools, model and limits. The roster rarely changes mid-task, so it is a command, not a model tool.

A persistent widget lists running and recently finished children. Down on an empty prompt highlights the roster, Up and Down move, Escape clears, Enter opens a live conversation viewer with thinking, tool calls and results.

Install

pi install npm:@tduyng/pi-subagent

Local checkout: pi install /path/to/dotfiles/pi/agent/extensions/pi-subagent

Worktree isolation needs git on PATH, and the bulk-read hint names rg.

| Setting | Default | Meaning | | --- | --- | --- | | BULK_READ | 1 | 0 disables the read guard | | BULK_READ_MIN_LINES | 350 | Line threshold for a blocked read | | PI_LOG_REDUCER | 1 | 0 disables the log reducer | | PI_LOG_REDUCER_TIMEOUT_MS | 15000 | Reducer deadline, 60,000 at most |

Limits

  • Eight tasks per call, four running at once. A fifth concurrent write-capable child is refused rather than queued.
  • Child deadlines default to 30 minutes. A profile deadline past the 32-bit setTimeout ceiling clamps to it, because Node rounds a larger delay down to 1 ms and would kill the child instantly.
  • A child cannot spawn its own subagent, so delegation stays one level deep.
  • Read-only children run in parallel. A write-capable child never runs alongside another one, and two tasks that normalize to the same request are refused.
  • The registry holds 50 tasks, the widget 8 rows, and the touched list 12 entries per task.