pi-crew 0.11.1 → 0.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/CHANGELOG.md +39 -9
  2. package/README.md +161 -1036
  3. package/agents/verifier.md +18 -7
  4. package/dist/index.mjs +744 -91462
  5. package/docs/README.md +57 -46
  6. package/docs/architecture.md +87 -33
  7. package/docs/commands-reference.md +9 -5
  8. package/docs/troubleshooting.md +3 -2
  9. package/package.json +1 -3
  10. package/schema.json +29 -0
  11. package/skills/real-test-pi-crew/SKILL.md +193 -36
  12. package/src/agents/agent-config.ts +1 -1
  13. package/src/agents/discover-agents.ts +1 -1
  14. package/src/config/config-validation.ts +15 -0
  15. package/src/config/config.ts +47 -13
  16. package/src/config/env-vars.ts +35 -0
  17. package/src/config/types.ts +19 -0
  18. package/src/errors.ts +2 -2
  19. package/src/extension/async-notifier.ts +23 -0
  20. package/src/extension/help.ts +21 -10
  21. package/src/extension/knowledge-injection.ts +2 -1
  22. package/src/extension/management.ts +8 -3
  23. package/src/extension/notification-sink.ts +17 -0
  24. package/src/extension/registration/command-utils.ts +28 -2
  25. package/src/extension/registration/commands/dashboard.ts +11 -1
  26. package/src/extension/registration/commands/manage.ts +31 -15
  27. package/src/extension/registration/commands/run.ts +24 -2
  28. package/src/extension/registration/commands/shared.ts +23 -0
  29. package/src/extension/registration/commands/status.ts +25 -2
  30. package/src/extension/registration/context-builder.ts +8 -2
  31. package/src/extension/registration/health-notify-policy.ts +100 -0
  32. package/src/extension/registration/lazy-configurers.ts +35 -0
  33. package/src/extension/registration/lifecycle-handlers.ts +91 -30
  34. package/src/extension/registration/lifecycle.ts +75 -10
  35. package/src/extension/registration/observability.ts +98 -35
  36. package/src/extension/registration/registration-types.ts +7 -5
  37. package/src/extension/registration/runtime-cleanup.ts +9 -3
  38. package/src/extension/registration/subagent-helpers.ts +38 -0
  39. package/src/extension/registration/wire-cross-extension.ts +28 -0
  40. package/src/extension/run-compare.ts +220 -0
  41. package/src/extension/run-export.ts +37 -5
  42. package/src/extension/run-maintenance.ts +155 -5
  43. package/src/extension/team-tool/dispatch/index.ts +3 -2
  44. package/src/extension/team-tool/dispatch/manage.ts +5 -2
  45. package/src/extension/team-tool/goal.ts +4 -1
  46. package/src/extension/team-tool/handle-settings.ts +19 -2
  47. package/src/extension/team-tool/health-monitor.ts +21 -7
  48. package/src/extension/team-tool/lifecycle-actions.ts +49 -1
  49. package/src/extension/team-tool/plan.ts +10 -0
  50. package/src/extension/team-tool/routing-hint.ts +63 -0
  51. package/src/extension/team-tool/status.ts +4 -0
  52. package/src/extension/team-tool.ts +52 -6
  53. package/src/extension/webhook-notify.ts +382 -0
  54. package/src/observability/metric-sink.ts +12 -2
  55. package/src/prompt/prompt-runtime.ts +82 -31
  56. package/src/prompt/worker-events-channel.ts +12 -0
  57. package/src/runtime/README.md +1 -1
  58. package/src/runtime/async-runner.ts +87 -1
  59. package/src/runtime/background-runner.ts +313 -234
  60. package/src/runtime/broker/crew-broker.ts +17 -11
  61. package/src/runtime/broker/delegate/shadow-lifecycle.ts +92 -0
  62. package/src/runtime/broker/wait-status-cache.ts +1 -1
  63. package/src/runtime/child-pi/child-pi-timers.ts +1 -1
  64. package/src/runtime/child-pi/mock-fixtures.ts +48 -0
  65. package/src/runtime/crew-agent-records.ts +337 -45
  66. package/src/runtime/deadletter.ts +43 -1
  67. package/src/runtime/delegate-spawn.ts +5 -1
  68. package/src/runtime/dispatch-batch.ts +72 -5
  69. package/src/runtime/goal-workflow/goal-loop-runner.ts +73 -4
  70. package/src/runtime/heartbeat/heartbeat-watcher.ts +7 -0
  71. package/src/runtime/model/model-fallback.ts +21 -1
  72. package/src/runtime/model/pi-args.ts +8 -10
  73. package/src/runtime/recovery/crash-recovery.ts +25 -1
  74. package/src/runtime/run-worker.ts +12 -1
  75. package/src/runtime/scheduling/global-worker-cap.ts +13 -6
  76. package/src/runtime/scheduling/run-coalesced-task-group.ts +27 -1
  77. package/src/runtime/scheduling/scheduler.ts +49 -13
  78. package/src/runtime/scheduling/semaphore.ts +148 -20
  79. package/src/runtime/scratchpad/README.md +1 -1
  80. package/src/runtime/scratchpad/protocol.ts +1 -1
  81. package/src/runtime/settings-store.ts +1 -1
  82. package/src/runtime/skill-instructions.ts +22 -0
  83. package/src/runtime/stale-reconciler.ts +85 -13
  84. package/src/runtime/task-runner/pre-execution.ts +26 -2
  85. package/src/runtime/task-runner/prompt-builder.ts +142 -45
  86. package/src/runtime/task-runner.ts +21 -1
  87. package/src/runtime/team-runner.ts +38 -1
  88. package/src/runtime/workspace-lock.ts +4 -1
  89. package/src/schema/config-schema.ts +14 -0
  90. package/src/schema/team-tool-schema.ts +17 -0
  91. package/src/state/atomic-write.ts +53 -0
  92. package/src/state/contracts.ts +109 -0
  93. package/src/state/coordination/locks.ts +191 -33
  94. package/src/state/coordination/mailbox.ts +140 -15
  95. package/src/state/crew-init.ts +87 -12
  96. package/src/state/event-log/cursor.ts +37 -1
  97. package/src/state/event-log/event-log-rotation.ts +72 -7
  98. package/src/state/stores/active-run-registry.ts +13 -1
  99. package/src/state/stores/state-store.ts +112 -22
  100. package/src/state/types.ts +4 -0
  101. package/src/ui/dashboard-panes/agents-pane.ts +11 -2
  102. package/src/ui/heartbeat-aggregator.ts +34 -0
  103. package/src/ui/keybinding-map.ts +22 -4
  104. package/src/ui/live-conversation-overlay.ts +6 -3
  105. package/src/ui/run-dashboard.ts +98 -5
  106. package/src/ui/run-snapshot-cache.ts +18 -1
  107. package/src/ui/spinner.ts +26 -2
  108. package/src/ui/tool-progress-formatter.ts +2 -1
  109. package/src/ui/tool-renderers/brief-mode.ts +2 -1
  110. package/src/ui/tool-renderers/index.ts +3 -3
  111. package/src/utils/incremental-reader.ts +11 -3
  112. package/src/utils/paths.ts +94 -12
  113. package/src/utils/project-markers.ts +40 -0
  114. package/src/worktree/worktree-manager.ts +206 -26
  115. package/workflows/distill.workflow.md +3 -3
  116. package/workflows/fast-fix.workflow.md +1 -1
  117. package/workflows/plan-execute.workflow.md +1 -1
  118. package/workflows/review.workflow.md +1 -1
  119. package/workflows/strict-fast-fix.workflow.md +1 -1
  120. package/docs/migration-v0.4-v0.5.md +0 -208
  121. package/docs/runtime-flow.md +0 -148
package/README.md CHANGED
@@ -1,82 +1,49 @@
1
1
  # pi-crew
2
2
 
