Imported from melihmucuk/pi-crew (
AGENTS.md). Install upstream withnpx skills add melihmucuk/pi-crew. Copyright stays with the author.
AGENTS.md
Project Overview
pi-crew provides non-blocking subagent orchestration for the Pi coding agent. It runs bounded tasks in isolated SDK sessions, routes results back to the session that spawned them, and keeps successful subagents alive for follow-up turns. The critical outcome is reliable background work without blocking the owner session or mixing results between sessions.
Key Files / Folders
extension/index.ts— Extension entry point; session activation and shutdown, process cleanup, tool registration, and renderer registration.extension/crew.ts—CrewRuntime; owns state, ownership, delivery queueing, aborts, and lifecycle transitions.extension/subagent-session.ts— SDK session creation, capability isolation, and prompt-cycle outcomes.extension/subagent-status.ts— Lifecycle status vocabulary: the status values and their phases (in-flight,awaiting-owner,terminal), plus the tool-activity vocabulary.extension/subagent-result.ts— Universal result contract,crew_reporttool, and cycle result acceptance.extension/catalog.ts— Agent definition and config discovery, parsing, overrides, and warning semantics.extension/task.ts— Source of truth for the structured task schema, validation, and child-prompt formatting.extension/tools.ts— Public registration and invocation boundary for thecrew_*tools.extension/tool-output.ts— Shared action-result types, JSON execution-error serialization, and readable error/abort formatting.extension/tool-activity.ts— Sanitizes and summarizes tool activity for display.extension/mentions.ts— Inline@crew:nameautocomplete and model-context-only mention expansion.extension/delivery.ts— Result delivery policy, model-bound result messages, and the TUI-only abort entry.extension/context-status.ts— Owner-scoped status snapshots and model-call-counted reminders at safe append boundaries.extension/herdr.ts— Optional Herdr sidebar metadata; never owns agent lifecycle authority.extension/format.ts— Model-id parsing and display formatting helpers.extension/ui.ts— Renderers and the session-bound status widget.tests/— Behavior contracts for the catalog, task contract, runtime, tools, lifecycle wiring, mentions, UI, sanitization, and package metadata.package.json— Source of truth for shipped and Pi-registered resources.
Development Invariants
- Preserve the ownership boundaries listed in Key Files / Folders. Do not add wrappers without a seam where behavior genuinely varies.
crew_spawn.taskmust remain a closedgoal/context/instructionsassignment:goaland every array item are non-blank,contextmay be empty, andinstructionshas at least one item. Reject unknown fields, flat strings, and legacy conversion; preserve task values when formatting the child prompt.CrewRuntimemust remain process-global; delivery and widget bindings must be rebound for the active owner session. A runtime-version mismatch on reload aborts the stale runtime's subagents before replacing it.- Subagent sessions must filter out pi-crew through
extensionsOverrideand link to the owner withSessionManager.newSession({ parentSession }). Do not automatically delete subagent session files. - Create each child
ModelRuntimewith model-network access disabled. Snapshot owner provider registrations and transfer only authentication required by the configured model, or by the owner's current model when no model is configured; credential transfer must not enable network access. - Run prompt cycles directly with
AgentSession.prompt(); do not add custom context-overflow recovery. crew_reportis the universal successful-result boundary;reportis the complete role-specific final answer, not a prelude to another summary. Preserve the closed result schema, cycle-local final-call acceptance, and one-reminder policy specified indocs/result-protocol.md#successful-resultswhen changing result validation or prompt cycles.- Lifecycle statuses are
running,completed,needs_input,error, andaborted, defined once inextension/subagent-status.tswith their phase (in-flight,awaiting-owner,terminal). Compare phases, never raw status values, and keep one presentation table inextension/ui.tskeyed by those statuses. Each successful prompt cycle settles into itscrew_reportoutcome;completedandneeds_inputstay abortable and visible as active until explicitcrew_done, which disposes the session directly. Settling a prompt cycle disposes the session automatically only for terminal statuses. - Tool-activity statuses are a separate vocabulary, defined once as
SUBAGENT_TOOL_STATUSinextension/subagent-status.ts; they are never lifecycle statuses. Acrew_reportcall counts toward the tool-call total but never occupies a retained activity row, so protocol mechanics cannot evict real activity from the widget. - Subagent working time counts prompt cycles only: add the cycle duration to
workedMswhen a cycle settles, restartrunningSinceon spawn and respond, and never count waiting for an owner action. The status widget shows that total per agent, presents the outcome as an icon instead of repeating a status label, and prints the toggle hint once per render. Thewidget.showToolCallsconfig is presentation-only: when false it hides tool-activity rows and the toggle hint while keeping status, usage, and call/failure totals, and it never changes tool execution or activity recording. - Herdr integration is presentation-only and must leave the official Pi integration's lifecycle and session identity untouched. Enable reporting only in TUI mode with
HERDR_ENV=1,HERDR_PANE_ID, andHERDR_SOCKET_PATH; outside Herdr, do not subscribe to activity, build summaries, start timers, or send IPC. Count only in-flight subagents across the process, including inactive owners' preserved work. Serialize metadata reports and retain only the latest pending count. On shutdown, detach observers and stop renewals; replace pending counts with a final clear rather than draining obsolete updates. - Always use
sessionManager.getSessionId()for ownership.getSessionFile()is not owner identity. crew_respondmay only restart an owned subagent in theawaiting-ownerphase and must return without waiting for the prompt; a subagent with no attached session settles as an error instead of blocking the tool.crew_donemay only close an owned subagent in theawaiting-ownerphase and must not send a message. Aborts may target only owned abortable subagents and must preserve missing and foreign-ID reporting.crew_spawnandcrew_respondare non-blocking.crew_listis only for definition discovery;crew_statusis only for an owned open-session snapshot. Both return JSON to the model and render structured details separately for the TUI. Never poll for completion because results arrive asynchronously.- Inline
@crew:namereferences identify a user-selected subagent but do not require spawning; sentence intent controls delegation. Mention names are limited to ASCII letters, digits, and hyphens; filter other discovered names from autocomplete without narrowing catalog or tool validity, and never partially expand unsupported names. Expand every syntactically valid reference in user text to<pi-crew subagent="name" />only in model-bound context, without catalog lookup or mutation of stored text or image content. - Route results to the owner session that spawned the subagent and queue results while that owner is inactive. Defer activation flushes to the next macrotask and drop pending messages older than 24 hours during flush.
/forkand/clonere-parent the previous session'sin-flightandawaiting-ownersubagents and their queued results to the new session id, matched by the previous session file; no othersession_startreason adopts anything.completed,needs_input, anderrorresults are delivered as model-visible messages with{ deliverAs: "steer", triggerTurn: true }: a steer queues into a running turn and an idle owner gets a turn that delivers it, so the owner session's streaming state never changes pi-crew's policy. Every such delivered result triggers an owner turn, so no result may be deferred while peers are still running.abortedis recorded withpi.appendEntry("crew-abort")instead — TUI-only, no model context, no turn — because the owner already knows from thecrew_aborttool result or is shutting down. Both kinds go through the same owner-routing queue. Any prompt template that combines a batch of results must gate the next stage on every spawned agent having settled.- Owner status snapshots and reminders are append-only model context, added before an owner run or after a turn's tool results. Context repair may insert only missing, uniquely identified pi-crew status/reminder messages from the compaction-aware session record, at their recorded positions. Never replace, remove, or reorder existing messages or change the system prompt; snapshot deduplication uses the session record, not SDK-loop visibility. Never wake an idle owner for status reminders or close a successful subagent automatically; see
docs/result-protocol.md#owner-status-contextfor the emission policy. - All pi-crew-produced tool results, including action/report acknowledgements and execution errors, are JSON. Throw serialized execution errors to preserve Pi's error flag; Pi-generated errors outside tool execution are not rewritten. TUI renderers derive readable text from structured results instead of copying display text into model content; see
docs/result-protocol.md#tool-results. - Keep result model context and TUI presentation separate: model-bound content is JSON with
subagent_id,brief, and the exact validatedresult(or terminalstatus/error), while the renderer builds Markdown cards only from structured details. Do not copy a display body into message details or expose protocol wrappers in the card. - Every
session_shutdowndeactivates delivery.reload,new,resume, andforkpreserve background work; onlyquitaborts it. ThebeforeExithook also aborts all subagents. Do not register process signal handlers or exit the process from the extension; pi owns signal handling and shutdown. - Discover agent definitions in priority order: project agents, user agents, then bundled agents. Higher-priority sources win silently; duplicate names within one source warn. Project agents and the project
pi-crew.jsonare loaded only whenctx.isProjectTrusted()is true; otherwise both are skipped with a single discovery warning. - Merge
pi-crew.jsonoverrides in user-then-project order; project fields win while unspecified user fields remain. When changing tool-list parsing or merging, preserve the definition/override delta, reset, ordering, and warning rules indocs/configuration.md#tool-deltas. - Models use
provider/model-id. A configured model must resolve exactly or the subagent fails before prompting; only an omitted model inherits the spawning-session model. Wrong-typed fields warn and are ignored in both.mddefinitions andpi-crew.json; a malformed model string warns at discovery but keeps its raw value, so the spawn still fails. Omittedtoolsmeans the default built-in tool set; omittedskillsmeans all discovered skills; an explicit empty list means none. Tool allowlists may include extension-registered custom Pi tools, so do not validate them against a fixed built-in list. - Treat tool arguments as untrusted display data and route widget targets through
summarizeToolTarget. Keep summaries single-line and control-sequence-free, redact recognized sensitive keys and authentication/flag forms, and strip HTTP(S) query and fragment data. This is not a complete secret detector. - Bundled resources must be included in npm
files. Pi extensions, skills, and prompts must also appear in thepimanifest; bundled agent definitions belong only in the npm package. - Test observable public behavior. Use the
CrewRuntimecreateRunnerseam for subagent lifecycle tests; add seams only where production behavior genuinely varies. - Ask before adding dependencies, CI checks, baselines, ratchets, or broad enforcement.
Commands
npm run typecheck— Type-check the extension and test TypeScript sources.npm test— Run the behavior suite with the Node test runner.
Documentation
- Keep README feature descriptions brief: user-visible behavior and required setup only. Leave implementation details out.
Read When Relevant
- When changing user-facing installation, tool behavior, agent discovery or config, or packaged resources, read
README.md. For discovery or config, also readdocs/configuration.md; for result validation, lifecycle, delivery, or model-context presentation, readdocs/result-protocol.md. - When changing bundled delegation behavior, orchestration guidance, or
crew_*tool prompt guidance, readskills/pi-crew/SKILL.mdtogether with the relevant tool definitions. - When changing the structured task contract or child-prompt formatting, read
README.md,skills/pi-crew/SKILL.md, all bundledagents/*.mddefinitions, and bothprompts/pi-crew-*.mdorchestration templates. - When changing planning orchestration or scout/planner contracts, read
prompts/pi-crew-plan.mdand the relevantagents/scout.mdandagents/planner.mddefinitions. - When changing review orchestration or reviewer contracts, read
prompts/pi-crew-review.mdand the relevant reviewer definitions underagents/. - When changing a bundled subagent's capabilities, lifecycle, or output format, read its
agents/*.mddefinition and any prompt that references it. - When changing custom-agent authoring guidance or supported definition fields, read
skills/pi-crew/references/create-agent.mdanddocs/configuration.md. - When maintaining
AGENTS.md, keep only durable, non-obvious, implementation-shaping rules. Do not add one-off preferences or details owned by another source. If code conflicts with this file, report the conflict instead of silently leaving stale guidance.
