Claude Code like Sub-agents for Pi — parallel execution, live widget, custom agent types, mid-run steering and more ...
Claude Code like Sub-agents for Pi — parallel execution, live widget, custom agent types, mid-run steering and more ...
A pi extension that brings Claude Code-style autonomous sub-agents and workflow orchestration to pi. Spawn specialized agents that run in isolated sessions — each with its own tools, system prompt, model, and thinking level. Run them in the background (the default) or block on them, steer them mid-run, resume completed sessions, and define your own custom agent types. When the orchestration shouldn't be improvised, hand a deterministic JavaScript script to the SubagentWorkflow tool — agent(), parallel(), pipeline() — and scripts written for Claude Code's Workflow tool run here unchanged.
https://github.com/user-attachments/assets/8685261b-9338-4fea-8dfe-1c590d5df543
Agent, get_subagent_result, steer_subagent) — feels native/agents → Settings → Widget: all (every agent), background (default — hides foreground runs, which already render inline as the Agent tool result), or offmain + every running subagent rendered below the editor (earliest-launched first). Press ↓ (or ←) at an empty prompt to jump in, ↑/↓ to move the selection, Enter to open the selected agent's live, auto-updating conversation, Esc to return. Finished agents linger briefly before dropping out, and a viewer stays open through completion so you can read the final output. Toggle via /agents → Settings → Fleet view/agents to open a live-scrolling overlay of its full conversation (auto-follows new content, scroll up to pause). Steer a running agent inline by pressing Enter to open a composer, typing, then Enter to send (Esc or an empty submit returns) — the message appears as a user message and redirects the agent after its current tool. Stop a still-running agent by pressing x (then x again to confirm) — both work for background agents too. Assistant text renders as Markdown; m cycles that between off, assistant-only and everything (see Viewer markdown).pi/agents/.md or .agents/agents/.md (project) or globally, with YAML frontmatter: custom system prompts, model selection, thinking levels, tool restrictions, and Claude Code-compatible colored name badgesallowed_subagents gets its own ownership-scoped Agent, get_subagent_result, and steer_subagent tools, depth-capped from the main session (default 2). It can control only its own children, they are stopped when it finishes, and their transcripts and token spend roll up to it. The allowlist is a privilege boundary — a child runs with its own tools, so pick it as carefully as tools: itself@explore also check the RPC path at the prompt and it goes to that agent instead of the main model, without a word of it entering the chat. One syntax covers the whole lifecycle — message it while it runs, resume it once it has finished, reopen its session from disk long after that, or start it if it never ran. Mentioning an agent that isn't running spawns it through an off-screen clone of the conversation, so it gets Claude Code's context-written prompt and a real Agent tool call without a word of it reaching the chat; direct mode starts it here from your text instead, with no model call at all. The orchestrator can name an agent so you address it as @auth-audit, and handles work in steer_subagent/get_subagent_result too. @ completes live agents, resumable ones, and startable types alongside pi's file completion; @main forces text back to the main model. Toggle via /agents → Settings → Agent mentionsSubagentWorkflow tool that runs a deterministic JavaScript script orchestrating many subagents: agent(), parallel(), pipeline(), phase(), log() and args, with a pure-literal meta block declaring the phases. pipeline() has no barrier between stages, so one item can be in a later stage while another is still in the first — unlike parallel(), which idles every fast agent until the slowest finishes. Runs in the background with a live card, inspectable via /agents → Workflows or by selecting the run in FleetView. agent() also takes gate: "npm test" to verify a child by running a command (inside its worktree, when isolated) rather than asking another model, and resume: "" to continue a child instead of re-paying its context. Scripts run in a node:vm sandbox on a worker thread where Date.now(), Math.random() and eval throw. On by default, but it stands down for company: if another extension already provides a Workflow or SubagentWorkflow tool, this one warns and disables itself for the session rather than offering the model two orchestrators. Pin it either way with "workflowsEnabled" in subagents.json or /agents → Settings → Workflows. A script written for Claude Code's Workflow tool runs here unchanged: same globals, schema returns a validated object exactly as it does there, budget is present and always reports no token target (pi has no such directive) so its budget.total-guarded patterns still take the branch they were written for, and nested workflow() composes saved workflows one level deep. Full guiderun_in_background: false to block and get the result inline"explore", "Explore", "EXPLORE" all work. A type that doesn't resolve to exactly one enabled agent — unknown, disabled, or ambiguous between two agents differing only by case — falls back to general-purpose with a note, or is refused outright under fallbackSubagent: none"haiku", "sonnet") instead of full IDs, with automatic filtering to only available/configured models.pi/skills/, .agents/skills/, and global locations (Pi-standard /SKILL.md directory layout supported)disallowed_tools frontmattersubagents:created, started, completed, failed, steered, compacted) emitted via pi.events, enabling other extensions to react to sub-agent activitypi.events event bus (subagents:rpc:ping, subagents:rpc:spawn, subagents:rpc:stop, subagents:rpc:consume). Standardized reply envelopes with protocol versioning. Emits subagents:ready on session start. Full referenceschedule to the Agent tool to fire on cron / interval / one-shot. Session-scoped jobs with PID-locked persistence; results land via the same subagent-notification followUp path as manual background completions; manage via /agents → Scheduled jobsenabledModels allowlist (sourced from /scoped-models, with both global and project-local pi settings honored). Caller-supplied out-of-scope → hard error to orchestrator; frontmatter-pinned out-of-scope → warning + runs anyway (frontmatter authoritative). Toggle via /agents → Settings → Scope modelspi install npm:@tintinweb/pi-subagents
Or load directly for development:
pi -e ./src/index.ts
Requires pi 0.84.0 or newer: the SubagentWorkflow tool builds on constrainedSampling (pi 0.82.0) and pi-tui's stripTerminalSequences (0.84.0). The peerDependencies range declares it, so npm flags an older pi at install time.
This extension is developed and tested against pi.
Third-party adapters report running it elsewhere. These are maintained independently of this project: not tested here, not covered by our CI, and compatibility may break with any release.
dsh) — via an adapter that maps pi's host API onto native DSH agents. Details and reports: #258The parent agent spawns sub-agents using the Agent tool:
Agent({
subagent_type: "Explore",
prompt: "Find all files that handle authentication",
description: "Find auth files",
run_in_background: true,
})
Agents run in the background by default: the call returns an ID immediately and notifies you on completion, carrying a preview of the result (use get_subagent_result for the full text). Pass run_in_background: false to block until the agent finishes and get its full output inline.
Add a schedule field to register the agent to fire later instead of running now:
Agent({
subagent_type: "Explore",
prompt: "Look at recent commits and summarize what changed since last week",
description: "Weekly commit review",
schedule: "0 0 9 * * 1", // 9am every Monday (6-field cron)
})
Schedule formats:
second minute hour day-of-month month day-of-week), e.g. "0 0 9 * * 1" for 9am every Monday, "0 */15 * * * *" for every 15 minutes."5m", "1h", "30s", "2d". Fires repeatedly at that interval."+10m", "+2h", "+1d". Fires once at that future time."2026-12-25T09:00:00.000Z".When a schedule fires, the spawn runs in background and its completion notification arrives in the conversation through the same subagent-notification followUp path as a manually-spawned background agent — your parent agent reasons about the result the same way.
Schedules are session-scoped: they reset on /new and restore on /resume. List and cancel via /agents → Scheduled jobs (creation is the Agent tool's job — there is no parallel manual-create wizard). Storage at /.pi/subagent-schedules/.json with PID-based file locking for cross-instance safety.
Disable the feature entirely: /agents → Settings → Scheduling → disabled removes schedule from the Agent tool spec (no LLM-context cost), hides the menu entry, and stops any
No open issues yet, or sync has not completed.