3
- > ## ⚠️ IMPORTANT — Read before using
4
- >
5
- > **pi-crew is a sub-agent orchestration layer that was developed almost entirely
6
- > by AI, for the author's own workflow.** It is **not** a hardened, audited
7
- > product. Here's the honest framing:
8
- >
9
- > - **AI-generated code, limited human review.** The vast majority of pi-crew
10
- > was written and iterated on by autonomous AI agents. While every change
11
- > goes through static review + runtime tests, I (the author) have not
12
- > line-by-line verified everything. There will be bugs, edge cases, and
13
- > behaviors I haven't anticipated.
14
- > - **It can spawn processes, run shell commands, and write files on your
15
- > behalf.** Dynamic workflows (`.dwf.ts`) and goal loops run with the same
16
- > privileges as your Pi session — treat any `.dwf.ts` like `node script.js`
17
- > you downloaded from the internet.
18
- > - **Built for *my* needs, not yours.** This scratches a personal itch. It
19
- > likely won't fit every workflow, team setup, or risk tolerance — and
20
- > that's fine.
21
- >
22
- > **If that sounds too risky, don't use it** — no hard feelings.
23
- >
24
- > **If you still want to use it**, the safest path is to **fork it, read the
25
- > parts you'll touch, and adapt it to your own setup.** If you find a bug,
26
- > a footgun, or a sharp edge, please open an issue or send a note — your
27
- > feedback is genuinely appreciated. Thanks. ✌️
28
- >
29
- > See also: [SECURITY-ISSUES.md](docs/bugs/SECURITY-ISSUES.md),
30
- > [docs/dynamic-workflows.md](docs/dynamic-workflows.md#security-model-important)
31
- > (trust model), and the [Known limitations](#known-limitations) section below.
32
-
33
- **Coordinate AI agent teams inside [Pi](https://github.com/nicekate/pi-coding-agent).**
3
+ **Multi-agent team orchestration for [Pi](https://github.com/nicekate/pi-coding-agent).**
34
4
 
35
- 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.
5
+ pi-crew is a Pi extension that adds one `team` tool for coordinating autonomous
6
+ agent workflows — research, implementation, review, testing, and cleanup. Each
7
+ task runs as a real child Pi process, with durable on-disk state, parallel
8
+ execution, and opt-in git-worktree isolation. Runs can be monitored, steered,
9
+ resumed, scheduled, and exported.
36
10
 
37
11
  ```text
38
- npm: pi-crew
39
- repo: https://github.com/baphuongna/pi-crew
12
+ npm: pi-crew
13
+ repo: https://github.com/baphuongna/pi-crew
40
14
  ```
41
15
 
42
-
16
+ > ## ⚠️ IMPORTANT — Read before using
17
+ >
18
+ > **pi-crew was developed almost entirely by AI, for the author's own
19
+ > workflow.** It is not a hardened, audited product:
20
+ >
21
+ > - **AI-generated code, limited human review.** Every change ships after
22
+ > static review + runtime tests, but nothing is independently audited.
23
+ > - **It acts on your machine.** It spawns processes, runs shell commands, and
24
+ > writes files — including project-defined `.dwf.ts` scripts, which carry
25
+ > the same trust as any `node script.js` you downloaded.
26
+ > - **Built for one workflow** (the author's). It may not fit yours — that's
27
+ > fine.
28
+ >
29
+ > If that's too risky, don't use it — no hard feelings. If you still want it:
30
+ > **fork it, read the parts you'll touch, and adapt it to your setup.**
31
+ > Details: [trust model](docs/trust-model.md) ·
32
+ > [security issues](docs/bugs/SECURITY-ISSUES.md) ·
33
+ > [Known limitations](#known-limitations).
43
34
 
44
35
  ## Features
45
36
 
46
- - **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](#workflow-topology-advisory) below.
47
- - **One Pi tool** — `team` handles routing, planning, execution, review, and cleanup
48
- - **Autonomous delegation** — policy injection decides when/how to delegate based on task complexity
49
- - **needs_attention status** — tasks that complete without calling `submit_result` get `needs_attention` (terminal) instead of `completed`; allows retry/re-run without blocking downstream phases
50
- - **Real child Pi workers** — each task spawns a separate Pi process by default; scaffold/dry-run opt-out
51
- - **Adaptive planning** — implementation workflow lets a planner agent decide subagent fanout
52
- - **Parallel execution** — tasks in the same phase run concurrently with configurable concurrency
53
- - **Durable state** — manifest, tasks, events, artifacts all persisted to disk
54
- - **Async/background runs** — detached runs survive session switches with completion notifications
55
- - **Worktree isolation** — opt-in git worktrees per task for safe parallel edits
56
- - **Rich UI** — task list above the editor (pi-tasks style: numbered plan rows, dependency hints, `… and N more` overflow), dock at the very bottom (static icons, per-row model, footer usage), and an inline agent panel (open a worker's transcript with `↓` from the empty prompt — never a session switch). Live widget, dashboard, and progress tracking unchanged.
57
- - **Inline agent panel** (`src/ui/inline-panel/`) — status rows at the bottom, transcript in-document with pi's native components, `CustomEditor` overlay for steering (rides the existing `team steer` channel). Adapted from `pi-subtask` v0.7.4 (MIT) — attribution `NOTICE.md` §"Inline agent panel"; no code copied verbatim.
58
- - **Adaptive default team** (`workflows/default.workflow.md`) — the built-in default is now a single `assess` → adaptive-DAG step instead of a fixed `explore → plan → execute → verify` chain. The planner inspects the repo and emits a JSON plan; independent tasks run in parallel; the verifier closes the loop. Workflow files are runtime data — the change is live without a rebuild. Pin to `workflow='plan-execute'` if you need the old fixed DAG.
59
- - **Observability** — metrics registry, Prometheus/OTLP exporters, heartbeat watching, deadletter queue
60
- - **Resource management** — create/update/delete agents, teams, workflows with validation
61
- - **Import/export** — portable run bundles for sharing and archiving
62
- - **Adaptive plan fanout** — single `assess` step lets a planner pick the smallest effective crew
63
- - **Adaptive workflows** — `implementation`, `review`, `parallel-research`, `research` workflows ship in `workflows/`
64
- - **Hardened secrets** — linear-time detection covers PEM keys, Authorization headers, Bearer tokens, and `key=value` patterns
65
- - **Scheduled runs** — `schedule`/`scheduled` actions with cron, interval, and one-shot support; spawned runs tracked and auto-cancelled on job removal
66
- - **Plugin system** — framework-aware context injection (Next.js, Vite, Vitest) via plugin registry
67
- - **Health scoring** — penalty-based run health with time-series snapshots
68
- - **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`. See `docs/goals.md`.
69
- - **Dynamic workflows** (P2/P3) — author orchestration as a `.dwf.ts` script (JS loops/branch/cross-review) instead of a static step list. The script runs in the background, calls subagents via `ctx.agent()`/`ctx.fanOut()`, holds intermediate results in JS variables, and only `ctx.setResult()` reaches the main context. `ctx.phase()` marks logical phases; **round-14** adds `ctx.log()` (durable `dwf.log` events), `ctx.budget` (per-workflow token budget that auto-rejects `ctx.agent()` when exhausted), and `ctx.args<T>()` (typed workflow arguments). TypeScript IntelliSense is available via `import type { WorkflowCtx } from "pi-crew/workflow"`. `workflow-create`/`-delete`/`-save` require `confirm:true` at the tool-call layer (the only gate — a malicious agent that passes `confirm:true` programmatically bypasses it; this is postinstall-equivalent trust, not a human-in-the-loop dialog). See `docs/dynamic-workflows.md`.
70
- - **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 via `buildSkillValidationDiagnostics()`.
71
- - **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.
72
- - **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.
73
- - **Inter-pi broker** (v0.9.47, default-on) — a Unix-domain-socket message bus that lets concurrently-running Pi sessions pass messages, steering notes, and task-status events to each other. **On by default** on Linux + macOS; auto-disabled on native Windows (no unix socket). Three independent kill switches: `broker.enabled: false` (config), `PI_CREW_BROKER=0` (env, always wins), Windows auto-disable. See [docs/decisions/2026-07-22-broker-phase4-gated-on.md](docs/decisions/2026-07-22-broker-phase4-gated-on.md).
74
- - **Worker stateful scratchpad** (experimental, opt-in per role) — `executor` / `test-engineer` / `verifier` workers get a `scratchpad` tool: a persistent Bun-free JS evaluator whose namespace **compounds across calls within a task attempt** (variables set in one cell are visible in the next), so intermediate results live in memory instead of being re-derived from the transcript. Snapshots are flushed (redacted, atomic) per-attempt into the artifact store; the next attempt (retry / crash-recovery re-queue / re-run) **automatically revives the namespace** from the latest snapshot. Dormant by default (armed only when the spawner sets `PI_CREW_SCRATCHPAD=1`); zero behavior change for non-opt-in workers. Ported from the `@shift-labs/pi-rlm` pattern. See [src/runtime/scratchpad/README.md](src/runtime/scratchpad/README.md) (Phase 1-3 design, env keys, guards, threat model).
75
- - **`test:critical` + `real-test-pi-crew` skill** (v0.9.47) — a curated 14-file / 97-test subset (`npm run test:critical`, ~20s) for fast in-loop verification, plus a bundled skill distilling the full 8-tier end-to-end verification discipline (unit → 3-path kill-switch proof → typecheck/bundle → live TUI probing → smoke team run). Prevents the verifier-worker hang that full `npm test` (>4 min) caused against the 300s worker timeout.
76
- - **Provider extensions in subagents** (v0.9.57, local-path support v0.9.63) — pi-crew spawns child-pi workers with `--no-extensions` (security posture), which made extension-registered providers (e.g. `pi-commandcode-provider`, `pi-other-provider`) unresolvable inside subagents. pi-crew now **auto-discovers provider packages** from `~/.pi/agent/settings.json` `packages` — both `npm:` specs (v0.9.57) and **local-path specs** like `../../source/foo` (v0.9.63) — and loads them via `--extension` in every builtin/user subagent, so **all provider models work in subagents**. An explicit `runtime.agentExtensions: string[]` config is an optional extra allowlist on top of auto-discovery. **SEC-1 preserved:** project/project-pi agents never receive these (env-gate unchanged).
77
- - **Built-in performance observability** (v0.9.63) — every team run auto-attaches a detached resource sampler (per-PID CPU/RSS via ppid-tree attribution, 6 live warning categories) and auto-generates a markdown performance report on completion (22 anomaly categories, per-subagent timeline, token/cost/model attribution). Toggle per-team via frontmatter `observability: true|false`. Overhead ≈ 0 (sampler ~0.05% CPU / 56MB RSS; analyzer ~72ms post-run). See [Built-in performance observability](#built-in-performance-observability) below.
78
-
79
- ---
37
+ - **One `team` tool, 55 actions** — run, monitor, steer, schedule, and manage agents/teams/workflows ([actions reference](docs/actions-reference.md)).
38
+ - **Real child Pi workers** — each task spawns an isolated `pi` process; `runtime.mode: "scaffold"` gives a dry-run with prompts only.
39
+ - **Built-in teams & adaptive planning** — 6 teams and 11 workflows ship in the box; the `default` and `implementation` workflows let a planner agent pick the smallest effective crew.
40
+ - **Parallel execution + worktree isolation** — tasks in the same phase run concurrently; `workspaceMode: "worktree"` gives each task its own git worktree for safe parallel edits.
41
+ - **Durable runs** — manifest, tasks, events, and artifacts persist under `.crew/`; resume, retry, or steer in-flight tasks; export/import run bundles. `.crew/knowledge.md` injects durable project learnings into every worker prompt.
42
+ - **Async background runs** — `async: true` detaches a run so it survives session switches, with completion notification.
43
+ - **Dynamic workflows** — author orchestration as a `.dwf.ts` script with real JS loops/branching, typed `ctx`, phases, and token budgets ([docs](docs/dynamic-workflows.md)).
44
+ - **Autonomous goal loops** — `action: "goal"` runs worker → LLM judge → feedback turns until the goal is achieved or budget/turn limits hit ([docs](docs/goals.md)).
45
+ - **Inter-pi broker** — concurrent Pi sessions exchange messages and steering over a unix socket; on by default (Linux/macOS), three kill switches.
46
+ - **Observability & UI** — task list above the editor, agent dock, inline transcript panel, dashboard; per-run resource sampler + auto-generated performance report and cost breakdown.
80
47
 
81
48
  ## Install
82
49
 
@@ -84,1016 +51,174 @@ repo: https://github.com/baphuongna/pi-crew
84
51
  pi install npm:pi-crew
85
52
  ```
86
53
 
87
- Local development:
54
+ > The `npm:` prefix is required — without it, `pi install` treats the argument
55
+ > as a local path. Requires Node ≥ 22.
88
56
 
89
- ```bash
90
- pi install ./pi-crew
91
- ```
92
-
93
- Post-install config bootstrap:
57
+ Local development (from a clone):
94
58
 
95
59
  ```bash
96
- pi-crew # after npm install
97
- node ./pi-crew/install.mjs # from local clone
60
+ pi install .
98
61
  ```
99
62
 
100
- > **Split-scope install note (v0.8.11+):** pi installs extensions under
101
- > `~/.pi/agent/npm/node_modules/<ext>/`, separate from pi's own
102
- > node_modules tree (nvm / `%APPDATA%\npm` / Volta / fnm). Since v0.8.11
103
- > pi-crew resolves the `@earendil-works/pi-coding-agent` peer dep robustly
104
- > across these layouts — no symlink/NODE_PATH workaround needed. If you ever
105
- > do hit `Cannot find module '@earendil-works/pi-coding-agent'`, set
106
- > `PI_CREW_PEER_DEP_DIR=<path to the pi-coding-agent package dir>` as a
107
- > one-line workaround (or install pi-crew in pi's own scope:
108
- > `npm install -g @earendil-works/pi-crew`).
109
-
110
63
  ### Uninstall
111
64
 
112
- `pi uninstall npm:pi-crew` removes the package, but pi doesn't fire an
113
- extension uninstall hook, so several things pi-crew created are left behind.
114
- Reverse them explicitly with `team action=cleanup`. There are **two scopes**:
115
-
116
- > **v0.8.14+**: `team action=init` **no longer injects a guidance block into
117
- > AGENTS.md** (it was redundant — the `team` tool self-describes via its tool
118
- > registration, so the agent learns pi-crew's commands from there, not AGENTS.md).
119
- > The cleanup steps below still work for removing blocks injected by **older
120
- > versions** (<0.8.14).
121
-
122
- #### Project scope (reverse `team action=init`)
123
-
124
- ```bash
125
- # 1. (Optional) Preview what would be removed, without writing:
126
- team action=cleanup dryRun=true
127
-
128
- # 2. Remove the AGENTS.md guidance block only (.crew/ preserved):
129
- team action=cleanup
130
-
131
- # 3. Remove BOTH the guidance block AND the .crew/ state directory (force):
132
- team action=cleanup force=true
133
- ```
134
-
135
- The guidance block is wrapped in `<!-- PI-CREW:GUIDANCE:START -->` /
136
- `<!-- PI-CREW:GUIDANCE:END -->` markers, so cleanup removes **only** that
137
- block — your own AGENTS.md content is never touched. The `.crew/` directory
138
- is removed **only** with `force=true` (it's irreversible).
139
-
140
- #### User scope (remove user-level state `pi uninstall` leaves behind)
141
-
142
- ```bash
143
- # 4. Preview + remove pi-crew user-scope junk:
144
- team action=cleanup scope=user dryRun=true # preview
145
- team action=cleanup scope=user # remove ~/.pi/agent/extensions/pi-crew/
146
- # + pi-crew smoke-test *.bak files
147
-
148
- # 5. (Optional) Also remove the global config (holds your settings):
149
- team action=cleanup scope=user force=true # also removes ~/.pi/agent/pi-crew.json
150
- ```
151
-
152
- This removes the pi-crew state dir (`~/.pi/agent/extensions/pi-crew/`, which
153
- holds run artifacts + state), the global config (with `force=true`), and the
154
- `*.md.bak-<timestamp>` smoke-test backup files pi-crew's own tests may leave in
155
- `~/.pi/agent/agents/`. **Your authored agent files (`*.md`) are never touched**
156
- — pi-crew can't tell which were user-created vs test-copied, so only the
157
- clearly-pi-crew `.bak-*` backups are removed.
158
-
159
- #### Final step
65
+ `pi uninstall npm:pi-crew` removes the package, but pi has no uninstall hook —
66
+ pi-crew-created state is left behind. Reverse it explicitly:
160
67
 
161
68
  ```bash
162
- # 6. Remove the package itself:
163
- pi uninstall npm:pi-crew
69
+ team action=cleanup dryRun=true # preview, no writes
70
+ team action=cleanup force=true # remove project guidance block + .crew/
71
+ team action=cleanup scope=user force=true # + user-level state and global config
72
+ pi uninstall npm:pi-crew # finally, the package itself
164
73
  ```
165
74
 
166
-
167
- ---
168
-
169
- ## Quick Start
170
-
171
- ### 1. Initialize project
75
+ ## Quick start
172
76
 
173
77
  ```text
174
78
  /team-init
175
- ```
176
-
177
- ### 2. Run a team
178
-
179
- ```text
180
79
  /team-run Investigate failing tests and propose a fix
181
80
  ```
182
81
 
183
- Or via tool call:
184
-
185
- ```json
186
- {
187
- "action": "run",
188
- "team": "default",
189
- "goal": "Investigate failing tests and propose a fix"
190
- }
191
- ```
192
-
193
- ### 3. Check status
194
-
195
- ```text
196
- /team-status <runId>
197
- /team-dashboard
198
- ```
199
-
200
- ### 4. Get a recommendation
201
-
202
- When unsure which team/workflow fits:
82
+ Or via tool calls (all examples verified against the action schema):
203
83
 
204
84
  ```json
205
- {
206
- "action": "recommend",
207
- "goal": "Refactor auth flow and add tests"
208
- }
209
- ```
210
-
211
- ---
212
-
213
- ## Builtin Teams
214
-
215
- | Team | Workflow | Purpose |
216
- |------|----------|----------|
217
- | `default` | adaptive: planner derives concrete tasks from the goal, parallel phases, verify | Balanced, general-purpose |
218
- | `fast-fix` | explore → execute → verify | Quick bug fixes |
219
- | `implementation` | Adaptive planner decides fanout | Multi-file implementation |
220
- | `review` | explore → code-review → security-review → verify | Code review + security audit |
221
- | `research` | explore → analyze → write | Research and documentation |
222
- | `parallel-research` | Parallel shards → synthesize → write | Multi-source research |
223
-
224
- ---
225
-
226
- ## Workflow topology advisory
227
-
228
- 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.
229
-
230
- ### How it works
231
-
232
- ```text
233
- team action='run', workflow='fast-fix', goal='...'
234
- ↓
235
- pi-crew analyzes topology: 3-step sequential
236
- ↓
237
- ⚠️ [team-tool.preflight] WARN: 3-step sequential chain: measured 5.7× slower
238
- and 1.9× costlier than 3 raw Agent calls (Run #3 in .crew/state/runs/).
239
- Proceeding anyway.
240
- ↓
241
- Workflow runs to completion. Agent sees the note, decides for next time.
242
- ```
243
-
244
- ### Topology → advisory level
245
-
246
- | Topology | When | Level | What pi-crew prints |
247
- |---|---|---|---|
248
- | `single` | 1 step, no concurrency | `warn` | "raw Agent tool would be ~30× faster and ~5× cheaper. Proceeding anyway." |
249
- | `sequential` (2-3 steps) | Linear chain, no fan-out | `warn` | "measured 5.7× slower than raw Agent calls. Proceeding anyway." |
250
- | `sequential` (4+ steps) | Linear chain, longer | `warn` | "audit trail may justify pi-crew overhead. Proceeding anyway." |
251
- | `concurrent` | ≥3 truly parallel agents (parallelGroup) | `note` | "✅ Validated use case: N-way parallel fan-out. pi-crew's parallelism wins." |
252
- | `complex-dag` | 4+ steps with data dependencies | `note` | "✅ Validated use case: complex DAG with adaptive plan." |
253
- | `dynamic` | `.dwf.ts` script | `info` | "Runtime decides topology." |
254
-
255
- ### When to prefer raw `Agent` over `team`
256
-
257
- Use the raw `Agent` tool when:
258
- - You have a single task or quick question (1-step)
259
- - You have 2–3 sequential independent steps (no DAG branching, no concurrency)
260
-
261
- Use `team` when:
262
- - You have ≥3 agents running TRULY CONCURRENTLY (`parallelGroup`)
263
- - You have a COMPLEX DAG (4+ steps with data dependencies, branching)
264
- - You need an audit trail, team coordination, or worktree isolation that justifies pi-crew's overhead
265
-
266
- ### How agents learn the rule
267
-
268
- The guidance is available in three places agents see:
269
-
270
- 1. **`team` tool description** — the LLM reads this when considering whether to call the tool. Includes an explicit "ℹ️ ADVISORY NOTE (preflight, never blocks)" section.
271
- 2. **`team` prompt snippet** — rendered in agent context when the tool is relevant. Single-line summary of the rule.
272
- 3. **`.crew/knowledge.md` CONVENTIONS section** — always injected into every worker session's context. Contains the full 4-question self-check.
273
-
274
- ### How to silence the advisory
275
-
276
- The advisory is **informational only** — there is no `force:true` flag needed (the run proceeds regardless).
277
-
278
- ### Implementation
279
-
280
- - `src/workflows/topology-analyzer.ts` — pure classifier (parses workflow YAML, builds DAG, detects parallelGroups)
281
- - `src/workflows/preflight-validator.ts` — returns `{level: info|note|warn, message, suggestion}` (never throws)
282
- - Integration: `src/extension/team-tool/run.ts` (extension layer, prints advisory) + `src/runtime/team-runner.ts` (defense-in-depth, also logs)
283
-
284
- ### Tests
285
-
286
- - `test/unit/topology-analyzer.test.ts` — 13 cases (each topology + edge cases)
287
- - `test/unit/preflight-validator.test.ts` — 11 cases (each level + advisory contract)
288
-
289
-
290
- - `test/functional/pi-crew-live.test.ts` + `test/functional/pi-crew-live-broad.test.ts` — 16 live integration tests run against the **real pi binary + real LLM provider** (verified after v0.9.42 audit, ~26 commits). Use these when you want to confirm end-to-end behavior, not just unit-level invariants.
291
-
292
- ## Recent changes
293
-
294
- ### v0.10.2: UI rewrite + adaptive default team (2026-08-24)
295
-
296
- 40 commits after `v0.10.1` (≈3,500 LOC, 54 files). Headline: the UI surface
297
- goes from "two modal overlays + status widget" to a proper in-document
298
- panel — task list above the editor, dock at the very bottom, and an inline
299
- agent transcript that opens with `↓` from the empty prompt. The default
300
- team also moves from a fixed 4-step chain to a single adaptive `assess` →
301
- parallel-execute → verify DAG.
302
-
303
- - **Task list above the editor** — pi-tasks style numbered plan rows
304
- (`#1`, `#2`, …) instead of `01_explore` ids; completed rows dim and
305
- strike through; running row shows spinner + elapsed time + token
306
- counts; queued rows name dependencies (`› blocked by #2`). Header
307
- is Claude-Code style (`● 4 tasks (1 done, 1 in progress, 2 open)`).
308
- Role/agent/model identity moved to the dock — the list is the *plan*,
309
- not a worker report. 10-row cap with `… and N more` overflow.
310
- - **Inline agent panel** (`src/ui/inline-panel/`, ~1,761 LOC, 10 files) —
311
- `↓` from the empty prompt opens the dock; Enter drops into the worker's
312
- full transcript rendered in-document with pi's native components;
313
- steering rides the existing `team steer` channel (no stdin pipe).
314
- Worker view is a *byte-copy* of the worker's own session log, polled
315
- for live refresh, and Enter on the dock row always opens a real Pi
316
- session (the worker-143 kill on switches and the `AbortError`
317
- post-exit crash are both fixed). Full-screen overlay preserved for
318
- end-of-run review.
319
- - **Dock survives until the run is done** — rows no longer disappear at
320
- "completed"; 3-row scroll window keeps the in-progress task visible;
321
- per-row model display.
322
- - **Adaptive default team** (`workflows/default.workflow.md`, runtime
323
- data — no rebuild needed) — old fixed `explore → plan → execute →
324
- verify` replaced by a single `assess` step (planner role) that emits
325
- an `ADAPTIVE_PLAN_JSON` block. Independent tasks go into the SAME
326
- phase so they run in parallel; verifier still closes the loop.
327
- **Pin to `workflow='plan-execute'` if you need the old fixed DAG.**
328
- - **Model-routing passthrough muted** + Biome 2.5.3 lint/format sync.
329
- - Real-test re-run on the released v0.10.1 bundle: test:critical 102/102,
330
- typecheck clean, 9a 10/10, 9b 5/5, chain 306.8s observation.
331
- See `CHANGELOG.md` §Unreleased for full notes and `NOTICE.md` for
332
- pi-subtask / pi-tasks attributions.
333
-
334
- ### v0.9.65: team-tool schema empty-string guard + effectiveness empty-result guard (2026-08-10)
335
-
336
- - **`budgetTotal` empty-string unset marker accepted**: `budgetTotal` was the only numeric `TeamToolParams` field missing the `Literal("")` union branch its siblings had. Calling models that emit every schema key with defaults were rejected by pi-ai's pre-handler validation → `Validation failed for tool "team"` on every action. The `MISCONFIGURATION GUARD` (rejects 1-999) is preserved. Caught by the Tier 9 feature battery — Tiers 1-8 stayed green while the team tool was broken for emitting models.
337
- - **Effectiveness empty-result guard**: a completed task with an empty result artifact (`sizeBytes === 0`) is now treated as no-observed-work — closing the monitoring gap where a 429-absorbed / model-not-found worker produced zero real content but the run still completed with `consistency=1`. Empty-result tasks flow through the existing `noObservedWork` escalation. Regression tests: `test/unit/runtime/core/effectiveness-guard.test.ts` (8 tests).
338
- - Full 9-tier real-test re-run (2026-08-10): Tiers 1-8 + 9a (10/10) + 9b (5/5) pass; previous failure modes did not reproduce. See [CHANGELOG.md](CHANGELOG.md) §0.9.65 and `docs/real-test/reports/real-test-2026-08-10-full-9-tier-f4-effectiveness-guard.md`.
339
-
340
- ### v0.9.63: built-in performance observability + local-path provider-extension discovery
341
-
342
- - **Built-in performance observability (always-on, toggle per team)**: every team run now auto-attaches a detached resource sampler (`scripts/resource-sampler.mjs` — per-PID CPU/RSS via ppid-tree attribution, 6 live warning categories: high_cpu / rss_jump / rss_high / rss_leak / proc_died / proc_zombie) and auto-generates a markdown performance report (`scripts/analyze-run.mjs` → `docs/perf-report-<runId>.md` — 22 anomaly categories, per-subagent launch/respawn/active/drain timeline, token/cost/model attribution). Runtime wiring in `src/runtime/team-runner.ts`: `startPerfSampler` (detached + `unref`'d; death never affects the run) + `schedulePerfAnalyze` (+3s after `after_run_complete`, `unref`'d `setTimeout`). Toggle: team frontmatter `observability: true|false` (default `true`). **Overhead ≈ 0** (A/B verified: sampler ~0.05% CPU / 56MB RSS, analyzer ~72ms post-run, ~32KB artifacts/run). New scripts: `scripts/resource-sampler.mjs`, `scripts/analyze-run.mjs`. Tests: `test/unit/scripts/{analyze-run,resource-sampler}-audit.test.ts`.
343
- - **Local-path provider extensions now discovered for child workers**: `discoverProviderExtensions` previously resolved only `npm:` specs from `~/.pi/agent/settings.json` `packages`, skipping local-path specs on the assumption they were the pi-crew extension itself. That broke local provider extensions (e.g. `pi-other-provider` installed via `pi install <local-path>`) — every model from such a provider hit `Error: Model "…" not found` in child workers and burned ~10s/task of fallback churn. Fix: resolve `./`, `../`, and absolute specs relative to the settings.json dir (same sanctioned trust level as `npm:`), and skip pi-crew itself via `packageRoot()`. **SEC-1 preserved** (project/project-pi AGENT extensions stay gated). Tests in `test/unit/runtime/model/provider-extensions.test.ts`.
344
- - See [CHANGELOG.md](CHANGELOG.md) §0.9.63 and `docs/real-test/reports/real-test-2026-08-08-provider-ext-local-path.md`.
345
-
346
- ### v0.9.57: team-tool schema repair + provider-extension auto-discovery + post-reorg repo-layout consolidation
347
-
348
- - **Team tool repaired (was broken live while tests stayed green)**: calling models emit empty-string/boolean defaults for every schema key, which pi-ai's pre-handler `validateToolArguments` rejected (`Validation failed for tool team`) and `Type.Unsafe` schema fields without `[TypeBox.Kind]` made `Value.Check` throw (`Unknown type`). Schema now accepts unset markers natively; `SkillOverride`/`FreeformConfig` switched to TypeBox-native constructors; `normalizeTeamParams` drops empties in the handler. Chain-runner also fixed (quote-aware step splitting). Caught by a new **Tier 9 feature battery** in the [`real-test-pi-crew`](skills/real-test-pi-crew/SKILL.md) skill (live team-tool action coverage).
349
- - **Source reorg finalised (~90 commits)**: `src/` is now cluster-organised — `src/runtime/` (15 subdirs + ~77 flat files) and `src/state/` (3 subdirs + 12 root files), with the other top-level dirs (`extension/`, `ui/`, `config/`, `utils/`, `agents/`, …) cluster-honed too. See [Repository layout](#repository-layout) and the cluster maps [`src/runtime/README.md`](src/runtime/README.md) / [`src/state/README.md`](src/state/README.md).
350
- - **Tests mirrored into subdirs**: 566 flat `.test.ts` files now live in 35 leaf subdirectories mirroring `src/` (`test/unit/runtime/`, `test/unit/state/`, `test/unit/extension/`, …). 151 cross-cutting tests (`round*`, `v0*`, `package-*`, errors, i18n, bundle-*) stay at `test/unit/` root by design. See [`test/unit/README.md`](test/unit/README.md).
351
- - **Recursive-glob test-runner fix**: `scripts/test-runner.mjs` now expands `**` globs itself — Node v22's `--test` only expands single-level `*`, so subdir tests (e.g. `test/unit/security/`) were **invisible** to `npm test` before.
352
- - **Docs consolidated**: 47 flat docs at `docs/` root → 20 living docs kept at root, 27 historical moved to `docs/archive/` (flat); 11 stray root `.md` files moved to `docs/archive/` + `docs/bugs/`. New [`docs/README.md`](docs/README.md) indexes the living docs + subdirs.
353
- - **Provider extensions in subagents** (see [Features](#features)): auto-discovery of provider packages from `~/.pi/agent/settings.json` `packages` (npm: specs) + explicit `runtime.agentExtensions` allowlist. Implementation: `src/runtime/model/provider-extensions.ts` + merge in `src/agents/discover-agents.ts`. SEC-1 preserved (project/project-pi agents never receive these).
354
- - See [CHANGELOG.md](CHANGELOG.md) for the full reorg + feature log.
355
-
356
- ### v0.9.47 (2026-07-22): Inter-pi broker Phase 4 (default-on) + verifier-hang fix + verification skill
357
-
358
- - **Broker default-on**: `broker.enabled` flipped `false` → `true` on Linux + macOS. The inter-pi broker lets concurrent Pi sessions exchange messages, steering notes, and task-status events over a Unix-domain socket. Three kill switches remain: config `broker.enabled: false`, env `PI_CREW_BROKER=0` (always wins), Windows auto-disable.
359
- - **Verifier-hang fix**: `npm run test:critical` — a curated 14-file / 97-test subset (~20s) replaces full `npm test` (>4 min) in verifier prompts. The full suite was exceeding the 300s `RESPONSE_TIMEOUT_MS`, killing workers with exit 143. Both plan-templates and all 4 workflow verifier prompts now specify the fast command.
360
- - **`real-test-pi-crew` skill** (659 lines): distills the 8-tier verification discipline used to ship this release (critical tests → 3-path kill-switch proof → typecheck/bundle → bundle md5 sync → live TUI probing via tmux/pty → smoke team run). Bundled `scripts/pty_probe.py`.
361
- - **Postinstall skill-collision fix**: v0.9.47's `copySkills()` (which mirrored skills to `~/.pi/agent/skills/`) caused 31 "collision" warnings — Pi already discovers skills natively from the npm package. v0.9.48 removes `copySkills()` and adds a safe byte-identical cleanup (`cleanupStaleSkillCopies()`) that clears the stale copies on upgrade. User-customized skills are preserved.
362
- - See [CHANGELOG.md](CHANGELOG.md) §0.9.47 and [docs/decisions/2026-07-22-broker-phase4-gated-on.md](docs/decisions/2026-07-22-broker-phase4-gated-on.md).
363
-
364
- ### v0.9.45 – v0.9.46 (2026-07-20): security + perf remediation, UI stability
365
-
366
- - **Custom agent roles default to read-only (FIND-12, breaking):**
367
- `permissionForRole()` returns `"read_only"` for unknown roles (was
368
- permissive `"workspace_write"`). Write-capable roles are now an explicit
369
- allowlist (`WRITE_ROLES`). See `CHANGELOG.md` for the migration.
370
- - **Mailbox / snapshot-cache / scan perf:** delivery cache + async append
371
- (FIND-01/02), `listActive` TTL + mtime-sort strict limit (FIND-03/04),
372
- byte-bounded event-log tail-read (FIND-05).
373
- - **Heartbeat race (FIND-06):** in-flight guard + drain + terminal-safety +
374
- late-save repair in the coalesced task group.
375
- - **UI flicker eliminated:** the render path no longer hard-deletes snapshot
376
- entries, so the crew widget / powerbar / live sidebar stay stable (no more
377
- "(loading…)" flashing every ~160ms).
378
- - **Emoji width-overflow crash fixed for good:** `visibleWidth` delegates to
379
- pi-tui's own measure, so agent-output emoji can never exceed terminal width.
380
- - **Background-subagent notifications coalesce:** N near-simultaneous
381
- completions now produce ONE consolidated wake-up instead of N drips.
382
-
383
- ### v0.9.42 – v0.9.44: 4-wave audit + flaky-CI fixes
384
-
385
- A 4-wave audit + fix pass was completed (see `docs/archive/UPGRADE_REVIEW.md` for the full 647-line report and `CHANGELOG.md` for the diff):
386
-
387
- - **−481 KB** bundle size (externalized `acorn` + fixed `@sinclair/typebox` name).
388
- - **−31.1%** in `child-pi.ts` (1842 → 1270 lines via 6 decomposition steps).
389
- - **~30 bug fixes** across security, correctness, budget enforcement, worker cap, observability, and worktree isolation.
390
- - **Lock re-entrance guard** via `AsyncLocalStorage` (H-1) — fixes a root-cause mutual-exclusion violation.
391
- - **Task-level metrics now functional** (OBS-NEW-1/2) — `crew.task.{count,duration_ms,tokens_total}` were always zero; now emit on every run completion.
392
- - **Live-test-only bugs found** (mock tests had passed): token usage not captured (nested `obj.message.usage`), child-pi spawning wrong binary (`argv1` trust heuristic), worktree mode blocked by own `.gitignore`.
393
-
394
- ## Builtin Agents
395
-
396
- ```
397
- analyst · critic · executor · explorer · planner · reviewer
398
- security-reviewer · test-engineer · verifier · writer
399
- ```
400
-
401
- ---
402
-
403
- ## Runtime Modes
404
-
405
- pi-crew supports multiple runtime modes for task execution:
406
-
407
- | Mode | Description |
408
- |------|-------------|
409
- | `auto` (default) | Uses `child-process` unless overridden by config |
410
- | `child-process` | Spawns real `pi` child processes — each task runs in isolation |
411
- | `scaffold` | Dry-run mode — renders prompts and persists artifacts without executing |
412
- | `live-session` (experimental) | In-process session execution within the parent Pi |
413
-
414
- ```json
415
- // Use scaffold mode (no real workers, just prompts)
416
- { "action": "run", "team": "default", "goal": "...", "runtime": { "mode": "scaffold" } }
417
-
418
- // Disable workers globally
419
- { "executeWorkers": false }
420
- ```
421
-
422
- ## Built-in performance observability
423
-
424
- Every team run auto-attaches a **detached resource sampler** and auto-generates a **performance report** on completion — measuring real resource usage and surfacing anomalies from the run's actual events/transcripts, not a synthetic benchmark.
425
-
426
- ### Artifacts produced (per run, under `.crew/artifacts/<runId>/`)
427
-
428
- | File | Contents |
429
- |------|----------|
430
- | `resources.jsonl` | Per-PID CPU/RSS samples every 2s (root runner + all child workers via ppid-tree attribution, including respawns). PID-reuse guarded by `/proc` starttime; first-sample CPU excluded from averages. |
431
- | `perf-obs.log` | Sampler diagnostics: spawn marker, live warnings, terminal-stop confirmation. |
432
- | `docs/perf-report-<runId>.md` | Markdown report: 22 anomaly categories, per-subagent timeline (launch/respawn/startup/active-work/drain/finalize), token/cost/model attribution. |
433
-
434
- ### Live warnings (written to `perf-obs.log` during the run)
435
-
436
- `high_cpu` (≥300% one core) · `rss_jump` (+200MB/interval) · `rss_high` (≥1GB) · `rss_leak` (window-30 monotonic +100MB) · `proc_died` · `proc_zombie`. Rate-limited (10s/pid/category).
437
-
438
- ### Toggle
439
-
440
- ```yaml
441
- # teams/my-team.team.md
442
- ---
443
- name: my-team
444
- observability: false # default: true — set false to skip sampler + report
445
- ---
446
- ```
447
-
448
- `observability: true` is the default for parsed team files; direct-object `TeamConfig` fixtures (unit tests) stay unset so they never spawn the sampler. `schedulePerfAnalyze` runs the analyzer `+3s` after `after_run_complete` via an `unref`'d `setTimeout` — it never blocks run completion. The sampler auto-stops when the run manifest reaches a terminal status.
449
-
450
- ### Overhead
451
-
452
- Measured A/B (same team/goal, observability on vs off): **no detectable wall-time difference** (delta inside the 429-storm noise). Sampler: ~0.05% of one core, 56MB RSS fixed, detached + `unref`'d. Analyzer: ~72ms one-shot after run. ~32KB artifacts/run. See `docs/real-test/reports/real-test-2026-08-07-perf-obs-overhead.md`.
453
-
454
- ## Async Runs
455
-
456
- Async runs are **detached** from the session — they survive session switches and reloads. Pi-crew notifies when complete.
457
-
458
- ```json
459
- { "action": "run", "team": "default", "goal": "...", "async": true }
460
- ```
461
-
462
- ```text
463
- /team-run --async Investigate failing tests
85
+ { "action": "run", "team": "default", "goal": "Investigate failing tests and propose a fix" }
86
+ { "action": "status", "runId": "team_..." }
87
+ { "action": "recommend", "goal": "Refactor auth flow and add tests" }
88
+ { "action": "run", "team": "implementation", "goal": "Refactor auth", "async": true, "workspaceMode": "worktree" }
464
89
  ```
465
90
 
466
- Background runs use `node --import jiti-register.mjs` for TypeScript support. See [docs/runtime-flow.md](docs/runtime-flow.md) for details.
467
-
468
- ## Worktree Isolation
91
+ `action: "recommend"` picks a team/workflow when you're unsure which fits.
92
+ Slash commands (`/team-status`, `/team-dashboard`, `/team-config`, …) cover ops
93
+ and debugging — [full list](docs/commands-reference.md).
469
94
 
470
- Worktree mode creates an **isolated git worktree per task** — safe for parallel edits to the same branch.
95
+ ## Built-in teams
471
96
 
472
- ```json
473
- {
474
- "action": "run",
475
- "team": "implementation",
476
- "goal": "Refactor auth",
477
- "workspaceMode": "worktree"
478
- }
479
- ```
480
-
481
- ```text
482
- /team-run --worktree Refactor auth
483
- ```
97
+ | Team | Workflow shape | Use for |
98
+ |------|----------------|---------|
99
+ | `default` | adaptive: assess → parallel tasks → verify | general-purpose work |
100
+ | `fast-fix` | explore → execute → verify | small bug fixes |
101
+ | `implementation` | adaptive planner decides fanout | multi-file features/refactors |
102
+ | `review` | explore → code-review → security-review → verify | code + security review |
103
+ | `research` | explore → analyze → write | investigation and documentation |
104
+ | `parallel-research` | parallel shards → synthesize → write | multi-source audits |
484
105
 
485
- Requirements:
486
- - Git repository (cwd must be inside a git repo)
487
- - Clean working tree (no uncommitted changes in the leader worktree)
488
- - Can be disabled via config: `requireCleanWorktreeLeader: false`
489
- - Worktrees auto-cleanup on run completion/cancel
490
-
491
- If preconditions are not met, a friendly error message is returned instead of crashing.
492
-
493
- ---
106
+ 18 built-in agents ship in [`agents/`](agents/) (explorer, planner, executor,
107
+ critic, reviewer, verifier, test-engineer, writer, analyst, oracle, librarian,
108
+ …). Resources are discovered in three layers — builtin package < user
109
+ (`~/.pi/agent/`) < project (`.crew/`) — and project resources cannot shadow
110
+ builtin ones. Formats: [docs/resource-formats.md](docs/resource-formats.md).
494
111
 
495
112
  ## Configuration
496
113
 
497
- ### Config Paths
114
+ Config files (first found wins per scope):
498
115
 
499
116
  | Scope | Path |
500
117
  |-------|------|
501
- | User (primary) | `~/.pi/agent/pi-crew.json` |
502
- | User (legacy, still read for migration) | `~/.pi/agent/extensions/pi-crew/config.json` |
503
- | Project (crewRoot) | `.crew/config.json` (or `.pi/teams/config.json` legacy) |
504
- | Project (alt) | `.pi/pi-crew.json` |
505
-
506
- ### Quick Config
507
-
508
- ```text
509
- /team-config # view all settings
510
- /team-config runtime.mode=scaffold # set a key (--project for project scope)
511
- /team-config --unset=runtime.mode # reset a key to default
512
- /team-config --project runtime.mode # project-scoped view
513
- /team-settings path # show config file path
514
- ```
515
-
516
- ### Key Settings
517
-
518
- A comprehensive reference of every config key. 🔒 marks keys that are
519
- **sensitive** — project config (`.crew/config.json`) cannot set them; they are
520
- silently ignored with a warning unless set in **user config**
521
- (`~/.pi/agent/pi-crew.json`). Cross-referenced against `src/config/types.ts`
522
- (`PiTeamsConfig`), `src/config/defaults.ts`, and the project-override sanitizer
523
- in `src/config/config.ts`.
524
-
525
- For machine-readable validation, see [schema.json](schema.json).
526
-
527
- #### Top-level
528
-
529
- | Key path | Type | Default | Description |
530
- |----------|------|---------|-------------|
531
- | `asyncByDefault` 🔒 | `boolean` | `false` | Detach every `run` by default (survives session switches). |
532
- | `executeWorkers` 🔒 | `boolean` | `true` | Spawn worker agents. `false` = dry-run planning only. |
533
- | `notifierIntervalMs` | `number` | `5000` | How often the completion notifier polls. |
534
- | `requireCleanWorktreeLeader` 🔒 | `boolean` | _(unset)_ | Require a clean git repo before starting a worktree-mode run. |
535
- | `ignoreMethod` | `"gitignore" \| "exclude"` | _(unset)_ | How run artifacts are ignored by git. |
536
-
537
- #### `autonomous.*` — Delegation & magic keywords
538
-
539
- | Key path | Type | Default | Description |
540
- |----------|------|---------|-------------|
541
- | `autonomous.profile` 🔒 | `manual \| suggested \| assisted \| aggressive` | `suggested` | How much the agent self-delegates to crew runs. |
542
- | `autonomous.enabled` 🔒 | `boolean` | `true` | Master switch for autonomous delegation. |
543
- | `autonomous.injectPolicy` 🔒 | `boolean` | `true` | Inject the delegation policy into prompts. |
544
- | `autonomous.preferAsyncForLongTasks` 🔒 | `boolean` | `false` | Auto-detach runs expected to be long. |
545
- | `autonomous.allowWorktreeSuggestion` 🔒 | `boolean` | `true` | Suggest worktree isolation for mutating goals. |
546
- | `autonomous.magicKeywords` | `Record<string, string[]>` | _(unset)_ | Trigger words mapped to team/workflow hints. |
547
-
548
- #### `limits.*` — Scheduling ceilings
549
-
550
- | Key path | Type | Default | Description |
551
- |----------|------|---------|-------------|
552
- | `limits.maxConcurrentWorkers` | `number` | workflow-dependent¹ | Hard cap on parallel workers. Ceiling 1024. |
553
- | `limits.allowUnboundedConcurrency` | `boolean` | `false` | Permit unbounded fan-out (dangerous). |
554
- | `limits.maxTaskDepth` | `number` | `100` | Max nesting depth of the task graph. |
555
- | `limits.maxChildrenPerTask` | `number` | `1000` | Max children a single task may spawn. |
556
- | `limits.maxRunMinutes` | `number` | `1440` | Wall-clock cap for a run (24 h). |
557
- | `limits.maxRetriesPerTask` | `number` | `100` | Max automatic retries per task. |
558
- | `limits.maxTasksPerRun` | `number` | `10000` | Max tasks allowed in a single run. |
559
- | `limits.heartbeatStaleMs` | `number` | `86400000` | Heartbeat staleness threshold (24 h). |
560
- | `limits.serializeOnPathOverlap` | `boolean` | `false` | Skip ready tasks whose `step.output` overlaps an in-flight task. |
561
-
562
- ¹ Per workflow: `parallelResearch` 4, `research` 3, `implementation` 4, `review` 3, `default` 3 (fallback 2).
563
-
564
- #### `runtime.*` — Worker execution
565
-
566
- | Key path | Type | Default | Description |
567
- |----------|------|---------|-------------|
568
- | `runtime.mode` 🔒 | `auto \| scaffold \| child-process \| live-session` | `auto` | How workers are spawned. |
569
- | `runtime.preferLiveSession` 🔒 | `boolean` | _(unset)_ | Prefer in-process live-session workers. |
570
- | `runtime.allowChildProcessFallback` 🔒 | `boolean` | _(unset)_ | Fall back to child-process if live-session unavailable. |
571
- | `runtime.maxTurns` | `number` | `10000` | Max agent turns per task. |
572
- | `runtime.graceTurns` | `number` | `5` | Extra turns allowed after a stop signal. |
573
- | `runtime.taskTimeoutMs` | `number` | `0` | Per-task wall-clock timeout (0 = none). |
574
- | `runtime.inheritContext` 🔒 | `boolean` | `true` | Inherit parent context into workers. |
575
- | `runtime.promptMode` | `replace \| append` | `replace` | How the task prompt is applied. |
576
- | `runtime.groupJoin` | `off \| group \| smart` | `smart` | How grouped task results are joined. |
577
- | `runtime.groupJoinAckTimeoutMs` | `number` | `86400000` | Timeout for group-join acknowledgements. |
578
- | `runtime.requirePlanApproval` 🔒² | `boolean` | `false` | Pause for plan approval before mutating tasks. |
579
- | `runtime.completionMutationGuard` | `off \| warn \| fail` | `warn` | Guard against tasks mutating outside plan approval. |
580
- | `runtime.effectivenessGuard` | `off \| warn \| block \| fail` | `off` | Pre-flight topology validator enforcement mode. |
581
- | `runtime.isolationPolicy` 🔒 | `{ isolatedRoles?, defaultRuntime? }` | _(unset)_ | Per-role runtime selection for crash isolation. |
582
- | `runtime.excludeContextBash` | `boolean` | `false` | Exclude certain bash results from worker context. |
583
- | `runtime.agentExtensions` | `string[]` | _(unset)_ | Extra extension paths (file paths or npm entry points) loaded in **every** child-pi worker on top of auto-discovered provider packages (see [Features](#features)). Optional allowlist — auto-discovery already loads provider packages from `~/.pi/agent/settings.json` `packages`. Project/project-pi agents never receive these (SEC-1). |
584
-
585
- ² `requirePlanApproval` is sensitive only when set to `false` in project config
586
- (the sanitizer blocks *disabling* the gate from untrusted project config).
587
-
588
- #### `control.*` — Needs-attention gating
589
-
590
- | Key path | Type | Default | Description |
591
- |----------|------|---------|-------------|
592
- | `control.enabled` | `boolean` | _(unset)_ | Enable the needs-attention controller. |
593
- | `control.needsAttentionAfterMs` | `number` | _(unset)_ | Threshold before flagging a run as needing attention. |
594
-
595
- #### `worktree.*` — Git worktree isolation
596
-
597
- > Worktree **mode** is chosen at run time via `workspaceMode: "worktree"`, not
598
- > in config. These keys configure how a worktree is set up.
599
-
600
- | Key path | Type | Default | Description |
601
- |----------|------|---------|-------------|
602
- | `worktree.setupHook` 🔒 | `string` | _(unset)_ | Shell command run after worktree creation. |
603
- | `worktree.setupHookTimeoutMs` | `number` | _(unset)_ | Timeout for the setup hook. |
604
- | `worktree.linkNodeModules` | `boolean` | `false` | Symlink `node_modules` into the worktree. |
605
- | `worktree.seedPaths` | `string[]` | _(unset)_ | Extra paths to copy/symlink into the worktree. |
606
-
607
- #### `goalWrap.*` — Goal-completion workflows
608
-
609
- A per-workflow map (`Record<workflowName, GoalWrapWorkflowConfig>`) that applies
610
- the `goal` action's completion-guarantee loop to builtin workflows.
611
-
612
- | Key path | Type | Default | Description |
613
- |----------|------|---------|-------------|
614
- | `goalWrap.<name>.enabled` | `boolean` | _(unset)_ | Enable goal-wrap for this workflow. |
615
- | `goalWrap.<name>.maxTurns` | `number` (1–50) | _(unset)_ | Max iterations of the goal loop. |
616
- | `goalWrap.<name>.evaluatorModel` | `string` | _(unset)_ | Model used by the LLM judge. |
617
- | `goalWrap.<name>.verification.commands` | `string[]` | _(unset)_ | Commands run to verify completion. |
618
- | `goalWrap.<name>.budgetTotal` | `number` | _(unset)_ | Token budget for the goal loop. |
619
- | `goalWrap.<name>.budgetUnlimited` | `boolean` | _(unset)_ | Skip the token budget. |
620
-
621
- #### `agents.*` — Agent overrides
622
-
623
- | Key path | Type | Default | Description |
624
- |----------|------|---------|-------------|
625
- | `agents.disableBuiltins` 🔒 | `boolean` | `false` | Hide built-in agents. |
626
- | `agents.overrides` 🔒 | `Record<name, AgentOverride>` | _(unset)_ | Per-agent `model`, `fallbackModels`, `thinking`, `tools`, `skills`, `disabled`. |
627
-
628
- #### `tools.*` — Tool behaviour
629
-
630
- | Key path | Type | Default | Description |
631
- |----------|------|---------|-------------|
632
- | `tools.enableClaudeStyleAliases` | `boolean` | _(unset)_ | Accept Claude-style tool aliases. |
633
- | `tools.enableSteer` 🔒 | `boolean` | _(unset)_ | Enable the `steer` action. |
634
- | `tools.terminateOnForeground` 🔒 | `boolean` | _(unset)_ | Terminate background runs when foreground starts. |
635
-
636
- #### `telemetry.*`
637
-
638
- | Key path | Type | Default | Description |
639
- |----------|------|---------|-------------|
640
- | `telemetry.enabled` | `boolean` | `false` | Collect anonymous usage telemetry. |
641
-
642
- #### `policy.*` — Capability gating
643
-
644
- | Key path | Type | Default | Description |
645
- |----------|------|---------|-------------|
646
- | `policy.requireIntentForDestructiveActions` | `boolean` | _(unset)_ | Require explicit intent for deletes/forgets. |
647
- | `policy.disabledCapabilities` | `string[]` | _(unset)_ | Disable named capabilities. |
648
-
649
- #### `notifications.*`
650
-
651
- | Key path | Type | Default | Description |
652
- |----------|------|---------|-------------|
653
- | `notifications.enabled` | `boolean` | `false` | Enable run-completion notifications. |
654
- | `notifications.severityFilter` | `Severity[]` | `[warning, error, critical]` | Which severities to surface. |
655
- | `notifications.dedupWindowMs` | `number` | `30000` | De-duplicate notifications within this window. |
656
- | `notifications.batchWindowMs` | `number` | `0` | Batch notifications for this long before emitting. |
657
- | `notifications.quietHours` | `string` | _(unset)_ | Quiet-hours schedule (e.g. `"22:00-08:00"`). |
658
- | `notifications.sinkRetentionDays` | `number` | `7` | How long notification sinks retain data. |
659
-
660
- #### `observability.*`
661
-
662
- | Key path | Type | Default | Description |
663
- |----------|------|---------|-------------|
664
- | `observability.enabled` | `boolean` | _(unset)_ | Enable the periodic observability poller. |
665
- | `observability.pollIntervalMs` | `number` | _(unset)_ | Polling interval. |
666
- | `observability.metricRetentionDays` | `number` | _(unset)_ | How long metrics are retained. |
667
-
668
- #### `reliability.*` — Retry, recovery & validation
669
-
670
- | Key path | Type | Default | Description |
671
- |----------|------|---------|-------------|
672
- | `reliability.autoRetry` | `boolean` | `false` | Auto-retry failed tasks. |
673
- | `reliability.retryPolicy.maxAttempts` | `number` | _(unset)_ | Max retry attempts. |
674
- | `reliability.retryPolicy.backoffMs` | `number` | _(unset)_ | Base backoff between retries. |
675
- | `reliability.retryPolicy.jitterRatio` | `number` | _(unset)_ | Jitter fraction (0–1). |
676
- | `reliability.retryPolicy.exponentialFactor` | `number` | _(unset)_ | Exponential backoff multiplier. |
677
- | `reliability.retryPolicy.retryableErrors` | `string[]` | _(unset)_ | Error substrings considered retryable. |
678
- | `reliability.retryPolicy.maxTotalSpawns` | `number` | `0` | Flat per-task spawn budget (0 = auto). |
679
- | `reliability.autoRecover` | `boolean` | `false` | Auto-recover stuck/orphaned runs. |
680
- | `reliability.deadletterThreshold` | `number` | _(unset)_ | Attempts before a task is dead-lettered. |
681
- | `reliability.autoRepairIntervalMs` | `number` | `60000` | Periodic stale-run repair interval (0 = off). |
682
- | `reliability.cleanupOrphanedTempDirs` | `boolean` | `true` | Remove orphaned `/tmp/pi-crew-*` dirs. |
683
- | `reliability.forcePreflight` | `boolean` | `false` | Bypass the topology validator (audit-logged). |
684
- | `reliability.ambientStatusInjection` | `boolean` | `true` | Inject ambient crew-status note on every LLM call. |
685
- | `reliability.perWriteValidation` | `boolean` | `true` | Validate `write`/`edit` results (JSON v1). |
686
- | `reliability.scopeModels` | `boolean` | `false` | Enforce subagent models stay within the allowlist. |
687
-
688
- #### `otlp.*` — OpenTelemetry export
689
-
690
- | Key path | Type | Default | Description |
691
- |----------|------|---------|-------------|
692
- | `otlp.enabled` | `boolean` | _(unset)_ | Enable OTLP trace/metric export. |
693
- | `otlp.endpoint` 🔒 | `string` | _(unset)_ | OTLP collector endpoint. |
694
- | `otlp.headers` 🔒 | `Record<string, string>` | _(unset)_ | Auth headers sent to the collector. |
695
- | `otlp.intervalMs` | `number` | _(unset)_ | Export flush interval. |
696
-
697
- #### `ui.*` — Dashboard & widget
698
-
699
- | Key path | Type | Default | Description |
700
- |----------|------|---------|-------------|
701
- | `ui.widgetPlacement` | `aboveEditor \| belowEditor \| bottom` | `bottom` | Where the status widget renders. `bottom` docks inside the crew-vibes footer (very bottom of the screen), falling back to `belowEditor` when no footer sink exists. |
702
- | `ui.inlinePanel` | `boolean` | `true` | Keyboard-navigable agent rows under the prompt (`↓` from an empty prompt). Yields to any extension that owns the editor component. |
703
- | `ui.refreshMs` | `number` | `1000` | Internal UI refresh cadence default (not a user-settable `ui.*` schema key — kept here for completeness). |
704
- | `ui.widgetDefaultFrameMs` | `number` | `1000` | Internal widget frame-budget default (not a user-settable `ui.*` schema key — kept here for completeness). |
705
- | `ui.widgetMaxLines` | `number` | `8` | Max lines shown by the widget. |
706
- | `ui.powerbar` | `boolean` | `true` | Show the power bar. |
707
- | `ui.dashboardPlacement` | `center \| right` | `center` | Dashboard screen position. |
708
- | `ui.dashboardWidth` | `number` | `72` | Dashboard column width. |
709
- | `ui.dashboardLiveRefreshMs` | `number` | `1000` | Dashboard live-refresh interval. |
710
- | `ui.autoOpenDashboard` | `boolean` | `false` | Auto-open the dashboard. |
711
- | `ui.autoOpenDashboardForForegroundRuns` | `boolean` | `false` | Auto-open only for foreground runs. |
712
- | `ui.autoCloseDashboardMs` | `number` | _(unset)_ | Auto-close the dashboard after this long. |
713
- | `ui.showModel` | `boolean` | `true` | Show model names in the UI. |
714
- | `ui.showTokens` | `boolean` | `true` | Show token counts. |
715
- | `ui.showTools` | `boolean` | `true` | Show tool activity. |
716
- | `ui.transcriptTailBytes` | `number` | `1048576` | Bytes of transcript tail kept. |
717
- | `ui.mascotStyle` | `cat \| armin` | `cat` | Mascot character. |
718
- | `ui.mascotEffect` | `random \| none \| …` | `random` | Mascot animation effect. |
719
-
720
- #### `broker.*` — Inter-Pi broker
721
-
722
- > Default is **ON** since v0.9.47 (Linux + macOS). Disable via
723
- > `broker.enabled: false`, env `PI_CREW_BROKER=0`, or auto-off on Windows.
724
-
725
- | Key path | Type | Default | Description |
726
- |----------|------|---------|-------------|
727
- | `broker.enabled` | `boolean` | `true` | Master switch for the local socket broker. |
728
- | `broker.pathHashLen` | `number` (4–32) | `8` | SHA-256 prefix length in the socket filename. |
729
- | `broker.maxFrameBytes` | `number` (1024–1048576) | `262144` | Max NDJSON frame size (256 KiB). |
730
- | `broker.outboundQueueCap` | `number` (32–4096) | `256` | Per-connection outbound queue cap. |
731
-
732
- > ⚠️ **Trust boundary**: 🔒 keys are blocked from project config — set them in
733
- > **user config** only. The project config sanitizer silently drops them with a
734
- > warning so untrusted repos cannot escalate privileges or redirect telemetry.
735
-
736
- 📖 Interactive config UI: [docs/commands-reference.md#team-settings--config-management](docs/commands-reference.md) · machine-readable: [schema.json](schema.json)
737
-
738
- ---
739
-
740
- ## Reliability & Trust
741
-
742
- ### Compaction resilience
743
-
744
- 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:
745
-
746
- ```
747
- Context compacted. 1 pi-crew run(s) still in-flight — use team status to continue.
748
- ```
749
-
750
- **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.)
751
-
752
- **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.
753
-
754
- ### Plan-level human-in-the-loop (HITL)
755
-
756
- 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:
757
-
758
- ```
759
- team api op=approve-plan runId=<runId> # approve → execute
760
- team api op=cancel-plan runId=<runId> # cancel
761
- ```
762
-
763
- This is plan-level (not per-step) — per-step gates would kill the parallelism that's pi-crew's point.
764
-
765
- ### Cross-run memory (`.crew/knowledge.md`)
766
-
767
- 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.
768
-
769
- ```markdown
770
- # Project Knowledge
771
- - Tests: run with `npm test` (not jest directly)
772
- - Style: tabs, not spaces
773
- - Auth refactor (2026-06): split auth.ts into session.ts + api.ts
774
- ```
775
-
776
- ### Cost visibility
777
-
778
- Every `team summary <runId>` includes a per-role cost report:
779
-
780
- ```
781
- ═══ Cost Report ═══
782
- Tokens: 134k (in 112k, out 5.7k, cache-write 16k)
783
- Cost: $0.7700 across 18 turn(s)
784
- By role:
785
- executor (2 tasks): $0.6100 — 79%, 98k tok, 13 turns
786
- reviewer (1 task): $0.1100 — 14%, 23k tok, 3 turns
787
- ```
788
-
789
- ### Single-agent mode (cliff hedge)
790
-
791
- Any workflow can run single-agent instead of multi-agent — composing all phases into one sequential prompt:
792
-
793
- ```
794
- team plan team=default workflow=default goal="..." singleAgent=true
795
- ```
796
-
797
- 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.
798
-
799
- ---
800
-
801
- ## Tool Actions
118
+ | User | `~/.pi/agent/pi-crew.json` |
119
+ | User (legacy, still read) | `~/.pi/agent/extensions/pi-crew/config.json` |
120
+ | Project | `.crew/config.json` (legacy layout: `.pi/teams/config.json`; alt: `.pi/pi-crew.json`) |
121
+
122
+ Most-used keys (full set: [docs/usage.md](docs/usage.md) · [schema.json](schema.json)):
123
+
124
+ | Key | What it does |
125
+ |-----|--------------|
126
+ | `runtime.mode` 🔒 | `auto \| scaffold \| child-process \| live-session` — how workers execute |
127
+ | `executeWorkers` 🔒 | `false` = dry-run planning only, no child processes |
128
+ | `asyncByDefault` 🔒 | detach every run by default (survives session switches) |
129
+ | `limits.maxConcurrentWorkers` | hard cap on parallel workers |
130
+ | `runtime.maxTurns` | per-task turn ceiling |
131
+ | `runtime.requirePlanApproval` | pause at the plan→execute boundary for approval |
132
+ | `worktree.linkNodeModules` | symlink `node_modules` into task worktrees |
133
+ | `agents.overrides` 🔒 | per-agent `model` / `skills` / `tools` override |
134
+ | `reliability.autoRetry` | auto-retry failed tasks |
135
+ | `broker.enabled` | inter-session message bus; default `true` (`PI_CREW_BROKER=0` always wins; auto-off on native Windows) |
136
+ | `notifications.webhook` 🔒 | opt-in outbound webhook on run completion — one POST per terminal run, quiet-hours-aware, SSRF-guarded (see below) |
137
+
138
+ 🔒 = sensitive: settable in **user config only** — project config silently
139
+ drops these keys with a warning, so untrusted repos can't escalate privileges.
140
+ Environment variables (`PI_CREW_BROKER`, `PI_CREW_USE_BUNDLE`, …) are listed in
141
+ [src/config/env-vars.ts](src/config/env-vars.ts).
142
+
143
+ ### Webhook notifications (US-030)
144
+
145
+ Disabled by default — **no URL configured means zero network calls**. When a
146
+ run reaches a terminal status (`completed` / `failed` / `cancelled`), and it
147
+ is outside `notifications.quietHours`, pi-crew POSTs one JSON document to
148
+ your URL (5 s timeout, exactly one retry on 5xx/network error, failures never
149
+ affect the run):
802
150
 
803
151
  ```json
804
- // Execute workflow (foreground or async)
805
- { "action": "run", "team": "default", "goal": "..." }
806
- { "action": "run", "team": "default", "goal": "...", "async": true }
807
-
808
- // Monitor & control
809
- { "action": "status", "runId": "team_..." }
810
- { "action": "summary", "runId": "team_..." }
811
- { "action": "events", "runId": "team_..." }
812
- { "action": "artifacts", "runId": "team_..." }
813
- { "action": "cancel", "runId": "team_..." }
814
- { "action": "resume", "runId": "team_..." }
815
- { "action": "retry", "runId": "team_..." }
816
- { "action": "steer", "runId": "team_...", "taskId": "01_explore", "message": "Focus on src/ only" }
817
- { "action": "respond", "runId": "team_...", "message": "Answer" }
818
- { "action": "wait", "runId": "team_..." }
819
-
820
- // Discovery
821
- { "action": "list" }
822
- { "action": "get", "resource": "team", "team": "default" }
823
- { "action": "get", "resource": "agent", "agent": "explorer" }
824
- { "action": "get", "resource": "workflow", "workflow": "review" }
825
- { "action": "recommend", "goal": "Refactor auth flow" }
826
- { "action": "search", "goal": "heartbeat detection" }
827
-
828
- // Resource management
829
- { "action": "create", "resource": "agent", "config": { "name": "api-reviewer", ... } }
830
- { "action": "update", "resource": "team", "name": "backend", "config": { ... } }
831
- { "action": "delete", "resource": "workflow", "name": "quick-review" }
832
- { "action": "validate" }
833
-
834
- // Run maintenance
835
- { "action": "cleanup", "runId": "team_..." }
836
- { "action": "forget", "runId": "team_...", "confirm": true }
837
- { "action": "prune", "olderThanDays": 7, "confirm": true }
838
- { "action": "export", "runId": "team_..." }
839
- { "action": "import", "path": "/path/to/bundle.tar.gz" }
840
-
841
- // Environment & configuration
842
- { "action": "doctor", "config": { "smokeChildPi": true } }
843
- { "action": "config" }
844
- { "action": "init", "config": { "copyBuiltins": true } }
845
- { "action": "autonomy", "profile": "assisted" }
846
-
847
- // Advanced
848
- { "action": "api", "runId": "team_...", "config": { "operation": "read-manifest" } }
849
- { "action": "plan", "team": "default", "goal": "..." }
850
- { "action": "orchestrate", "planPath": "plan.md", "team": "implementation", "goal": "..." }
851
- { "action": "parallel", "config": { "tasks": [{"goal": "...", "agent": "explorer"}] } }
852
- { "action": "worktrees", "runId": "team_..." }
853
- { "action": "graph", "runId": "team_..." }
854
- { "action": "explain", "runId": "team_..." }
855
- { "action": "health" }
856
- { "action": "doctor" }
857
- { "action": "cache" }
858
- { "action": "invalidate", "runId": "team_..." }
859
-
860
- // Scheduled runs
861
- { "action": "schedule", "team": "fast-fix", "goal": "Run tests", "cron": "0 9 * * MON" }
862
- { "action": "schedule", "team": "default", "goal": "...", "interval": 3600000 }
863
- { "action": "schedule", "team": "research", "goal": "...", "once": "+10m" }
864
- { "action": "scheduled" }
865
-
866
- // Diagnostics & settings
867
- { "action": "config" }
868
- { "action": "settings" }
869
- { "action": "autonomy" }
870
- { "action": "anchor" }
871
- { "action": "onboard" }
872
- { "action": "auto-summarize" }
873
- ```
874
-
875
- 📖 Full actions reference (54 schema actions across 5 domain dispatchers: run/status/control/manage/automate): [docs/actions-reference.md](docs/actions-reference.md)
876
-
877
- ---
878
-
879
- ## Slash Commands
880
-
881
- ```text
882
- /team-run [--team=X] [--async] [--worktree] <goal>
883
- /team-status <runId>
884
- /team-dashboard
885
- /team-doctor
886
- /team-init [--copy-builtins]
887
- /team-config [key=value]
888
- /team-autonomy [status|on|off|suggested|assisted]
889
- ```
890
-
891
- 📖 Full commands reference: [docs/commands-reference.md](docs/commands-reference.md)
892
-
893
- ---
894
-
895
- ## Resource Discovery
896
-
897
- Agents, teams, and workflows are discovered from three layers:
898
-
899
- ```
900
- builtin (package) < user (~/.pi/agent/) < project (.crew/ or .pi/teams/)
901
- ```
902
-
903
- Project resources can add new names but **cannot shadow** builtin/user resources.
904
-
905
- ### Resource Paths
906
-
907
- | Type | Builtin | User | Project |
908
- |------|---------|------|---------|
909
- | Agent | `agents/*.md` | `~/.pi/agent/agents/*.md` | `.crew/agents/*.md` |
910
- | Team | `teams/*.team.md` | `~/.pi/agent/teams/*.team.md` | `.crew/teams/*.team.md` |
911
- | Workflow | `workflows/*.workflow.md` | `~/.pi/agent/workflows/*.workflow.md` | `.crew/workflows/*.workflow.md` |
912
-
913
- ### Custom Resources with Routing Metadata
914
-
915
- ```yaml
916
- ---
917
- name: api-reviewer
918
- description: Reviews API changes
919
- triggers: api, endpoint, contract
920
- useWhen: backend API changes, OpenAPI changes
921
- avoidWhen: docs-only edits
922
- cost: cheap
923
- category: backend
924
- ---
925
- Your system prompt here.
926
- ```
927
-
928
- 📖 Full resource formats: [docs/resource-formats.md](docs/resource-formats.md)
929
-
930
- ---
931
-
932
- ## State Layout
933
-
934
- ```
935
- <crewRoot>/ # .crew/ (new) or .pi/teams/ (legacy)
936
- ├── state/runs/{runId}/
937
- │ ├── manifest.json # run metadata
938
- │ ├── tasks.json # task graph + status
939
- │ ├── events.jsonl # append-only events
940
- │ └── agents/{taskId}/status.json # per-agent state
941
- ├── artifacts/{runId}/
942
- │ ├── goal.md
943
- │ ├── prompts/{taskId}.md
944
- │ ├── results/{taskId}.txt
945
- │ ├── logs/{taskId}.log
946
- │ └── summary.md
947
- ├── worktrees/{runId}/{taskId}/
948
- └── imports/{runId}/run-export.json
949
- ```
950
-
951
- ---
952
-
953
- ## Environment Variables
954
-
955
- | Variable | Purpose |
956
- |----------|---------|
957
- | `PI_CREW_BROKER=0` | **Disable the inter-pi broker entirely** (always wins over config). Use to opt out of cross-session messaging. |
958
- | `PI_CREW_BROKER=1` | Explicitly enable the broker (redundant under the v0.9.47 default-on; useful for overriding a config `broker.enabled: false`). |
959
- | `PI_CREW_USE_BUNDLE=1` | Force-load via bundled `dist/index.mjs` (~19% faster cold-start than strip-types). Default: bundle (since v0.9.17). Set `PI_CREW_USE_BUNDLE=0` to force strip-types fallback. Requires `npm run build:bundle` to have produced `dist/`. |
960
- | `PI_CREW_EXECUTE_WORKERS=0` | Disable child workers (scaffold mode) |
961
- | `PI_TEAMS_EXECUTE_WORKERS=0` | Legacy disable flag |
962
- | `PI_TEAMS_MOCK_CHILD_PI=success` | Mock child worker for testing |
963
- | `PI_TEAMS_PI_BIN=<path>` | Explicit Pi CLI path |
964
- | `PI_TEAMS_HOME=<path>` | Override home for tests |
965
-
966
- ---
967
-
968
- ## Development
969
-
970
- ### Auto-rebuild bundle on edit
971
-
972
- For active development on the bundle, run the watcher in a separate terminal:
973
-
974
- ```bash
975
- npm run watch:bundle
976
- ```
977
-
978
- 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).
979
-
980
- ```bash
981
- npm run watch:bundle # watch + auto-rebuild
982
- npm run watch:bundle --debounce 500 # custom debounce
983
- node scripts/watch-bundle.mjs --once # build once and exit (CI prep)
984
- ```
985
-
986
- 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.
987
-
988
- ```bash
989
- cd pi-crew
990
- npm install # dependencies
991
- npm test # unit + integration tests (~6,500 tests)
992
- npm run test:critical # fast subset: 97 broker/UI tests in ~20s
993
- npm run typecheck # tsc --noEmit
994
- npm run ci # full CI-equivalent check
995
- npm pack --dry-run # package verification
996
- ```
997
-
998
- Stats: **476 source files** (112K lines) · **762 test files** (717 unit + 34 integration + 5 smoke + 3 functional + 2 platform + 1 manual) · **CI: Ubuntu ✅ macOS ✅ Windows ✅**
999
-
1000
- ---
1001
-
1002
- ## Repository layout
1003
-
1004
- After the v0.9.x reorg (~90 commits) the repo is cluster-organised so related
1005
- files live together — source, tests, and docs mirror each other.
1006
-
1007
- ```
1008
- src/ # ~476 TS files
1009
- ├── runtime/ # team-run execution machinery — 15 subdirs + ~77 flat files
1010
- ├── state/ # persistent state layer — 3 subdirs + 12 root files
1011
- ├── extension/ # Pi extension surface (register, team-tool, ui glue)
1012
- ├── ui/ # TUI, dashboard, overlays
1013
- ├── config/ · utils/ · agents/ · workflows/ · … # supporting clusters
1014
- test/
1015
- └── unit/ # mirrors src/ — 35 leaf subdirs + 151 cross-cutting tests at root
1016
- ├── runtime/ · state/ · extension/ · ui/ · config/ · …
1017
- docs/ # living docs at root; history in docs/archive/
152
+ "notifications": {
153
+ "quietHours": "22:00-07:00",
154
+ "webhook": {
155
+ "url": "https://hooks.example.com/pi-crew",
156
+ "enabled": true,
157
+ "secret": "shared-secret",
158
+ "allowLocalhost": false
159
+ }
160
+ }
1018
161
  ```
1019
162
 
1020
- - **`src/`** — each top-level dir has a cluster map; the two largest are
1021
- [`src/runtime/README.md`](src/runtime/README.md) (15 subdirs: child-pi,
1022
- broker, live-session, recovery, scheduling, verification, model, output,
1023
- heartbeat, process, goal-workflow, compaction, task-runner, custom-tools,
1024
- errors) and [`src/state/README.md`](src/state/README.md) (event-log,
1025
- stores, coordination).
1026
- - **`test/unit/`** — mirrors `src/` 1:1; cross-cutting tests (`round*`,
1027
- `v0*`, `package-*`, errors, i18n, bundle-*) stay at the root by design.
1028
- See [`test/unit/README.md`](test/unit/README.md).
1029
- - **`docs/`** — 20 living docs at the root; 27 historical docs moved to
1030
- `docs/archive/`. See [`docs/README.md`](docs/README.md).
163
+ Payload (PII-safe — no transcripts or events, goal is first-line only):
164
+ `{ "event": "run.terminal", "runId": …, "status": …, "team": …, "goal": …,
165
+ "durationMs": …, "cost": …, "tokens": …, "at": "<ISO>" }`. With `secret`
166
+ set, every request carries `x-pi-crew-signature: sha256=<hmac-sha256(raw body,
167
+ secret)>`. Non-http(s) URLs and loopback/link-local targets (`localhost`,
168
+ `127.0.0.0/8`, `[::1]`, `fe80::/10`, `169.254.0.0/16`) are refused unless you
169
+ set `allowLocalhost: true` explicitly. The whole `webhook` block is 🔒 — user
170
+ config only, so an untrusted repo cannot point your runs at an attacker URL.
1031
171
 
1032
- ---
1033
-
1034
- ## Documentation
172
+ ## Where things live
1035
173
 
1036
174
  | Doc | Contents |
1037
175
  |-----|----------|
1038
- | [docs/actions-reference.md](docs/actions-reference.md) | Full tool actions + examples |
1039
- | [docs/commands-reference.md](docs/commands-reference.md) | Slash commands + `/team-api` |
1040
- | [docs/resource-formats.md](docs/resource-formats.md) | Agent/team/workflow file formats |
1041
- | [docs/usage.md](docs/usage.md) | Usage patterns + config examples |
1042
- | [docs/troubleshooting.md](docs/troubleshooting.md) | Common errors, recovery, and error-code reference (E001–E012) |
1043
- | [docs/architecture.md](docs/architecture.md) | Internal architecture + run flow |
1044
- | [docs/runtime-flow.md](docs/runtime-flow.md) | Runtime execution details |
1045
- | [docs/goals.md](docs/goals.md) | **v0.9.0** Autonomous goal loops (`team action='goal'`) |
1046
- | [docs/dynamic-workflows.md](docs/dynamic-workflows.md) | **v0.9.0** `.dwf.ts` script runtime + trust model |
1047
- | [docs/live-mailbox-runtime.md](docs/live-mailbox-runtime.md) | Mailbox + live-session runtime |
1048
- | [docs/publishing.md](docs/publishing.md) | Release & publish process |
1049
- | [docs/README.md](docs/README.md) | Index of all docs/ (living + subdirs) |
1050
- | [src/runtime/README.md](src/runtime/README.md) | Runtime source cluster map (15 subdirs) |
1051
- | [src/state/README.md](src/state/README.md) | State source cluster map (3 subdirs) |
1052
- | [test/unit/README.md](test/unit/README.md) | Unit-test cluster map (mirrors src/) |
1053
- | [docs/archive/next-upgrade-roadmap.md](docs/archive/next-upgrade-roadmap.md) | Future upgrade roadmap |
1054
- | [schema.json](schema.json) | Config JSON schema |
1055
-
1056
- Research docs (not in package): [`docs/pi-crew-research/`](https://github.com/baphuongna/pi-crew/tree/main/docs) — audits, deep research, distillation notes.
1057
-
1058
- ---
176
+ | [docs/README.md](docs/README.md) | index of all docs (living + archive) |
177
+ | [docs/usage.md](docs/usage.md) | usage patterns + config examples |
178
+ | [docs/actions-reference.md](docs/actions-reference.md) | all 55 `team` actions with examples |
179
+ | [docs/commands-reference.md](docs/commands-reference.md) | slash commands + `/team-api` |
180
+ | [docs/architecture.md](docs/architecture.md) | internal architecture + run flow |
181
+ | [docs/troubleshooting.md](docs/troubleshooting.md) | common errors, recovery, error codes |
182
+ | [docs/trust-model.md](docs/trust-model.md) | trust boundaries + accepted risks |
183
+ | [docs/dynamic-workflows.md](docs/dynamic-workflows.md) | `.dwf.ts` runtime + its security model |
184
+ | [docs/resource-formats.md](docs/resource-formats.md) | agent/team/workflow file formats |
185
+ | [docs/publishing.md](docs/publishing.md) | release & publish process |
186
+
187
+ Also: [schema.json](schema.json) (machine-readable config) ·
188
+ [CHANGELOG.md](CHANGELOG.md) (version history) · [`skills/`](skills/) (bundled
189
+ skills) · [NOTICE.md](NOTICE.md) (attributions).
1059
190
 
1060
191
  ## Known limitations
1061
192
 
1062
- This is AI-developed software built for a personal workflow. These are the
1063
- sharp edges I'm aware of — there are almost certainly others I'm not.
193
+ - **`.dwf.ts` scripts are not sandboxed.** They run in plain module scope with
194
+ full `require`/`process` access (postinstall-equivalent trust). Only run
195
+ scripts you have reviewed. See
196
+ [the security model](docs/dynamic-workflows.md#security-model-important).
197
+ - **Workers run with your privileges; verification is best-effort.** Guards
198
+ (read-only defaults for unknown roles, path allowlists, sensitive-key
199
+ sanitizing) raise the bar, but they are not a boundary against a malicious
200
+ worker in the same process. See [docs/trust-model.md](docs/trust-model.md).
201
+ - **AI-developed, single maintainer.** Every change ships after static review
202
+ + runtime tests, but there is no independent human audit. Found a bug or a
203
+ sharp edge? [Open an issue](https://github.com/baphuongna/pi-crew/issues).
1064
204
 
1065
- - **Multi-step goal-wrap crashes non-deterministically.** Goal-wrapping
1066
- multi-step builtin workflows (`fast-fix`, `default`) can hit a V8/libuv
1067
- event-loop race that kills the background process with no signal, no core,
1068
- and no V8 diagnostic report (8 investigation attempts: gdb, strace, perf,
1069
- `--report-on-fatalerror`, sync-fs workarounds, worker-thread atomic writer —
1070
- see [CHANGELOG.md](CHANGELOG.md) § v0.9.0 "Phase 1.5 #3").
1071
- **Mitigation:** multi-step workflows silently auto-downgrade to a normal
1072
- team-run (no goal-wrap layer); single-step workflows (`implementation`)
1073
- goal-wrap end-to-end.
1074
- - **`.dwf.ts` scripts are NOT sandboxed in v1.** The `WorkflowCtx` is
1075
- `Object.freeze()`d, but the script runs in plain module scope with full
1076
- `require`/`import`/`process` access (postinstall-equivalent trust).
1077
- `isolated-vm` (real V8 isolate) is planned for a future release. Only place
1078
- `.dwf.ts` files you have reviewed. See
1079
- [docs/dynamic-workflows.md#security-model-important](docs/dynamic-workflows.md#security-model-important).
1080
- - **Editor/agent file caching.** After editing a loaded pi-crew source file,
1081
- restart the Pi session for changes to take effect (jiti in-memory cache).
1082
- Editing a `.dwf.ts` in place while a run is mid-flight can serve a stale
1083
- module body; rename the file or restart Pi to force a fresh load.
1084
- - **Verification integrity is best-effort against adversarial workers.** The
1085
- bookend snapshot (P1a) and git-worktree sandbox (Phase 1.5 #2, opt-in)
1086
- raise the bar, but a worker in the same process can still tamper with files
1087
- outside the snapshot window. Full isolation requires the planned sandbox.
1088
- - **Single maintainer + AI review.** Every change ships after 2+ consecutive
1089
- clean static-review rounds + runtime tests, but there's no independent human
1090
- audit. Fork and read before trusting anything that touches your data.
205
+ ## Development
1091
206
 
1092
- If you hit any of these — or a new one — please
1093
- [open an issue](https://github.com/baphuongna/pi-crew/issues).
207
+ ```bash
208
+ npm install
209
+ npm test # unit + integration suites
210
+ npm run test:critical # fast broker/UI subset (~20s)
211
+ npm run typecheck # tsc --noEmit + strip-types import check
212
+ npm run lint # biome (linters only)
213
+ npm run format:check # biome format
214
+ npm run ci # full gate: checks, typecheck, lint, bundle, tests, pack
215
+ npm run build:bundle # rebuild dist/index.mjs
216
+ ```
1094
217
 
1095
- ---
218
+ Running Pi sessions load the pre-built `dist/index.mjs` bundle — rebuild
219
+ (`npm run build:bundle`, or `npm run watch:bundle` while editing) and start a
220
+ new Pi session to pick up source changes.
1096
221
 
1097
- ## Acknowledgements
222
+ ## License
1098
223
 
1099
- `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`.
224
+ MIT — see [LICENSE](LICENSE).