pi-crew
v0.1.41
Published
Pi extension for coordinated AI teams, workflows, worktrees, and async task orchestration
Downloads
5,236
Maintainers
Readme
pi-crew
pi-crew is a Pi extension/package for coordinated AI teams: autonomous routing, manual slash-command controls, durable run state, artifacts, async/background execution, optional worktree isolation, resource management, validation, import/export, dashboard helpers, and safe API interop.
NPM package:
pi-crewGitHub repository:
https://github.com/baphuongna/pi-crewStatus
pi-crew is published on npm and implemented with safe execution defaults and product-oriented foundations.
Current highlights:
- one main Pi tool:
team - autonomous delegation policy injection before agent start
- metadata-aware
recommendaction for routing, decomposition, fanout hints, async/worktree suggestions - configurable autonomy profiles:
manual,suggested,assisted,aggressive - builtin agents, teams, and workflows
- user/project/builtin resource discovery where user resources override builtin resources, and project resources cannot shadow trusted user/builtin names
- resource format support for routing metadata:
triggers,useWhen,avoidWhen,cost,category - durable run state: manifest, tasks, events, artifacts, imports/exports
- foreground workflow scheduler
- detached async/background runner
- stale async PID detection
- active run summary and async completion notifications in Pi sessions
- owner-session delivery guards so stale sessions do not receive background subagent/result/live-session completions
- real child Pi worker execution by default, with explicit scaffold/dry-run opt-out
- child Pi JSON output parsing for final text, usage, and event counts
- retryable model fallback attempts per task
- aggregate usage totals in status/summary
- progress, summary, prompt, result, log, diff, patch, export artifacts
- task packets, verification/green-contract evidence, policy decision artifacts, and task graph metadata
- opt-in git worktree isolation per task
- worktree branch mismatch detection
- dirty worktree preservation unless
forceis explicitly set - cancel/resume lifecycle operations
- forget/prune cleanup operations with explicit confirmation
- export/import portable run bundles
- resource create/update/delete with backups, dry-run, reference checks, and optional reference updates
- resource validation and doctor checks
- project initialization for
.pilayout and.gitignore - config show/update with user/project scope and nested unset support
- safe API interop for manifest/task/event/heartbeat/claim/mailbox operations
- realpath containment for run/import/artifact/transcript/mailbox/agent state reads and writes, including symlink escape protection
- read-only state APIs avoid creating mailbox files when only inspecting delivery or mailbox state
- run-level and task-level mailbox files with validation/repair support
/team-managerinteractive helper/team-dashboardcustom TUI overlay with progress preview, action shortcuts, and reloadparallel-researchteam/workflow for dynamicSource/pi-*fanout and parallel shard exploration- observability metrics: per-session Counter/Gauge/Histogram registry, JSONL sink,
/team-metrics, dashboard metrics pane, Prometheus/OTLP exporters (OTLP opt-in) - reliability hardening: heartbeat gradient watcher, opt-in retry executor with attempt trace, crash-recovery detection, deadletter queue
- background
Agent/crew_agentcompletion wake-up so parent sessions can automatically join completed subagent results - optional
runtime.requirePlanApprovalgate for planner-first approval before mutating adaptive implementation workers run - optional
runtime.completionMutationGuardto warn or fail implementation-style workers that complete without observed mutation tool calls - grouped result delivery is correlated through mailbox metadata, deduped by request id, and acknowledged via existing
ack-message - shared redaction for common secrets before durable event/log/mailbox/artifact/metric/diagnostic persistence
- package polish:
schema.json, TypeScript semantic check, strip-types import smoke, cross-platform CI workflow, dry-run package verification
Install
From npm:
pi install npm:pi-crewFrom the workspace root for local development:
pi install ./pi-crewOptional config bootstrap after npm install:
pi-crewOptional config bootstrap from a local clone:
node ./pi-crew/install.mjsLocal verification from this package:
cd pi-crew
npm run ciRuntime safety model
By default, run launches each crew task as a separate child Pi process. This matches the subagent model from pi-subagents: the parent session orchestrates while worker sessions execute independently and stream durable output back to run state.
Use scaffold/dry-run mode only when you explicitly want prompts/artifacts without launching workers:
{
"runtime": { "mode": "scaffold" }
}or disable workers globally:
{
"executeWorkers": false
}Worktree mode is opt-in:
{
"action": "run",
"team": "implementation",
"goal": "Implement feature X",
"workspaceMode": "worktree"
}By default, worktree mode requires a clean leader repository. Dirty task worktrees are preserved unless cleanup is called with force: true.
Config
User config path:
~/.pi/agent/extensions/pi-crew/config.jsonProject config path:
.crew/config.json # default (new projects)
.pi/teams/config.json # legacy (when the repo already has .pi/)The project root is auto-detected by walking up from the current directory and stopping at any of: .git, .pi, .crew, .hg, .svn, .factory, .omc, or any common manifest file (package.json, pyproject.toml, Cargo.toml, go.mod, pom.xml, composer.json, build.gradle[.kts]). If the project already has a .pi/ directory, pi-crew reuses it under .pi/teams/ to avoid creating a parallel layout; otherwise it uses .crew/.
Config merge priority:
user < project for ordinary presentation/UX settingsTrust-boundary exception: project config is intentionally not trusted for sensitive execution controls. Project-level values such as executeWorkers, asyncByDefault, runtime mode/live-session inheritance, autonomy mode, agents.disableBuiltins, agents.overrides, worktree.setupHook, and otlp.headers are ignored with warnings. Set those in user config when you want to trust them explicitly.
Resource discovery trust boundary: project-local agents, teams, and workflows may add new names, but cannot shadow builtin or user resources with the same name.
Supported config:
{
"asyncByDefault": false,
"executeWorkers": true,
"notifierIntervalMs": 5000,
"requireCleanWorktreeLeader": true,
"autonomous": {
"profile": "suggested",
"enabled": true,
"injectPolicy": true,
"preferAsyncForLongTasks": false,
"allowWorktreeSuggestion": true,
"magicKeywords": {
"review": ["review", "audit", "inspect"]
}
},
"runtime": {
"mode": "auto",
"groupJoin": "smart",
"groupJoinAckTimeoutMs": 300000,
"requirePlanApproval": false,
"completionMutationGuard": "warn"
},
"limits": {
"maxConcurrentWorkers": 3,
"maxTaskDepth": 2,
"maxChildrenPerTask": 5,
"maxRunMinutes": 60,
"maxRetriesPerTask": 1,
"heartbeatStaleMs": 60000
},
"ui": {
"widgetPlacement": "aboveEditor",
"widgetMaxLines": 8,
"powerbar": true,
"dashboardPlacement": "right",
"dashboardWidth": 56,
"dashboardLiveRefreshMs": 1000,
"autoOpenDashboard": false,
"autoOpenDashboardForForegroundRuns": true,
"showModel": true,
"showTokens": true,
"showTools": true
},
"tools": {
"enableClaudeStyleAliases": true,
"enableSteer": true,
"terminateOnForeground": false
},
"telemetry": {
"enabled": true
},
"observability": {
"enabled": true,
"pollIntervalMs": 5000,
"metricRetentionDays": 7
},
"reliability": {
"autoRetry": false,
"autoRecover": false,
"deadletterThreshold": 3,
"retryPolicy": {
"maxAttempts": 3,
"backoffMs": 1000,
"jitterRatio": 0.3,
"exponentialFactor": 2
}
},
"otlp": {
"enabled": false,
"endpoint": "http://localhost:4318/v1/metrics"
}
}Safety notes:
- Foreground child-process runs continue in the Pi extension process and return control to chat immediately, so large workflows do not block the interactive session. They are interrupted on session shutdown. Use
async: trueonly for intentionally detached runs that may survive the current session. - Async completion notifications survive extension reload/auto-compaction: active runs are not marked consumed just because the notifier restarts, while stale owner-session callbacks are suppressed after session switches.
- Background
Agent/crew_agentruns notify the parent session when they reach a terminal state; the parent can then callget_subagent_result/crew_agent_resultand continue the original task. tools.terminateOnForegroundis an opt-in power-user setting. When true, foregroundAgent/crew_agentcalls return withterminate: trueafter the child result is available, saving one follow-up LLM turn. Default is false so the assistant can still summarize raw worker output.- Runtime state paths are treated as untrusted data: run ids, import bundles, artifact/transcript paths, mailbox files, and agent control/log files are validated with containment checks before reads or writes.
runtime.completionMutationGuarddefaults towarn; setoffto disable orfailto fail implementation-style tasks that report success without observed mutation tool calls.- Group-join result messages use normal mailbox delivery and normal
ack-message; missing acknowledgements never block run completion, and duplicate delivery attempts reuse the same request id/message instead of appending spam. - Common secret patterns (
token=,apiKey=,Authorization: Bearer ..., private keys, etc.) are redacted before durable logs/events/mailbox/artifacts/metrics/diagnostics are written. observability.enableddefaults to true for in-memory metrics and heartbeat watching. Metric JSONL snapshots are gated bytelemetry.enabled; settelemetry.enabled=falseto opt out of local telemetry files.reliability.autoRetryandreliability.autoRecoverdefault to false. Enabling retry may execute an idempotent task more than once; each attempt is recorded intask.attempts, and exhausted retries append a deadletter entry.otlp.enableddefaults to false. Configureotlp.endpointonly when you want to push metrics to an OTLP HTTP collector.
UI notes:
widgetPlacement/widgetMaxLineskeep the persistent active-run widget compact.dashboardPlacement: "right"is the default for/team-dashboard; automatic overlay opening is opt-in because Pi custom overlays can be modal/focus-capturing in some terminals.autoOpenDashboard/autoOpenDashboardForForegroundRunscontrol whether the live sidebar opens automatically.dashboardLiveRefreshMscontrols the live sidebar refresh cadence.showModel,showTokens, andshowToolsshow worker model attempts, token usage, and tool activity in dashboard agent rows.
Show config:
/team-configUpdate user config:
/team-config asyncByDefault=true notifierIntervalMs=5000Update project config:
/team-config autonomous.profile=assisted autonomous.preferAsyncForLongTasks=true --projectUnset/delete nested config keys:
/team-config --unset=autonomous.preferAsyncForLongTasks --project
/team-config autonomous.preferAsyncForLongTasks=unset --project
/team-config autonomous.preferAsyncForLongTasks=null --projectConfig schema is exported as:
./schema.jsonMain tool
The extension registers one main tool:
teamUse it for complex multi-file work, planning, implementation, tests, reviews, security audits, research, async/background runs, and worktree-isolated execution.
When unsure which team/workflow to choose, call:
{
"action": "recommend",
"goal": "Refactor auth flow and add tests"
}Tool actions
Supported actions:
| Action | Purpose |
|---|---|
| list | List discovered teams, agents, workflows, and recent runs |
| get | Inspect a named agent/team/workflow |
| recommend | Suggest team/workflow/action plus decomposition and fanout hints |
| run | Create a run and execute the workflow scheduler |
| plan | Validate and preview workflow execution without running tasks |
| status | Read durable run status |
| summary | Read/write run summary artifact |
| events | Read run event log |
| artifacts | List run artifacts |
| worktrees | List run worktree metadata |
| cancel | Cancel queued/running work |
| resume | Re-queue failed/cancelled/skipped/running tasks |
| cleanup | Clean run worktrees; dirty worktrees are preserved unless forced |
| forget | Delete run state/artifacts after confirm: true |
| prune | Delete old finished runs after confirm: true |
| export | Export a portable run bundle |
| import | Import a run bundle into local imports |
| imports | List imported run bundles |
| create | Create agent/team/workflow in user/project scope |
| update | Update agent/team/workflow with backup |
| delete | Delete agent/team/workflow with confirm: true and backup |
| validate | Validate agents, teams, workflows, references, and model hints |
| doctor | Check local readiness and optionally run child Pi smoke check |
| config | Show/update config |
| init | Create project .pi layout and update .gitignore |
| autonomy | Show/update autonomous delegation settings |
| api | Safe interop for run/task/event/heartbeat/claim/mailbox state, including plan approval/cancel operations |
| help | Show help text |
Example tool calls
Run a default team safely:
{
"action": "run",
"team": "default",
"goal": "Investigate failing tests and propose a fix"
}Run async:
{
"action": "run",
"team": "implementation",
"goal": "Implement the user settings screen",
"async": true
}Run with worktrees:
{
"action": "run",
"team": "implementation",
"workflow": "implementation",
"goal": "Add API endpoint and tests",
"workspaceMode": "worktree"
}Require explicit approval after the adaptive planner writes a plan artifact and before mutating workers run:
{
"action": "run",
"team": "implementation",
"workflow": "implementation",
"goal": "Refactor auth and update tests",
"config": {
"runtime": { "requirePlanApproval": true }
}
}Approve or cancel the pending plan:
{
"action": "api",
"runId": "team_...",
"config": { "operation": "approve-plan" }
}Inspect a run:
{
"action": "status",
"runId": "team_..."
}Create a routed agent:
{
"action": "create",
"resource": "agent",
"config": {
"scope": "project",
"name": "api-reviewer",
"description": "Reviews backend API changes",
"systemPrompt": "You review backend API changes for correctness and compatibility.",
"triggers": ["api", "endpoint", "contract"],
"useWhen": ["backend API change", "OpenAPI contract update"],
"avoidWhen": ["documentation-only edits"],
"cost": "cheap",
"category": "backend"
}
}Slash commands
Manual slash commands are ops/debug controls. Autonomous tool use via policy/recommendation is the primary agent-driven path.
/teams
/team-run [--team=name] [--workflow=name] [--async] [--worktree] <goal>
/team-cancel <runId>
/team-status <runId>
/team-summary <runId>
/team-resume <runId>
/team-events <runId>
/team-artifacts <runId>
/team-worktrees <runId>
/team-cleanup <runId> [--force]
/team-forget <runId> --confirm [--force]
/team-prune --keep=20 --confirm
/team-export <runId>
/team-import <path-to-run-export.json> [--user]
/team-imports
/team-api <runId> <operation> [key=value]
/team-metrics [filter]
/team-manager
/team-dashboard
/team-init [--copy-builtins] [--overwrite]
/team-config [key=value] [--unset=key.path] [--project]
/team-autonomy [status|on|off|manual|suggested|assisted|aggressive] [--prefer-async] [--no-worktree-suggest]
/team-validate
/team-help
/team-doctor/team-api examples
/team-api team_... read-manifest
/team-api team_... list-tasks
/team-api team_... read-task taskId=task_...
/team-api team_... read-events
/team-api team_... read-heartbeat taskId=task_...
/team-api team_... write-heartbeat taskId=task_... alive=true
/team-api team_... claim-task taskId=task_... owner=worker-1
/team-api team_... release-task-claim taskId=task_... owner=worker-1 token=...
/team-api team_... transition-task-status taskId=task_... owner=worker-1 token=... status=running
/team-api team_... send-message direction=outbox to=worker body="please check this"
/team-api team_... send-message taskId=task_... direction=inbox to=worker body="task scoped message"
/team-api team_... read-mailbox direction=outbox
/team-api team_... read-mailbox taskId=task_... direction=inbox
/team-api team_... ack-message messageId=msg_... # also acknowledges group-join result messages
/team-api team_... read-delivery
/team-api team_... validate-mailbox repair=true
/team-api team_... approve-plan
/team-api team_... cancel-planUse /team-metrics for a current metrics snapshot. The optional argument is a glob-style metric filter:
/team-metrics
/team-metrics crew.task.*Dashboard
Open:
/team-dashboardShortcuts:
↑/↓ or j/k select run
r reload run list
p toggle short/long progress preview
Enter or s show status
a list artifacts
u show summary
i API read-manifest
q or Esc closeManager
Open:
/team-managerCurrent flows:
- list resources/runs
- run a team
- show run status
- cleanup run worktrees
- create routed agent/team resources
- update routed agent/team resources
- doctor
Resource paths
Builtin package resources:
agents/*.md
teams/*.team.md
workflows/*.workflow.mdUser resources:
~/.pi/agent/agents/*.md
~/.pi/agent/teams/*.team.md
~/.pi/agent/workflows/*.workflow.mdProject resources (new default layout):
.crew/agents/*.md
.crew/teams/*.team.md
.crew/workflows/*.workflow.mdLegacy layout (when .pi/ already exists in the repo):
.pi/teams/agents/*.md
.pi/teams/teams/*.team.md
.pi/teams/workflows/*.workflow.mdDiscovery priority:
builtin < user < projectResource metadata
Agents and teams may include optional routing metadata in frontmatter:
---
name: api-reviewer
description: Reviews API changes
triggers: api, endpoint, contract
useWhen: backend API changes, OpenAPI changes
avoidWhen: docs-only edits
cost: cheap
category: backend
---These fields guide autonomous policy injection and recommend routing.
Builtin resources
Builtin agents include roles such as:
analyst
critic
executor
explorer
planner
reviewer
security-reviewer
test-engineer
verifier
writerBuiltin teams include:
default
fast-fix
implementation
research
reviewBuiltin workflows include:
default
fast-fix
implementation
research
reviewState layout
Project-local state is preferred when the cwd is inside a recognised project (any of the markers listed in the Config section above). Otherwise pi-crew falls back to user-global state.
The project state root (<crewRoot> below) resolves to:
<repoRoot>/.crew/ # default, used for new projects
<repoRoot>/.pi/teams/ # legacy reuse when .pi/ already existsTypical project-local state (<crewRoot> is one of the two paths above):
<crewRoot>/state/runs/{runId}/manifest.json
<crewRoot>/state/runs/{runId}/tasks.json
<crewRoot>/state/runs/{runId}/events.jsonl
<crewRoot>/artifacts/{runId}/...
<crewRoot>/worktrees/{runId}/{taskId}
<crewRoot>/imports/{runId}/run-export.jsonMailbox state:
<crewRoot>/state/runs/{runId}/mailbox/inbox.jsonl
<crewRoot>/state/runs/{runId}/mailbox/outbox.jsonl
<crewRoot>/state/runs/{runId}/mailbox/delivery.json
<crewRoot>/state/runs/{runId}/mailbox/tasks/{taskId}/inbox.jsonl
<crewRoot>/state/runs/{runId}/mailbox/tasks/{taskId}/outbox.jsonlUser-global fallback (shared with other Pi tools):
~/.pi/agent/extensions/pi-crew/state/runs/...
~/.pi/agent/extensions/pi-crew/artifacts/...
~/.pi/agent/extensions/pi-crew/imports/...Project initialization
Initialize project-local layout:
/team-initOptionally copy builtin resources:
/team-init --copy-builtins
/team-init --copy-builtins --overwriteCreated directories (new projects):
.crew/agents/
.crew/teams/
.crew/workflows/
.crew/imports/If the project already has .pi/, the legacy layout is initialised instead:
.pi/teams/agents/
.pi/teams/teams/
.pi/teams/workflows/
.pi/teams/imports/.gitignore entries are written for whichever layout is active, e.g.:
# new layout
.crew/state/
.crew/artifacts/
.crew/worktrees/
.crew/imports/
# legacy layout
.pi/teams/state/
.pi/teams/artifacts/
.pi/teams/worktrees/
.pi/teams/imports/Import/export
Export writes:
{artifactsRoot}/export/run-export.json
{artifactsRoot}/export/run-export.mdImport stores bundles under (new layout):
.crew/imports/{runId}/run-export.json
.crew/imports/{runId}/README.mdor under the legacy layout when .pi/ already exists:
.pi/teams/imports/{runId}/run-export.json
.pi/teams/imports/{runId}/README.mdor user-global imports with --user:
~/.pi/agent/extensions/pi-crew/imports/{runId}/run-export.json
~/.pi/agent/extensions/pi-crew/imports/{runId}/README.mdDoctor and validation
Validate resources:
/team-validateDoctor:
/team-doctorDoctor checks include:
- cwd
- platform/architecture/Node.js version
pi --versiongit --version- writable state paths
- config parse
- discovery counts
- resource validation
- current model/provider when available
- model/fallback hints
Optional child Pi smoke check is explicit only:
{
"action": "doctor",
"config": {
"smokeChildPi": true
}
}Environment variables
PI_CREW_EXECUTE_WORKERS=0 disable child workers and use scaffold/dry-run mode
PI_TEAMS_EXECUTE_WORKERS=0 legacy disable flag
PI_TEAMS_MOCK_CHILD_PI=success test/mock child worker success
PI_TEAMS_MOCK_CHILD_PI=json-success
PI_TEAMS_MOCK_CHILD_PI=retryable-failure
PI_TEAMS_INHERIT_PROJECT_CONTEXT control child prompt context inheritance
PI_TEAMS_INHERIT_SKILLS control skill inheritance
PI_TEAMS_HOME override home path for tests/config/state
PI_TEAMS_PI_BIN optional explicit Pi CLI script/shim path for doctor/child workersDevelopment
Install dependencies:
cd pi-crew
npm installRun tests:
npm testTypecheck and smoke import:
npm run typecheckFull local CI-equivalent check:
npm run ciGitHub CI runs the same typecheck/test/pack checks on:
ubuntu-latest
windows-latest
macos-latestPackage dry-run only:
npm pack --dry-runDocumentation
Package docs:
pi-crew/docs/architecture.md
pi-crew/docs/usage.md
pi-crew/docs/resource-formats.md
pi-crew/docs/live-mailbox-runtime.md
pi-crew/docs/publishing.mdHistorical workspace-level design/progress docs may exist in the original development workspace under docs/pi-crew-*, but package-maintained docs live under pi-crew/docs/.
Local Pi smoke
A local Pi smoke test requires an installed Pi CLI and a real Pi environment:
cd pi-crew
npm run smoke:piThen in Pi:
/team-doctor
/team-validate
/team-autonomy statusAcknowledgements
pi-crew builds on ideas and selected MIT-licensed implementation patterns from pi-subagents and oh-my-claudecode.
It also draws conceptual inspiration from oh-my-openagent; no oh-my-openagent source code is copied unless separately documented and license-compatible.
