pi-crew
Pi extension for coordinated AI teams, workflows, worktrees, and async task orchestration
Package details
Install pi-crew from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-crew- Package
pi-crew- Version
0.9.20- Published
- Jul 7, 2026
- Downloads
- 12K/mo · 2,247/wk
- Author
- bom0792
- License
- MIT
- Types
- extension, skill
- Size
- 14.5 MB
- Dependencies
- 7 dependencies · 4 peers
Pi manifest JSON
{
"extensions": [
"./index.ts"
],
"skills": [
"./skills"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-crew
⚠️ IMPORTANT — Read before using
pi-crew is a sub-agent orchestration layer that was developed almost entirely by AI, for the author's own workflow. It is not a hardened, audited product. Here's the honest framing:
- AI-generated code, limited human review. The vast majority of pi-crew was written and iterated on by autonomous AI agents. While every change goes through static review + runtime tests, I (the author) have not line-by-line verified everything. There will be bugs, edge cases, and behaviors I haven't anticipated.
- It can spawn processes, run shell commands, and write files on your behalf. Dynamic workflows (
.dwf.ts) and goal loops run with the same privileges as your Pi session — treat any.dwf.tslikenode script.jsyou downloaded from the internet.- Built for my needs, not yours. This scratches a personal itch. It likely won't fit every workflow, team setup, or risk tolerance — and that's fine.
If that sounds too risky, don't use it — no hard feelings.
If you still want to use it, the safest path is to fork it, read the parts you'll touch, and adapt it to your own setup. If you find a bug, a footgun, or a sharp edge, please open an issue or send a note — your feedback is genuinely appreciated. Thanks. ✌️
See also: SECURITY-ISSUES.md, docs/dynamic-workflows.md (trust model), and the Known limitations section below.
Coordinate AI agent teams inside Pi.
pi-crew is a Pi extension that orchestrates autonomous multi-agent workflows — research, implementation, review, testing, and more — with durable state, parallel execution, worktree isolation, and safe defaults.
npm: pi-crew
repo: https://github.com/baphuongna/pi-crew
Features
- Workflow topology advisory (v0.9.15) — before each run, pi-crew classifies the workflow's shape (
single/sequential/concurrent/complex-dag) and prints an advisory note with measured cost evidence (e.g. "3-step sequential: measured 5.7× slower than 3 raw Agent calls — proceeding anyway"). Never blocks — the agent decides. Tool description and prompt-snippet carry the same guidance up-front, so agents know the trade-off before calling. New files:src/workflows/topology-analyzer.ts,src/workflows/preflight-validator.ts. See Workflow topology advisory below. - One Pi tool —
teamhandles routing, planning, execution, review, and cleanup - Autonomous delegation — policy injection decides when/how to delegate based on task complexity
- needs_attention status — tasks that complete without calling
submit_resultgetneeds_attention(terminal) instead ofcompleted; allows retry/re-run without blocking downstream phases - Real child Pi workers — each task spawns a separate Pi process by default; scaffold/dry-run opt-out
- Adaptive planning — implementation workflow lets a planner agent decide subagent fanout
- Parallel execution — tasks in the same phase run concurrently with configurable concurrency
- Durable state — manifest, tasks, events, artifacts all persisted to disk
- Async/background runs — detached runs survive session switches with completion notifications
- Worktree isolation — opt-in git worktrees per task for safe parallel edits
- Rich UI — live widget, dashboard, progress tracking, model/token display
- Observability — metrics registry, Prometheus/OTLP exporters, heartbeat watching, deadletter queue
- Resource management — create/update/delete agents, teams, workflows with validation
- Import/export — portable run bundles for sharing and archiving
- Adaptive plan fanout — single
assessstep lets a planner pick the smallest effective crew - Adaptive workflows —
implementation,review,parallel-research,researchworkflows ship inworkflows/ - Hardened secrets — linear-time detection covers PEM keys, Authorization headers, Bearer tokens, and
key=valuepatterns - Scheduled runs —
schedule/scheduledactions with cron, interval, and one-shot support; spawned runs tracked and auto-cancelled on job removal - Plugin system — framework-aware context injection (Next.js, Vite, Vitest) via plugin registry
- Health scoring — penalty-based run health with time-series snapshots
- Autonomous goal loops (P0/P1) —
team action='goal'runs an autonomous multi-turn loop: a worker does a turn, a separate LLM judge evaluates the transcript+evidence against the goal, and on "not-achieved" the reason is fed into the next turn's prompt. Stops on achieved / maxTurns / budget / blocked. Claude-Code-style/goal. Seedocs/goals.md. - Dynamic workflows (P2/P3) — author orchestration as a
.dwf.tsscript (JS loops/branch/cross-review) instead of a static step list. The script runs in the background, calls subagents viactx.agent()/ctx.fanOut(), holds intermediate results in JS variables, and onlyctx.setResult()reaches the main context.ctx.phase()marks logical phases; round-14 addsctx.log()(durabledwf.logevents),ctx.budget(per-workflow token budget that auto-rejectsctx.agent()when exhausted), andctx.args<T>()(typed workflow arguments). TypeScript IntelliSense is available viaimport type { WorkflowCtx } from "pi-crew/workflow".workflow-create/-delete/-saverequireconfirm:trueat the tool-call layer (the only gate — a malicious agent that passesconfirm:trueprogrammatically bypasses it; this is postinstall-equivalent trust, not a human-in-the-loop dialog). Seedocs/dynamic-workflows.md. - Strict SKILL.md validation (L3, v0.9.8) — skills with malformed frontmatter (missing/malformed
name/description, type mismatches) now fail-fast at discovery with visible diagnostics, instead of silently producing broken behavior at runtime. HYBRID policy: HARD on required fields, SOFT (warn) on unknown props for forward-compat. Surfaced viabuildSkillValidationDiagnostics(). - Durable event replay (L1, v0.9.8) —
RunEventBus.onWithReplay()catches up a re-subscribing dashboard/overlay with events it missed during transient absence (toggle, reconnect), replaying from the durable JSONL log with seq-based dedup. No information loss even if the live subscriber was briefly gone. - Lossless-by-default output handling (L4, v0.9.8) — worker output thresholds sized from measured data (100% of real outputs fit without compaction); when compaction is unavoidable it keeps head+tail (preserves closing code fences/headings) instead of head-only truncation. No more
[pi-crew compacted N chars]markers eating the end of a worker's result.
Install
pi install npm:pi-crew
Local development:
pi install ./pi-crew
Post-install config bootstrap:
pi-crew # after npm install
node ./pi-crew/install.mjs # from local clone
Split-scope install note (v0.8.11+): pi installs extensions under
~/.pi/agent/npm/node_modules/<ext>/, separate from pi's own node_modules tree (nvm /%APPDATA%\npm/ Volta / fnm). Since v0.8.11 pi-crew resolves the@earendil-works/pi-coding-agentpeer dep robustly across these layouts — no symlink/NODE_PATH workaround needed. If you ever do hitCannot find module '@earendil-works/pi-coding-agent', setPI_CREW_PEER_DEP_DIR=<path to the pi-coding-agent package dir>as a one-line workaround (or install pi-crew in pi's own scope:npm install -g @earendil-works/pi-crew).
Uninstall
pi uninstall npm:pi-crew removes the package, but pi doesn't fire an
extension uninstall hook, so several things pi-crew created are left behind.
Reverse them explicitly with team action=cleanup. There are two scopes:
v0.8.14+:
team action=initno longer injects a guidance block into AGENTS.md (it was redundant — theteamtool self-describes via its tool registration, so the agent learns pi-crew's commands from there, not AGENTS.md). The cleanup steps below still work for removing blocks injected by older versions (<0.8.14).
Project scope (reverse team action=init)
# 1. (Optional) Preview what would be removed, without writing:
team action=cleanup dryRun=true
# 2. Remove the AGENTS.md guidance block only (.crew/ preserved):
team action=cleanup
# 3. Remove BOTH the guidance block AND the .crew/ state directory (force):
team action=cleanup force=true
The guidance block is wrapped in <!-- PI-CREW:GUIDANCE:START --> /
<!-- PI-CREW:GUIDANCE:END --> markers, so cleanup removes only that
block — your own AGENTS.md content is never touched. The .crew/ directory
is removed only with force=true (it's irreversible).
User scope (remove user-level state pi uninstall leaves behind)
# 4. Preview + remove pi-crew user-scope junk:
team action=cleanup scope=user dryRun=true # preview
team action=cleanup scope=user # remove ~/.pi/agent/extensions/pi-crew/
# + pi-crew smoke-test *.bak files
# 5. (Optional) Also remove the global config (holds your settings):
team action=cleanup scope=user force=true # also removes ~/.pi/agent/pi-crew.json
This removes the pi-crew state dir (~/.pi/agent/extensions/pi-crew/, which
holds run artifacts + state), the global config (with force=true), and the
*.md.bak-<timestamp> smoke-test backup files pi-crew's own tests may leave in
~/.pi/agent/agents/. Your authored agent files (*.md) are never touched
— pi-crew can't tell which were user-created vs test-copied, so only the
clearly-pi-crew .bak-* backups are removed.
Final step
# 6. Remove the package itself:
pi uninstall npm:pi-crew
Quick Start
1. Initialize project
/team-init
2. Run a team
/team-run Investigate failing tests and propose a fix
Or via tool call:
{
"action": "run",
"team": "default",
"goal": "Investigate failing tests and propose a fix"
}
3. Check status
/team-status <runId>
/team-dashboard
4. Get a recommendation
When unsure which team/workflow fits:
{
"action": "recommend",
"goal": "Refactor auth flow and add tests"
}
Builtin Teams
| Team | Workflow | Purpose |
|---|---|---|
default |
explore → plan → execute → verify | Balanced, general-purpose |
fast-fix |
explore → execute → verify | Quick bug fixes |
implementation |
Adaptive planner decides fanout | Multi-file implementation |
review |
explore → code-review → security-review → verify | Code review + security audit |
research |
explore → analyze → write | Research and documentation |
parallel-research |
Parallel shards → synthesize → write | Multi-source research |
Workflow topology advisory
Before every team action='run', pi-crew classifies the workflow shape and prints an informational note. It never blocks — agents decide whether to proceed, refactor, or override.
How it works
team action='run', workflow='fast-fix', goal='...'
↓
pi-crew analyzes topology: 3-step sequential
↓
⚠️ [team-tool.preflight] WARN: 3-step sequential chain: measured 5.7× slower
and 1.9× costlier than 3 raw Agent calls (Run #3 in .crew/state/runs/).
Proceeding anyway.
↓
Workflow runs to completion. Agent sees the note, decides for next time.
Topology → advisory level
| Topology | When | Level | What pi-crew prints |
|---|---|---|---|
single |
1 step, no concurrency | warn |
"raw Agent tool would be ~30× faster and ~5× cheaper. Proceeding anyway." |
sequential (2-3 steps) |
Linear chain, no fan-out | warn |
"measured 5.7× slower than raw Agent calls. Proceeding anyway." |
sequential (4+ steps) |
Linear chain, longer | warn |
"audit trail may justify pi-crew overhead. Proceeding anyway." |
concurrent |
≥3 truly parallel agents (parallelGroup) | note |
"✅ Validated use case: N-way parallel fan-out. pi-crew's parallelism wins." |
complex-dag |
4+ steps with data dependencies | note |
"✅ Validated use case: complex DAG with adaptive plan." |
dynamic |
.dwf.ts script |
info |
"Runtime decides topology." |
When to prefer raw Agent over team
Use the raw Agent tool when:
- You have a single task or quick question (1-step)
- You have 2–3 sequential independent steps (no DAG branching, no concurrency)
Use team when:
- You have ≥3 agents running TRULY CONCURRENTLY (
parallelGroup) - You have a COMPLEX DAG (4+ steps with data dependencies, branching)
- You need an audit trail, team coordination, or worktree isolation that justifies pi-crew's overhead
How agents learn the rule
The guidance is available in three places agents see:
teamtool description — the LLM reads this when considering whether to call the tool. Includes an explicit "ℹ️ ADVISORY NOTE (preflight, never blocks)" section.teamprompt snippet — rendered in agent context when the tool is relevant. Single-line summary of the rule..crew/knowledge.mdCONVENTIONS section — always injected into every worker session's context. Contains the full 4-question self-check.
How to silence the advisory
The advisory is informational only — there is no force:true flag needed (the run proceeds regardless). If you want to silence the console.warn output for cleaner logs, set PI_CREW_QUIET_PREFLIGHT=1 in your environment.
Implementation
src/workflows/topology-analyzer.ts— pure classifier (parses workflow YAML, builds DAG, detects parallelGroups)src/workflows/preflight-validator.ts— returns{level: info|note|warn, message, suggestion}(never throws)- Integration:
src/extension/team-tool/run.ts(extension layer, prints advisory) +src/runtime/team-runner.ts(defense-in-depth, also logs)
Tests
test/unit/topology-analyzer.test.ts— 13 cases (each topology + edge cases)test/unit/preflight-validator.test.ts— 11 cases (each level + advisory contract)
Builtin Agents
analyst · critic · executor · explorer · planner · reviewer
security-reviewer · test-engineer · verifier · writer
Runtime Modes
pi-crew supports multiple runtime modes for task execution:
| Mode | Description |
|---|---|
auto (default) |
Uses child-process unless overridden by config |
child-process |
Spawns real pi child processes — each task runs in isolation |
scaffold |
Dry-run mode — renders prompts and persists artifacts without executing |
live-session (experimental) |
In-process session execution within the parent Pi |
// Use scaffold mode (no real workers, just prompts)
{ "action": "run", "team": "default", "goal": "...", "runtime": { "mode": "scaffold" } }
// Disable workers globally
{ "executeWorkers": false }
Async Runs
Async runs are detached from the session — they survive session switches and reloads. Pi-crew notifies when complete.
{ "action": "run", "team": "default", "goal": "...", "async": true }
/team-run --async Investigate failing tests
Background runs use node --import jiti-register.mjs for TypeScript support. See docs/runtime-flow.md for details.
Worktree Isolation
Worktree mode creates an isolated git worktree per task — safe for parallel edits to the same branch.
{
"action": "run",
"team": "implementation",
"goal": "Refactor auth",
"workspaceMode": "worktree"
}
/team-run --worktree Refactor auth
Requirements:
- Git repository (cwd must be inside a git repo)
- Clean working tree (no uncommitted changes in the leader worktree)
- Can be disabled via config:
requireCleanWorktreeLeader: false
- Can be disabled via config:
- Worktrees auto-cleanup on run completion/cancel
If preconditions are not met, a friendly error message is returned instead of crashing.
Configuration
Config Paths
| Scope | Path |
|---|---|
| User (primary) | ~/.pi/agent/pi-crew.json |
| User (legacy, still read for migration) | ~/.pi/agent/extensions/pi-crew/config.json |
| Project (crewRoot) | .crew/config.json (or .pi/teams/config.json legacy) |
| Project (alt) | .pi/pi-crew.json |
Quick Config
/team-config # view all settings
/team-config runtime.mode=scaffold # set a key (--project for project scope)
/team-config --unset=runtime.mode # reset a key to default
/team-config --project runtime.mode # project-scoped view
/team-settings path # show config file path
Key Settings
| Section | Keys | Default |
|---|---|---|
| Runtime | mode: auto | child-process | scaffold | live-session |
auto |
maxTurns, graceTurns, groupJoin, requirePlanApproval |
various | |
| Concurrency | limits.maxConcurrentWorkers |
workflow-dependent |
limits.maxTaskDepth, limits.maxChildrenPerTask |
2, 5 | |
| Async | asyncByDefault |
false |
runtime.groupJoin: off | group | smart |
smart |
|
| Autonomy | profile: manual | suggested | assisted | aggressive |
suggested |
autonomous.injectPolicy, preferAsyncForLongTasks |
true, false | |
| UI | widgetPlacement, dashboardPlacement |
compact widget |
showModel, showTokens |
display controls | |
| Reliability | autoRetry, autoRecover, deadletterThreshold |
opt-in |
| Observability | observability.enabled, observability.pollIntervalMs, otlp.enabled/otlp.endpoint |
opt-in |
| Worktree | worktree.setupHook, worktree.linkNodeModules, worktree.seedPaths (mode is set via workspaceMode: "worktree" at run time) |
disabled by default |
⚠️ Trust boundary: project config cannot override sensitive execution controls (workers, runtime mode, autonomy, agent overrides). Set those in user config only.
📖 Full config reference: docs/commands-reference.md#team-settings--config-management and schema.json
Reliability & Trust
Compaction resilience
pi-crew survives Pi's context compaction. When the context is compacted (auto or manual), in-flight crew runs are detected and a resume directive is injected into the post-compaction context, so tasks continue instead of stalling. You'll see a notification like:
Context compacted. 1 pi-crew run(s) still in-flight — use team status to continue.
Durable event replay (v0.9.8, L1): even if a dashboard/overlay is briefly gone during compaction or a reconnect, RunEventBus.onWithReplay() catches it up with the events it missed, replaying from the durable JSONL log with seq-based dedup — no information loss. (The dashboard wires this up per-run; the primitive is available for any subscriber.)
Lossless-by-default worker output (v0.9.8, L4): output-handling thresholds are sized from measured real data (100% of real worker outputs fit without any compaction). When compaction is unavoidable, it keeps head+tail instead of head-only truncation, so closing code fences and headings survive — no more [pi-crew compacted N chars] markers eating the end of a result.
Plan-level human-in-the-loop (HITL)
Set runtime.requirePlanApproval = true to gate any workflow at the plan→execute boundary. After the read-only (planning) phases complete, the run pauses for explicit approval before mutating tasks run:
team api op=approve-plan runId=<runId> # approve → execute
team api op=cancel-plan runId=<runId> # cancel
This is plan-level (not per-step) — per-step gates would kill the parallelism that's pi-crew's point.
Cross-run memory (.crew/knowledge.md)
Create .crew/knowledge.md in your project root with durable learnings (code style, test commands, common pitfalls, past refactors). It's auto-read (up to 16KB) and injected into every agent's system prompt — the main session and each crew worker. pi-crew gets better the longer you use it.
# Project Knowledge
- Tests: run with `npm test` (not jest directly)
- Style: tabs, not spaces
- Auth refactor (2026-06): split auth.ts into session.ts + api.ts
Cost visibility
Every team summary <runId> includes a per-role cost report:
═══ Cost Report ═══
Tokens: 134k (in 112k, out 5.7k, cache-write 16k)
Cost: $0.7700 across 18 turn(s)
By role:
executor (2 tasks): $0.6100 — 79%, 98k tok, 13 turns
reviewer (1 task): $0.1100 — 14%, 23k tok, 3 turns
Single-agent mode (cliff hedge)
Any workflow can run single-agent instead of multi-agent — composing all phases into one sequential prompt:
team plan team=default workflow=default goal="..." singleAgent=true
This is pi-crew's cliff-resilient mode: the workflow definitions, phase structure, and artifact contracts survive even if a single large-context model outperforms multi-agent teams.
Tool Actions
// Execute workflow (foreground or async)
{ "action": "run", "team": "default", "goal": "..." }
{ "action": "run", "team": "default", "goal": "...", "async": true }
// Monitor & control
{ "action": "status", "runId": "team_..." }
{ "action": "summary", "runId": "team_..." }
{ "action": "events", "runId": "team_..." }
{ "action": "artifacts", "runId": "team_..." }
{ "action": "cancel", "runId": "team_..." }
{ "action": "resume", "runId": "team_..." }
{ "action": "retry", "runId": "team_..." }
{ "action": "steer", "runId": "team_...", "taskId": "01_explore", "message": "Focus on src/ only" }
{ "action": "respond", "runId": "team_...", "message": "Answer" }
{ "action": "wait", "runId": "team_..." }
// Discovery
{ "action": "list" }
{ "action": "get", "resource": "team", "team": "default" }
{ "action": "get", "resource": "agent", "agent": "explorer" }
{ "action": "get", "resource": "workflow", "workflow": "review" }
{ "action": "recommend", "goal": "Refactor auth flow" }
{ "action": "search", "goal": "heartbeat detection" }
// Resource management
{ "action": "create", "resource": "agent", "config": { "name": "api-reviewer", ... } }
{ "action": "update", "resource": "team", "name": "backend", "config": { ... } }
{ "action": "delete", "resource": "workflow", "name": "quick-review" }
{ "action": "validate" }
// Run maintenance
{ "action": "cleanup", "runId": "team_..." }
{ "action": "forget", "runId": "team_...", "confirm": true }
{ "action": "prune", "olderThanDays": 7, "confirm": true }
{ "action": "export", "runId": "team_..." }
{ "action": "import", "path": "/path/to/bundle.tar.gz" }
// Environment & configuration
{ "action": "doctor", "config": { "smokeChildPi": true } }
{ "action": "config" }
{ "action": "init", "config": { "copyBuiltins": true } }
{ "action": "autonomy", "profile": "assisted" }
// Advanced
{ "action": "api", "runId": "team_...", "config": { "operation": "read-manifest" } }
{ "action": "plan", "team": "default", "goal": "..." }
{ "action": "orchestrate", "planPath": "plan.md", "team": "implementation", "goal": "..." }
{ "action": "parallel", "config": { "tasks": [{"goal": "...", "agent": "explorer"}] } }
{ "action": "worktrees", "runId": "team_..." }
{ "action": "graph", "runId": "team_..." }
{ "action": "explain", "runId": "team_..." }
{ "action": "health" }
{ "action": "doctor" }
{ "action": "cache" }
{ "action": "invalidate", "runId": "team_..." }
// Scheduled runs
{ "action": "schedule", "team": "fast-fix", "goal": "Run tests", "cron": "0 9 * * MON" }
{ "action": "schedule", "team": "default", "goal": "...", "interval": 3600000 }
{ "action": "schedule", "team": "research", "goal": "...", "once": "+10m" }
{ "action": "scheduled" }
// Diagnostics & settings
{ "action": "config" }
{ "action": "settings" }
{ "action": "autonomy" }
{ "action": "anchor" }
{ "action": "onboard" }
{ "action": "auto-summarize" }
📖 Full actions reference (40+ actions): docs/actions-reference.md
Slash Commands
/team-run [--team=X] [--async] [--worktree] <goal>
/team-status <runId>
/team-dashboard
/team-doctor
/team-init [--copy-builtins]
/team-config [key=value]
/team-autonomy [status|on|off|suggested|assisted]
📖 Full commands reference: docs/commands-reference.md
Resource Discovery
Agents, teams, and workflows are discovered from three layers:
builtin (package) < user (~/.pi/agent/) < project (.crew/ or .pi/teams/)
Project resources can add new names but cannot shadow builtin/user resources.
Resource Paths
| Type | Builtin | User | Project |
|---|---|---|---|
| Agent | agents/*.md |
~/.pi/agent/agents/*.md |
.crew/agents/*.md |
| Team | teams/*.team.md |
~/.pi/agent/teams/*.team.md |
.crew/teams/*.team.md |
| Workflow | workflows/*.workflow.md |
~/.pi/agent/workflows/*.workflow.md |
.crew/workflows/*.workflow.md |
Custom Resources with Routing Metadata
---
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
---
Your system prompt here.
📖 Full resource formats: docs/resource-formats.md
State Layout
<crewRoot>/ # .crew/ (new) or .pi/teams/ (legacy)
├── state/runs/{runId}/
│ ├── manifest.json # run metadata
│ ├── tasks.json # task graph + status
│ ├── events.jsonl # append-only events
│ └── agents/{taskId}/status.json # per-agent state
├── artifacts/{runId}/
│ ├── goal.md
│ ├── prompts/{taskId}.md
│ ├── results/{taskId}.txt
│ ├── logs/{taskId}.log
│ └── summary.md
├── worktrees/{runId}/{taskId}/
└── imports/{runId}/run-export.json
Environment Variables
| Variable | Purpose |
|---|---|
PI_CREW_USE_BUNDLE=1 |
Load via bundled dist/index.mjs (~5% faster cold-start). Default: strip-types. Requires npm run build:bundle to have produced dist/. Falls back to strip-types with a one-time warning if the bundle is missing. See scripts/bench-cold-start.mjs. |
PI_CREW_EXECUTE_WORKERS=0 |
Disable child workers (scaffold mode) |
PI_TEAMS_EXECUTE_WORKERS=0 |
Legacy disable flag |
PI_TEAMS_MOCK_CHILD_PI=success |
Mock child worker for testing |
PI_TEAMS_PI_BIN=<path> |
Explicit Pi CLI path |
PI_TEAMS_HOME=<path> |
Override home for tests |
Development
Auto-rebuild bundle on edit
For active development on the bundle, run the watcher in a separate terminal:
npm run watch:bundle
This watches src/ + index.bundle.ts and rebuilds dist/index.mjs after a 300ms debounce. Zero added dependencies (uses native node:fs.watch with per-directory watchers).
npm run watch:bundle # watch + auto-rebuild
npm run watch:bundle --debounce 500 # custom debounce
node scripts/watch-bundle.mjs --once # build once and exit (CI prep)
The watcher is the dev-loop companion to check:bundle-staleness (CI gate) — together they eliminate the "edit src/foo.ts, forget to rebuild, run stale bundle" failure mode.
cd pi-crew
npm install # dependencies
npm test # unit + integration tests (~4,800 tests)
npm run typecheck # tsc --noEmit
npm run ci # full CI-equivalent check
npm pack --dry-run # package verification
Stats: 431 source files (87K lines) · 606 test files (85K lines) · ~5,860 tests, 0 failures · CI: Ubuntu ✅ macOS ✅ Windows ✅
Documentation
| Doc | Contents |
|---|---|
| docs/actions-reference.md | Full tool actions + examples |
| docs/commands-reference.md | Slash commands + /team-api |
| docs/resource-formats.md | Agent/team/workflow file formats |
| docs/usage.md | Usage patterns + config examples |
| docs/troubleshooting.md | Common errors, recovery, and error-code reference (E001–E012) |
| docs/architecture.md | Internal architecture + run flow |
| docs/runtime-flow.md | Runtime execution details |
| docs/goals.md | v0.9.0 Autonomous goal loops (team action='goal') |
| docs/dynamic-workflows.md | v0.9.0 .dwf.ts script runtime + trust model |
| docs/live-mailbox-runtime.md | Mailbox + live-session runtime |
| docs/publishing.md | Release & publish process |
| docs/next-upgrade-roadmap.md | Future upgrade roadmap |
| schema.json | Config JSON schema |
Research docs (not in package): docs/pi-crew-research/ — audits, deep research, distillation notes.
Known limitations
This is AI-developed software built for a personal workflow. These are the sharp edges I'm aware of — there are almost certainly others I'm not.
- Multi-step goal-wrap crashes non-deterministically. Goal-wrapping
multi-step builtin workflows (
fast-fix,default) can hit a V8/libuv event-loop race that kills the background process with no signal, no core, and no V8 diagnostic report (8 investigation attempts: gdb, strace, perf,--report-on-fatalerror, sync-fs workarounds, worker-thread atomic writer — seeresearch-findings/goal-workflow/17-PHASE1.5-CRASH-INVESTIGATION-RFC.md). Mitigation: multi-step workflows silently auto-downgrade to a normal team-run (no goal-wrap layer); single-step workflows (implementation) goal-wrap end-to-end. .dwf.tsscripts are NOT sandboxed in v1. TheWorkflowCtxisObject.freeze()d, but the script runs in plain module scope with fullrequire/import/processaccess (postinstall-equivalent trust).isolated-vm(real V8 isolate) is planned for a future release. Only place.dwf.tsfiles you have reviewed. See docs/dynamic-workflows.md#security-model-important.- Editor/agent file caching. After editing a loaded pi-crew source file,
restart the Pi session for changes to take effect (jiti in-memory cache).
Editing a
.dwf.tsin place while a run is mid-flight can serve a stale module body; rename the file or restart Pi to force a fresh load. - Verification integrity is best-effort against adversarial workers. The bookend snapshot (P1a) and git-worktree sandbox (Phase 1.5 #2, opt-in) raise the bar, but a worker in the same process can still tamper with files outside the snapshot window. Full isolation requires the planned sandbox.
- Single maintainer + AI review. Every change ships after 2+ consecutive clean static-review rounds + runtime tests, but there's no independent human audit. Fork and read before trusting anything that touches your data.
If you hit any of these — or a new one — please open an issue.
Acknowledgements
pi-crew builds on ideas and selected MIT-licensed implementation patterns from pi-subagents and oh-my-claudecode, with conceptual inspiration from oh-my-openagent.