@ferris1225/pi-subagents

A managed sub-agent team for pi: research, implementation, independent review, interactive follow-ups, and Git worktree isolation.

Packages

Package details

extension

Install @ferris1225/pi-subagents from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@ferris1225/pi-subagents
Package
@ferris1225/pi-subagents
Version
6.0.5
Published
Nov 4, 2026
Downloads
4,753/mo · 2,111/wk
Author
ferris1225
License
MIT
Types
extension
Size
415 KB
Dependencies
0 dependencies · 4 peers
Pi manifest JSON
{
  "extensions": [
    "./index.ts"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-subagents

Sub-agents for Pi: research, implementation, independent review, interactive follow-ups, and Git worktree isolation.

Install

Requires Pi >= 1.5.0 and Node.js >= 22.19.0. Development and native integration tests use the Pi 1.5.0 SDK.

pi install npm:@ferris1225/pi-subagents

Run /subagents-setup to open a standalone centered modal panel rather than squeezing menus into the input editor dock. Wide panels place the role register and the focused role's settings side by side; narrow panels stack them. ↑/↓ changes the role, ←/→ selects Model, Thinking, or Reset, and Enter edits it in a searchable modal picker. The selected role shows its full model reference, effective reasoning level, requested level when clamped, and default/override source. Each selection saves immediately; Esc returns without applying a picker selection and keeps focus. Model pickers support search, paste, and paging. On short terminals, PgUp/PgDn scrolls the settings while the selected role and field stay pinned.

All roles follow the main model by default; thinking defaults to low for scout and high for artisan and sentinel. The panel distinguishes defaults from overrides and shows the effective level when model capabilities clamp a preference. Changing a model preserves the thinking preference. Settings live in ~/.pi/agent/pi-subagents.json as agentModels and agentThinkingLevels. Session start removes a model override that no authenticated provider offers anymore; an override outside the session's model scope is kept and only skipped while routing that session.

Agents

Agent Use for Access
scout Code, documentation, and web research with citations Read-only tools; no commands or edits
artisan Implementation and fixes with tests and checks Parent's tool surface, including codemode
sentinel Inspect an implementation or diff and challenge claims or assumptions for defects and regressions Parent's tool surface; instructed not to edit

The main model chooses from these role descriptions; names alone do not route a task. Use sentinel to inspect implementations/diffs or challenge a specific claim or assumption with counterexamples and focused checks.

Sentinel may run focused checks, so its no-edit boundary is an instruction, not a tool-enforced restriction. Change reviews focus on introduced defects; a wider audit needs an explicit brief. All roles reuse existing facts and valid checks, filling gaps rather than repeating main or upstream work.

Only scout, artisan, and sentinel are valid runtime role names. Existing model/thinking settings and interrupted run records migrate on load (reviewer, critic, and skeptic map to sentinel) and are saved with the current names. Explicit valid settings under the current names win. Custom roles are not supported. Retained records from older releases remain available for recovery.

Children receive a self-contained brief and project instructions, but no parent conversation. They cannot delegate or release. Main owns planning, integration, and the final result. Keep a fix and its regression tests with one owner.

Delegate

Pi proactively looks for useful bounded phases to delegate; no special request is required. Focused ownership, isolated context, parallel progress, and an independent check can each justify a child. A substantial self-contained fix can go to one artisan together with its regression tests, even when there is nothing to parallelize. Quick source checks and small understood edits stay in main. Choose team size from independent work. Explicit requests to work in main or avoid subagents take precedence.

Use one owner per deliverable, including its regression tests. Brief the child with the outcome, done condition, relevant paths, established evidence, write boundaries, required checks, and a compact expected result. Scout retrieves sources; artisan implements, while sentinel can execute focused checks. This policy applies the context-isolation, focused-role, and coordination-cost guidance in the official Codex subagents and Claude Code subagents docs to Pi's one-shot leaf runs.

A review request produces findings. Main applies fixes when changes are authorized and requests focused confirmation only when material uncertainty remains. Before reporting success, main checks each done condition and any blockers in the child's answer as well as the integrated diff.

Ask Pi to delegate explicitly, or call the tool directly:

subagent({
  agent: "artisan",
  task: "Fix cache invalidation in src/cache, add regression tests, and run the checks.",
});

Independent tasks can run together:

subagent({
  tasks: [
    {
      agent: "artisan",
      task: "Fix config validation and its regression tests.",
    },
    {
      agent: "artisan",
      task: "Update docs/providers.md from the established API citations.",
    },
  ],
});

Use wait: true when the next step needs the result. subagent and completed-run subagent_message follow-ups default to waiting in one-shot pi -p / JSON sessions, so the parent stays alive until the work finishes. TUI and RPC sessions default to background delivery; wait: false explicitly selects it in any mode. Each result is delivered once, after integration, either in the waiting tool call or as a background completion. Awaited failures are tool errors with retained evidence. An answer longer than 40 lines or 8,000 characters is not inlined; its delivery names the full-result file instead.

A launch receipt only confirms delegation and lists every started run id. Main continues independent work or pauses until the completion wakes it, then finishes the requested outcome and final checks. It does not poll or treat a successful launch as task completion. Equal normalized tasks in the same cwd are rejected as duplicates while active or settled in the current session. Reuse the result, or use subagent_message for an additional bounded step.

Status, cancellation, and recovery

Tool Use
subagent_status({ id: 12 }) Inspect a run's progress, result, and recovery paths
subagent_message({ id: 12, message: "Check the caller too" }) Steer a running child, or continue a completed run using its session when available and a summary otherwise
subagent_message({ id: 12, message: "Add the test", context: "summary" }) Start a new next step with only a bounded summary of the earlier run
subagent_stop({ id: "12" }) Stop a run and retire its retained session
subagent_stop({ all: true }) Stop all active runs in this session

The widget is a terminal task board capped at 10 lines: a quiet overview, then task rows with status/time at the right. Failures get space before optional telemetry; narrow terminals keep task identity visible. Model, thinking, token usage, and worktree state appear as secondary detail. Failed work stays until the next dispatch. Completion messages and status lookups retain the results. Overflow reports hidden tasks. Runs preparing their child process show starting. The refresh timer runs only while visible active work needs it. There is no process-count limit or shared-checkout startup lock: independent runs start together, including separate dispatch calls while another call awaits results.

Usually omit isolation: implementation tasks use detached Git worktrees in single calls and parallel batches. Reading and review use the current directory. Without a Git repository or committed HEAD, automatic isolation uses the caller's directory and reports why. Unexpected setup or integration failures remain failures; an explicit isolation: "worktree" requires isolation and never falls back. isolation: "shared" is an advanced override for tasks that need to write directly in the caller's checkout.

Each worktree starts from the caller's current tracked files and non-ignored untracked files, including uncommitted changes. Its initial snapshot is also the integration base, so dependent tasks see earlier results without reapplying them. The caller's index, branch, and HEAD stay unchanged. The child is told the original checkout and its worktree path, so it maps paths from the brief into the worktree. Worktrees isolate Git changes, not tool permissions. Independent tasks start together; only the final application of worktree changes to the original checkout is serialized. Integration leaves your index untouched, and failures retain recovery artifacts.

Cancelling the parent run with Escape stops unfinished work without waking the parent. A cancellation receipt is supplied on the next user turn with the stopped run ids, so main knows no additional subagent_stop is needed. Cancelled work must not restart automatically. Conversation-tree navigation also stops unfinished work. New/resume/fork/reload ends old children and retains interrupted work for manual recovery. Runs do not resume automatically; main finishes incomplete work from partial changes and artifacts.

A steering call waits for the child's existing RPC channel to acknowledge the matching request ID. The tool card shows Received · queued when Pi confirms queueing, Received · handled when an input hook consumes the message, or Accepted · queue state unconfirmed when no disposition is available. subagent_status retains the latest acknowledgement, request ID, age, and message summary. Rejection or a missing acknowledgement is an error, not a receipt. Queueing delivers at a Pi steering boundary; it does not prove that the model has executed the instruction.

To continue a successfully completed run, choose the context that fits the follow-up:

  • context: "auto" (default) continues a private copy of the retained session when available. If cleanup has removed it, the follow-up starts with a bounded summary and explicitly reports that full history is unavailable. No retry is needed for an expired session.
  • context: "session" requires full history for rework that depends on earlier details. If the session is unavailable, the call fails without starting a run.
  • context: "summary" always starts fresh for a new next step, with the earlier objective, final result and touched files. It cannot rely on omitted details or reuse the earlier provider cache.

Session continuations retain the earlier history and provider prompt-cache key (sessionId). Their private copy is bound to the new run's working directory, including when a previous temporary worktree has already been removed. Child startup and the copied session header use the same physical directory, so macOS path aliases and Windows junctions do not trigger a cross-project fork prompt. The continuation is instructed to re-read files before editing in the current cwd.

Every follow-up preserves the role and workspace and passes through normal admission and isolation. Set wait: true to receive its final result in the same call; this waiting option applies to newly started follow-ups, while steering a running child returns its acknowledgement. subagent_status reports whether a completed run has a session available or only summary context. Results and summaries remain available within the current parent runtime; completed runs are not restored after reload. Pending runs cannot be steered.

Children use Pi's native --mode rpc CLI with piped input/output, retries, and session persistence. On Windows, console hiding covers the Pi child and Node process launches made by its tools and extensions, including pi.exec, pwsh, and powershell. The child preloads this policy before Pi starts and passes it to Node descendants through NODE_OPTIONS, preserving existing options. An explicit child extension installs the same policy for runtimes without Node preloading. Windows launches stay attached so detachment cannot open a console. On macOS and Linux, the policy leaves shell options unchanged; the Pi child uses a separate process group for cancellation and does not launch a terminal app. RPC communication and process-tree cancellation remain active. Child startup errors are reported as failed runs. If Windows cannot launch taskkill, termination falls back to killing the child directly. Commands that explicitly open a terminal or GUI control their own windows. A settled provider failure can hand off once to the main model in the same session. State and full-result files live under ~/.pi/agent/ferris-pi-subagents/, grouped by project. PI_CODING_AGENT_DIR overrides the agent directory.

Pi codemode compatibility

Call subagent and the control tools directly. They use Pi's model-only exposure and are intentionally unavailable as nested tools.subagent(...) calls inside codemode. Children can still use codemode with their inherited callable tools. Indirect tools retain their exposure; scout promotes approved read-only tools for direct use. It waits up to ten seconds for startup registration and activates later arrivals between turns. Read-only classification uses Pi tool metadata.

Child RPC dialogs that require confirmation, selection, or text input are cancelled with a matching response and an explanation, so an unattended child does not hang waiting for an invisible dialog. No confirmation is approved automatically.

Storage and cleanup

Each project root holds sessions/, worktrees/, tmp/ and results/. Startup hygiene already drops temp leftovers, artifacts whose Pi process is gone, result files past their retention window, and project roots idle for three days. Parked recovery work and manifest references are protected during these sweeps. Interrupted checkpoints expire after 30 days when no recorded owner or child from the current boot is alive; expired checkpoints are pruned before restore. Missing session files do not erase validated recovery paths. Unreadable or malformed manifests leave artifacts intact and skip automatic reclamation; explicit cleanup reports the error. Startup warns about failed recovery inspection and continues initializing the progress widget.

Reclamation is automatic: a settlement may trigger one paced sweep (at most every five minutes) that drops dead-owner artifacts, expired result files, and settled session copies older than 30 minutes, then trims the oldest settled sessions until a project fits its 1.5 GB budget. Under budget pressure, settled sessions older than five minutes can be removed. Live runs, parked recovery work, and manifest references remain protected. Automatic follow-ups use the retained summary when a completed run's transcript has expired. Session shutdown waits for cleanup already in progress and prevents new settlement sweeps.

/subagents-cleanup immediately reclaims unclaimed dead-owner artifacts and idle project roots, reporting usage and freed bytes. /subagents-cleanup dry-run measures without deleting anything; any other argument is rejected without deleting. Session age and budget reclamation runs automatically on settlement.

Development

Runtime code lives under src/; the package has no skill or workflow resource directories. Built-in prompts change with the code and its tests.

Module Responsibility
delegation/ Built-in roles, parent routing prompt, and duplicate-dispatch admission
configuration/ Model and thinking settings, plus the standalone setup modal panel
presentation/ Running task board, activity, status, and result formatting
execution/, lifecycle/, isolation/ Child processes, durable state, cancellation, worktrees, and recovery
npm ci
npm run check

Pushing an unpublished package version to main runs the checks on Windows, macOS, and Linux before triggering publishing and a GitHub Release.

Changelog · MIT license