pi-crew 0.2.3 → 0.2.5

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 (348) hide show
  1. package/AGENTS.md +57 -32
  2. package/CHANGELOG.md +466 -448
  3. package/LICENSE +21 -21
  4. package/NOTICE.md +16 -16
  5. package/README.md +323 -323
  6. package/docs/FEATURE_INTAKE.md +126 -0
  7. package/docs/HARNESS.md +86 -0
  8. package/docs/HARNESS_BACKLOG.md +41 -0
  9. package/docs/TEST_MATRIX.md +49 -0
  10. package/docs/actions-reference.md +595 -595
  11. package/docs/architecture.md +180 -180
  12. package/docs/code-review-2026-05-11.md +592 -592
  13. package/docs/commands-reference.md +347 -347
  14. package/docs/comparison-pi-subagents-vs-pi-crew.md +303 -0
  15. package/docs/decisions/0001-durable-state.md +41 -0
  16. package/docs/decisions/0002-child-process-for-async.md +42 -0
  17. package/docs/decisions/0003-depth-guard.md +36 -0
  18. package/docs/decisions/0004-execfile-over-exec.md +34 -0
  19. package/docs/decisions/0005-no-parameter-properties.md +49 -0
  20. package/docs/decisions/0006-publish-bundled-esm.md +63 -0
  21. package/docs/decisions/0007-active-run-binary-index.md +54 -0
  22. package/docs/decisions/0008-child-pi-warm-pool.md +61 -0
  23. package/docs/decisions/README.md +23 -0
  24. package/docs/followup-review-round4-2026-05-13.md +107 -0
  25. package/docs/implementation-plan-top3.md +333 -0
  26. package/docs/live-mailbox-runtime.md +36 -36
  27. package/docs/next-upgrade-roadmap.md +808 -808
  28. package/docs/oh-my-pi-research.md +509 -0
  29. package/docs/perf/baseline-2026-05.md +113 -0
  30. package/docs/perf/final-report-2026-05.md +206 -0
  31. package/docs/perf/sprint-1-report.md +71 -0
  32. package/docs/perf/sprint-2-report.md +81 -0
  33. package/docs/perf/sprint-2.5-report.md +53 -0
  34. package/docs/perf/sprint-3-report.md +36 -0
  35. package/docs/perf/sprint-4-report.md +47 -0
  36. package/docs/perf/sprint-5-report.md +51 -0
  37. package/docs/perf/sprint-6-report.md +94 -0
  38. package/docs/perf/sprint-7-report.md +74 -0
  39. package/docs/perf/upgrade-plan-2026-05.md +147 -0
  40. package/docs/pi-subagents3-deep-analysis.md +508 -0
  41. package/docs/product/README.md +31 -0
  42. package/docs/product/platform.md +27 -0
  43. package/docs/product/runtime-safety.md +37 -0
  44. package/docs/product/team-run.md +39 -0
  45. package/docs/product/team-tool.md +37 -0
  46. package/docs/publishing.md +65 -65
  47. package/docs/resource-formats.md +134 -134
  48. package/docs/runtime-analysis-child-vs-live.md +171 -0
  49. package/docs/runtime-flow.md +148 -148
  50. package/docs/runtime-migration-in-process-analysis.md +250 -0
  51. package/docs/stories/README.md +30 -0
  52. package/docs/stories/backlog.md +36 -0
  53. package/docs/templates/decision.md +27 -0
  54. package/docs/templates/story.md +44 -0
  55. package/docs/templates/validation-report.md +32 -0
  56. package/docs/usage.md +238 -238
  57. package/index.ts +7 -6
  58. package/install.mjs +65 -65
  59. package/package.json +107 -100
  60. package/schema.json +222 -222
  61. package/skills/child-pi-spawning/SKILL.md +213 -0
  62. package/skills/context-artifact-hygiene/SKILL.md +32 -0
  63. package/skills/event-log-tracing/SKILL.md +299 -0
  64. package/skills/git-master/SKILL.md +225 -24
  65. package/skills/live-agent-lifecycle/SKILL.md +192 -0
  66. package/skills/mailbox-interactive/SKILL.md +300 -19
  67. package/skills/model-routing-context/SKILL.md +94 -0
  68. package/skills/multi-perspective-review/SKILL.md +88 -0
  69. package/skills/read-only-explorer/SKILL.md +250 -26
  70. package/skills/safe-bash/SKILL.md +307 -21
  71. package/skills/verification-before-done/SKILL.md +11 -2
  72. package/skills/widget-rendering/SKILL.md +258 -0
  73. package/skills/workspace-isolation/SKILL.md +202 -0
  74. package/skills/worktree-isolation/SKILL.md +202 -18
  75. package/src/adapters/claude-adapter.ts +25 -25
  76. package/src/adapters/codex-adapter.ts +21 -21
  77. package/src/adapters/cursor-adapter.ts +17 -17
  78. package/src/adapters/export-util.ts +137 -137
  79. package/src/adapters/index.ts +15 -15
  80. package/src/adapters/registry.ts +18 -18
  81. package/src/adapters/types.ts +23 -23
  82. package/src/agents/agent-config.ts +38 -38
  83. package/src/agents/agent-serializer.ts +38 -38
  84. package/src/agents/discover-agents.ts +121 -118
  85. package/src/config/config.ts +740 -858
  86. package/src/config/defaults.ts +96 -96
  87. package/src/config/drift-detector.ts +211 -211
  88. package/src/config/markers.ts +327 -327
  89. package/src/config/resilient-parser.ts +109 -108
  90. package/src/config/suggestions.ts +74 -74
  91. package/src/config/types.ts +199 -0
  92. package/src/extension/async-notifier.ts +123 -89
  93. package/src/extension/autonomous-policy.ts +169 -169
  94. package/src/extension/cross-extension-rpc.ts +104 -104
  95. package/src/extension/help.ts +47 -47
  96. package/src/extension/import-index.ts +69 -69
  97. package/src/extension/management.ts +395 -382
  98. package/src/extension/notification-router.ts +116 -116
  99. package/src/extension/notification-sink.ts +51 -51
  100. package/src/extension/project-init.ts +168 -168
  101. package/src/extension/register.ts +859 -668
  102. package/src/extension/registration/artifact-cleanup.ts +15 -15
  103. package/src/extension/registration/command-utils.ts +54 -54
  104. package/src/extension/registration/commands.ts +559 -452
  105. package/src/extension/registration/compaction-guard.ts +125 -125
  106. package/src/extension/registration/subagent-helpers.ts +102 -102
  107. package/src/extension/registration/subagent-tools.ts +220 -159
  108. package/src/extension/registration/team-tool.ts +159 -99
  109. package/src/extension/registration/viewers.ts +29 -0
  110. package/src/extension/result-watcher.ts +128 -128
  111. package/src/extension/run-bundle-schema.ts +89 -89
  112. package/src/extension/run-export.ts +73 -73
  113. package/src/extension/run-import.ts +84 -84
  114. package/src/extension/run-index.ts +94 -94
  115. package/src/extension/run-maintenance.ts +142 -142
  116. package/src/extension/session-summary.ts +8 -8
  117. package/src/extension/team-manager-command.ts +96 -96
  118. package/src/extension/team-recommendation.ts +188 -188
  119. package/src/extension/team-tool/api.ts +5 -2
  120. package/src/extension/team-tool/cancel.ts +224 -209
  121. package/src/extension/team-tool/config-patch.ts +36 -36
  122. package/src/extension/team-tool/context.ts +60 -60
  123. package/src/extension/team-tool/doctor.ts +242 -242
  124. package/src/extension/team-tool/handle-settings.ts +421 -195
  125. package/src/extension/team-tool/inspect.ts +41 -41
  126. package/src/extension/team-tool/lifecycle-actions.ts +139 -139
  127. package/src/extension/team-tool/parallel-dispatch.ts +156 -156
  128. package/src/extension/team-tool/plan.ts +19 -19
  129. package/src/extension/team-tool/respond.ts +112 -111
  130. package/src/extension/team-tool/run.ts +246 -229
  131. package/src/extension/team-tool/status.ts +110 -110
  132. package/src/extension/team-tool-types.ts +13 -13
  133. package/src/extension/team-tool.ts +344 -344
  134. package/src/extension/tool-result.ts +16 -16
  135. package/src/extension/validate-resources.ts +77 -77
  136. package/src/hooks/registry.ts +61 -61
  137. package/src/hooks/types.ts +40 -40
  138. package/src/i18n.ts +184 -184
  139. package/src/observability/correlation.ts +35 -35
  140. package/src/observability/event-to-metric.ts +68 -68
  141. package/src/observability/exporters/adapter.ts +30 -30
  142. package/src/observability/exporters/otlp-exporter.ts +106 -92
  143. package/src/observability/exporters/prometheus-exporter.ts +54 -54
  144. package/src/observability/metric-registry.ts +87 -87
  145. package/src/observability/metric-retention.ts +54 -54
  146. package/src/observability/metric-sink.ts +81 -56
  147. package/src/observability/metrics-primitives.ts +167 -167
  148. package/src/prompt/prompt-runtime.ts +72 -72
  149. package/src/runtime/adaptive-plan.ts +338 -0
  150. package/src/runtime/agent-control.ts +169 -169
  151. package/src/runtime/agent-memory.ts +72 -72
  152. package/src/runtime/agent-observability.ts +114 -114
  153. package/src/runtime/async-marker.ts +26 -26
  154. package/src/runtime/async-runner.ts +153 -153
  155. package/src/runtime/attention-events.ts +28 -28
  156. package/src/runtime/auto-resume.ts +100 -100
  157. package/src/runtime/background-runner.ts +122 -89
  158. package/src/runtime/cancellation.ts +61 -61
  159. package/src/runtime/capability-inventory.ts +116 -116
  160. package/src/runtime/child-pi-pool.ts +68 -0
  161. package/src/runtime/child-pi.ts +541 -461
  162. package/src/runtime/code-summary.ts +247 -247
  163. package/src/runtime/compaction-summary.ts +271 -271
  164. package/src/runtime/concurrency.ts +58 -58
  165. package/src/runtime/crash-recovery.ts +317 -301
  166. package/src/runtime/crew-agent-records.ts +379 -281
  167. package/src/runtime/crew-agent-runtime.ts +60 -60
  168. package/src/runtime/cross-extension-rpc.ts +72 -0
  169. package/src/runtime/custom-tools/irc-tool.ts +201 -201
  170. package/src/runtime/custom-tools/submit-result-tool.ts +90 -90
  171. package/src/runtime/deadletter.ts +47 -47
  172. package/src/runtime/delivery-coordinator.ts +176 -176
  173. package/src/runtime/delta-conflict.ts +360 -360
  174. package/src/runtime/diagnostic-export.ts +102 -102
  175. package/src/runtime/direct-run.ts +35 -35
  176. package/src/runtime/effectiveness.ts +82 -81
  177. package/src/runtime/errors/crew-errors.ts +166 -0
  178. package/src/runtime/event-stream-bridge.ts +92 -92
  179. package/src/runtime/foreground-control.ts +82 -82
  180. package/src/runtime/green-contract.ts +46 -46
  181. package/src/runtime/group-join.ts +234 -106
  182. package/src/runtime/heartbeat-watcher.ts +145 -124
  183. package/src/runtime/iteration-hooks.ts +267 -267
  184. package/src/runtime/live-agent-control.ts +88 -88
  185. package/src/runtime/live-agent-manager.ts +377 -179
  186. package/src/runtime/live-control-realtime.ts +36 -36
  187. package/src/runtime/live-session-runtime.ts +676 -600
  188. package/src/runtime/loop-gates.ts +129 -129
  189. package/src/runtime/manifest-cache.ts +263 -263
  190. package/src/runtime/mcp-proxy.ts +113 -113
  191. package/src/runtime/metric-parser.ts +40 -40
  192. package/src/runtime/model-fallback.ts +282 -274
  193. package/src/runtime/model-resolver.ts +118 -0
  194. package/src/runtime/output-validator.ts +187 -187
  195. package/src/runtime/overflow-recovery.ts +175 -175
  196. package/src/runtime/parallel-research.ts +44 -44
  197. package/src/runtime/parallel-utils.ts +156 -156
  198. package/src/runtime/parent-guard.ts +80 -80
  199. package/src/runtime/phase-progress.ts +217 -217
  200. package/src/runtime/pi-args.ts +165 -165
  201. package/src/runtime/pi-json-output.ts +111 -111
  202. package/src/runtime/pi-spawn.ts +167 -167
  203. package/src/runtime/policy-engine.ts +79 -79
  204. package/src/runtime/post-checks.ts +125 -125
  205. package/src/runtime/post-exit-stdio-guard.ts +86 -86
  206. package/src/runtime/process-status.ts +97 -73
  207. package/src/runtime/progress-event-coalescer.ts +43 -43
  208. package/src/runtime/recovery-recipes.ts +74 -74
  209. package/src/runtime/retry-executor.ts +81 -81
  210. package/src/runtime/role-permission.ts +39 -39
  211. package/src/runtime/run-tracker.ts +99 -0
  212. package/src/runtime/runtime-policy.ts +21 -0
  213. package/src/runtime/runtime-resolver.ts +94 -91
  214. package/src/runtime/scheduler.ts +294 -0
  215. package/src/runtime/semaphore.ts +131 -131
  216. package/src/runtime/sensitive-paths.ts +92 -92
  217. package/src/runtime/session-usage.ts +79 -79
  218. package/src/runtime/settings-store.ts +103 -0
  219. package/src/runtime/sidechain-output.ts +29 -29
  220. package/src/runtime/skill-instructions.ts +222 -222
  221. package/src/runtime/stale-reconciler.ts +198 -189
  222. package/src/runtime/streaming-output.ts +47 -0
  223. package/src/runtime/subagent-manager.ts +404 -400
  224. package/src/runtime/subprocess-tool-registry.ts +67 -67
  225. package/src/runtime/task-display.ts +38 -38
  226. package/src/runtime/task-graph-scheduler.ts +122 -122
  227. package/src/runtime/task-graph.ts +207 -207
  228. package/src/runtime/task-output-context.ts +177 -177
  229. package/src/runtime/task-packet.ts +93 -93
  230. package/src/runtime/task-quality.ts +207 -207
  231. package/src/runtime/task-runner/capabilities.ts +78 -78
  232. package/src/runtime/task-runner/live-executor.ts +131 -113
  233. package/src/runtime/task-runner/progress.ts +119 -119
  234. package/src/runtime/task-runner/prompt-builder.ts +139 -139
  235. package/src/runtime/task-runner/prompt-pipeline.ts +64 -64
  236. package/src/runtime/task-runner/result-utils.ts +14 -14
  237. package/src/runtime/task-runner/run-projection.ts +103 -103
  238. package/src/runtime/task-runner/state-helpers.ts +22 -22
  239. package/src/runtime/task-runner.ts +469 -459
  240. package/src/runtime/team-runner.ts +693 -945
  241. package/src/runtime/usage-tracker.ts +71 -0
  242. package/src/runtime/worker-heartbeat.ts +21 -21
  243. package/src/runtime/worker-startup.ts +57 -57
  244. package/src/runtime/workflow-state.ts +187 -187
  245. package/src/runtime/yield-handler.ts +190 -190
  246. package/src/schema/config-schema.ts +172 -168
  247. package/src/schema/team-tool-schema.ts +126 -126
  248. package/src/schema/validation-types.ts +151 -148
  249. package/src/skills/discover-skills.ts +67 -67
  250. package/src/skills/skill-templates.ts +374 -374
  251. package/src/state/active-run-registry.ts +227 -191
  252. package/src/state/artifact-store.ts +130 -129
  253. package/src/state/atomic-write.ts +262 -195
  254. package/src/state/blob-store.ts +116 -116
  255. package/src/state/contracts.ts +111 -111
  256. package/src/state/event-log-rotation.ts +161 -158
  257. package/src/state/event-log.ts +383 -303
  258. package/src/state/event-reconstructor.ts +217 -217
  259. package/src/state/jsonl-writer.ts +82 -82
  260. package/src/state/locks.ts +146 -146
  261. package/src/state/mailbox.ts +446 -405
  262. package/src/state/state-store.ts +364 -351
  263. package/src/state/task-claims.ts +44 -44
  264. package/src/state/types.ts +285 -285
  265. package/src/state/usage.ts +29 -29
  266. package/src/subagents/async-entry.ts +1 -1
  267. package/src/subagents/index.ts +3 -3
  268. package/src/subagents/live/control.ts +1 -1
  269. package/src/subagents/live/manager.ts +1 -1
  270. package/src/subagents/live/realtime.ts +1 -1
  271. package/src/subagents/live/session-runtime.ts +1 -1
  272. package/src/subagents/manager.ts +1 -1
  273. package/src/subagents/spawn.ts +1 -1
  274. package/src/teams/discover-teams.ts +116 -116
  275. package/src/teams/team-config.ts +27 -27
  276. package/src/teams/team-serializer.ts +38 -38
  277. package/src/types/diff.d.ts +18 -18
  278. package/src/ui/agent-management-overlay.ts +144 -144
  279. package/src/ui/crew-widget.ts +487 -370
  280. package/src/ui/dashboard-panes/agents-pane.ts +109 -28
  281. package/src/ui/dashboard-panes/cancellation-pane.ts +42 -42
  282. package/src/ui/dashboard-panes/capability-pane.ts +59 -59
  283. package/src/ui/dashboard-panes/health-pane.ts +30 -30
  284. package/src/ui/dashboard-panes/mailbox-pane.ts +35 -35
  285. package/src/ui/dashboard-panes/progress-pane.ts +30 -30
  286. package/src/ui/dashboard-panes/transcript-pane.ts +10 -10
  287. package/src/ui/heartbeat-aggregator.ts +63 -63
  288. package/src/ui/keybinding-map.ts +97 -94
  289. package/src/ui/live-conversation-overlay.ts +152 -0
  290. package/src/ui/live-run-sidebar.ts +180 -180
  291. package/src/ui/mascot.ts +442 -442
  292. package/src/ui/overlays/agent-picker-overlay.ts +57 -57
  293. package/src/ui/overlays/confirm-overlay.ts +58 -58
  294. package/src/ui/overlays/mailbox-compose-overlay.ts +144 -144
  295. package/src/ui/overlays/mailbox-compose-preview.ts +63 -63
  296. package/src/ui/overlays/mailbox-detail-overlay.ts +122 -122
  297. package/src/ui/pi-ui-compat.ts +57 -57
  298. package/src/ui/powerbar-publisher.ts +221 -197
  299. package/src/ui/render-scheduler.ts +216 -143
  300. package/src/ui/run-action-dispatcher.ts +118 -118
  301. package/src/ui/run-dashboard.ts +526 -464
  302. package/src/ui/run-event-bus.ts +208 -208
  303. package/src/ui/run-snapshot-cache.ts +826 -777
  304. package/src/ui/settings-overlay.ts +721 -0
  305. package/src/ui/snapshot-types.ts +86 -70
  306. package/src/ui/theme-adapter.ts +190 -190
  307. package/src/ui/tool-progress-formatter.ts +89 -0
  308. package/src/ui/transcript-cache.ts +94 -94
  309. package/src/ui/transcript-viewer.ts +335 -335
  310. package/src/utils/conflict-detect.ts +662 -0
  311. package/src/utils/file-coalescer.ts +86 -86
  312. package/src/utils/frontmatter.ts +68 -68
  313. package/src/utils/fs-watch.ts +88 -31
  314. package/src/utils/gh-protocol.ts +479 -0
  315. package/src/utils/ids.ts +17 -17
  316. package/src/utils/incremental-reader.ts +104 -104
  317. package/src/utils/internal-error.ts +6 -6
  318. package/src/utils/names.ts +27 -27
  319. package/src/utils/paths.ts +102 -63
  320. package/src/utils/redaction.ts +44 -44
  321. package/src/utils/safe-paths.ts +47 -47
  322. package/src/utils/scan-cache.ts +136 -136
  323. package/src/utils/sse-parser.ts +134 -134
  324. package/src/utils/task-name-generator.ts +337 -337
  325. package/src/utils/timings.ts +33 -33
  326. package/src/utils/visual.ts +243 -198
  327. package/src/workflows/discover-workflows.ts +139 -139
  328. package/src/workflows/validate-workflow.ts +40 -40
  329. package/src/workflows/workflow-config.ts +26 -26
  330. package/src/workflows/workflow-serializer.ts +32 -32
  331. package/src/worktree/branch-freshness.ts +45 -45
  332. package/src/worktree/cleanup.ts +75 -75
  333. package/src/worktree/worktree-manager.ts +188 -188
  334. package/teams/default.team.md +12 -12
  335. package/teams/fast-fix.team.md +11 -11
  336. package/teams/implementation.team.md +18 -18
  337. package/teams/parallel-research.team.md +14 -14
  338. package/teams/research.team.md +11 -11
  339. package/teams/review.team.md +12 -12
  340. package/tsconfig.json +19 -19
  341. package/workflows/default.workflow.md +30 -30
  342. package/workflows/fast-fix.workflow.md +23 -23
  343. package/workflows/implementation.workflow.md +43 -43
  344. package/workflows/parallel-research.workflow.md +46 -46
  345. package/workflows/research.workflow.md +22 -22
  346. package/workflows/review.workflow.md +30 -30
  347. package/skills/task-packet/SKILL.md +0 -28
  348. package/skills/verify-evidence/SKILL.md +0 -27
@@ -5,36 +5,317 @@ description: Interactive waiting-task and mailbox workflow. Use when implementin
5
5
 
6
6
  # mailbox-interactive
7
7
 
8
- Use this skill for live coordination between leader and workers.
8
+ Use this skill for live coordination between leader and workers. Mailbox provides an asynchronous message protocol for steer, follow-up, respond, and nudge operations.
9
9
 
10
- ## Source patterns distilled
10
+ ## Mailbox Architecture
11
11
 
12
- - pi-subagents intercom/contact supervisor: blocking decisions vs non-blocking progress updates
13
- - pi-crew mailbox: `src/state/mailbox.ts`, `src/extension/team-tool/respond.ts`, `src/extension/team-tool/api.ts`, `src/ui/overlays/mailbox-detail-overlay.ts`, `src/ui/run-action-dispatcher.ts`
14
- - Waiting state: `src/state/contracts.ts`, `src/runtime/supervisor-contact.ts`, `src/ui/status-colors.ts`
12
+ ```
13
+ Worker (waiting) mailbox inbox Leader (respond)
14
+ Worker (running) mailbox follow-ups ← Leader (followUp)
15
+ Leader → Worker: steer, followUp, nudge (non-blocking)
16
+ Worker → Leader: supervisor contact (blocking decision)
17
+ ```
18
+
19
+ ### Mailbox file structure
20
+
21
+ Each run has a mailbox directory at `.crew/state/runs/<runId>/mailbox/`:
22
+ - `inbox.jsonl` — incoming messages (to worker)
23
+ - `outbox.jsonl` — sent messages (from worker)
24
+ - `steering.jsonl` — steer messages specifically
25
+
26
+ ### Message structure
27
+
28
+ ```typescript
29
+ interface MailboxMessage {
30
+ id: string;
31
+ direction: "inbox" | "outbox";
32
+ from: string; // taskId or "leader"
33
+ to: string; // taskId or "leader"
34
+ body: string; // message text
35
+ status: "pending" | "delivered" | "acknowledged" | "rejected";
36
+ priority: "low" | "normal" | "high";
37
+ sentAt: string; // ISO timestamp
38
+ deliveredAt?: string;
39
+ data?: Record<string, unknown>; // source, correlation, etc.
40
+ }
41
+ ```
42
+
43
+ ## Core Operations
44
+
45
+ ### 1. respond — Leader responds to waiting worker
46
+
47
+ ```typescript
48
+ // Respond writes to inbox and transitions task back to running
49
+ async function respond(runId: string, taskId: string, body: string, priority = "normal") {
50
+ // 1. Write inbox message
51
+ const message = appendInboxMessage(manifest, { taskId, body, priority });
52
+
53
+ // 2. Re-read state inside lock
54
+ const { tasks } = loadRunManifestById(cwd, runId);
55
+ const task = tasks.find(t => t.id === taskId);
56
+
57
+ // 3. Verify task is waiting
58
+ if (task.status !== "waiting") {
59
+ throw new Error(`Cannot respond to non-waiting task: ${task.status}`);
60
+ }
61
+
62
+ // 4. Transition task back to running
63
+ const updated = { ...task, status: "running", waitingSince: undefined };
64
+ saveRunTasks(manifest, [updated]);
65
+
66
+ // 5. Emit event
67
+ appendEvent(eventsPath, { type: "task.responded", taskId, message: body });
68
+
69
+ return message;
70
+ }
71
+ ```
72
+
73
+ ### 2. steer — Live agent steering (non-blocking)
74
+
75
+ ```typescript
76
+ // Steer sends a message to a running live agent
77
+ async function steerLiveAgent(agentId: string, message: string) {
78
+ const handle = getLiveAgent(agentId);
79
+ if (!handle) throw new Error(`Live agent '${agentId}' not found`);
80
+
81
+ // If session.steer is available, deliver immediately
82
+ if (typeof handle.session.steer === "function") {
83
+ await handle.session.steer(message);
84
+ handle.updatedAt = new Date().toISOString();
85
+ return handle;
86
+ }
87
+
88
+ // Otherwise, queue for delivery when session becomes ready
89
+ handle.pendingSteers.push(message);
90
+ return handle;
91
+ }
92
+ ```
93
+
94
+ ### 3. followUp — Non-blocking follow-up to running agent
95
+
96
+ ```typescript
97
+ async function followUpLiveAgent(agentId: string, prompt: string) {
98
+ const handle = getLiveAgent(agentId);
99
+ if (!handle) throw new Error(`Live agent '${agentId}' not found`);
100
+
101
+ if (typeof handle.session.prompt === "function") {
102
+ await handle.session.prompt(prompt, { source: "api", expandPromptTemplates: false });
103
+ handle.updatedAt = new Date().toISOString();
104
+ return handle;
105
+ }
106
+
107
+ handle.pendingFollowUps.push(prompt);
108
+ return handle;
109
+ }
110
+ ```
111
+
112
+ ### 4. nudge — Ask agent to report status
113
+
114
+ ```typescript
115
+ function nudgeAgent(manifest: TeamRunManifest, agentId: string, message?: string) {
116
+ const agent = readCrewAgents(manifest).find(a => a.id === agentId || a.taskId === agentId);
117
+ if (!agent) throw new Error(`Agent '${agentId}' not found`);
118
+
119
+ const text = message ?? "Please report your current status, blocker, or smallest next step.";
120
+
121
+ // Write to mailbox
122
+ const mailboxMessage = appendSteeringMessage(manifest, {
123
+ taskId: agent.taskId,
124
+ body: text,
125
+ priority: "normal",
126
+ data: { source: "nudge-agent" }
127
+ });
128
+
129
+ // Emit event
130
+ appendEvent(manifest.eventsPath, {
131
+ type: "agent.nudged",
132
+ runId: manifest.runId,
133
+ taskId: agent.taskId,
134
+ message: text,
135
+ data: { agentId: agent.id, mailboxMessageId: mailboxMessage.id }
136
+ });
137
+
138
+ return mailboxMessage;
139
+ }
140
+ ```
141
+
142
+ ## Supervisor Contact
143
+
144
+ Workers can contact the leader for blocking decisions:
145
+
146
+ ```typescript
147
+ // Worker stdout contains supervisor contact pattern:
148
+ // @supervisor need_confirmation: <decision-type>
149
+ // @supervisor need_input: <input-prompt>
150
+
151
+ // Parsed by parseSupervisorContactFromLine() in supervisor-contact.ts
152
+ function parseSupervisorContact(line: string): SupervisorContact | null {
153
+ const match = line.match(/@supervisor\s+(\w+):\s*(.*)/);
154
+ if (!match) return null;
155
+ return { type: match[1], prompt: match[2] };
156
+ }
157
+
158
+ // Recorded as events and surfaced in UI
159
+ appendEvent(eventsPath, {
160
+ type: "supervisor.contact",
161
+ runId: manifest.runId,
162
+ taskId: task.id,
163
+ message: contact.prompt,
164
+ data: { contactType: contact.type }
165
+ });
166
+ ```
167
+
168
+ **Contact types:**
169
+ - `need_confirmation` — worker needs explicit approval
170
+ - `need_input` — worker needs a text response
171
+ - `need_selection` — worker needs to choose from options
172
+
173
+ ## Queue Depth and Backpressure
174
+
175
+ Mailbox queues can grow large with pending messages:
176
+
177
+ ```typescript
178
+ const MAX_PENDING_STEERS = 50;
179
+ const MAX_PENDING_FOLLOWUPS = 50;
180
+
181
+ // When queue exceeds limit, oldest messages are dropped
182
+ if (handle.pendingSteers.length >= MAX_PENDING_STEERS) {
183
+ handle.pendingSteers.shift(); // drop oldest
184
+ }
185
+ ```
186
+
187
+ **Backpressure signals:**
188
+ - If `pendingSteers.length > 20`, warn in UI
189
+ - If `pendingFollowUps.length > 20`, warn in UI
190
+
191
+ ## Corrupt JSONL Handling
192
+
193
+ Mailbox JSONL files can become corrupt on crash. Handle gracefully:
194
+
195
+ ```typescript
196
+ function readMailboxMessages(path: string): MailboxMessage[] {
197
+ if (!fs.existsSync(path)) return [];
198
+
199
+ const lines = fs.readFileSync(path, "utf-8").split("\n");
200
+ const messages: MailboxMessage[] = [];
201
+
202
+ for (const line of lines) {
203
+ if (!line.trim()) continue;
204
+ try {
205
+ messages.push(JSON.parse(line) as MailboxMessage);
206
+ } catch {
207
+ // Skip corrupt lines: partial write from crash
208
+ // Try to recover by reading up to the last valid JSON object
209
+ continue;
210
+ }
211
+ }
212
+
213
+ return messages;
214
+ }
215
+ ```
216
+
217
+ ## Timeout Patterns
218
+
219
+ ### Responding with timeout
220
+
221
+ ```typescript
222
+ async function respondWithTimeout(
223
+ runId: string,
224
+ taskId: string,
225
+ body: string,
226
+ timeoutMs = 30_000
227
+ ): Promise<MailboxMessage> {
228
+ const controller = new AbortController();
229
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
230
+
231
+ try {
232
+ const message = await respond(runId, taskId, body);
233
+ clearTimeout(timeout);
234
+ return message;
235
+ } catch (error) {
236
+ clearTimeout(timeout);
237
+ if (error.name === "AbortError") {
238
+ throw new Error(`Respond timed out after ${timeoutMs}ms`);
239
+ }
240
+ throw error;
241
+ }
242
+ }
243
+ ```
244
+
245
+ ### Non-blocking follow-up (no wait)
246
+
247
+ ```typescript
248
+ // Fire-and-forget: send message and return immediately
249
+ function followUpAsync(agentId: string, prompt: string): void {
250
+ const handle = getLiveAgent(agentId);
251
+ if (!handle) return;
252
+
253
+ if (typeof handle.session.prompt === "function") {
254
+ // Non-awaited: delivery happens in background
255
+ void handle.session.prompt(prompt, { source: "api", expandPromptTemplates: false })
256
+ .catch(() => { /* log if needed */ });
257
+ } else {
258
+ handle.pendingFollowUps.push(prompt);
259
+ }
260
+ }
261
+ ```
15
262
 
16
- ## Rules
263
+ ## Run Ownership Enforcement
17
264
 
18
- - Use `waiting` when a task needs leader input and can safely pause.
19
- - `respond` should write an inbox mailbox message and transition target waiting tasks back to `running`.
20
- - Mutating mailbox actions must use run locks and re-read state inside the lock.
21
- - Respect run ownership: foreign sessions cannot respond/resume owned waiting tasks.
22
- - Mailbox reads should be contained under run state and tolerate missing/empty JSONL files.
23
- - Acknowledge/read actions are UI/operator state; preserve message history rather than deleting records.
24
- - Supervisor contact parsed from child stdout should be recorded as events and surfaced in UI without blocking render paths.
265
+ Foreign sessions cannot mutate a run's mailbox:
266
+
267
+ ```typescript
268
+ // In respond.ts / cancel.ts
269
+ function verifyRunOwnership(manifest: TeamRunManifest, sessionId: string, force = false) {
270
+ if (!force && manifest.ownerSessionId && manifest.ownerSessionId !== sessionId) {
271
+ throw new Error(
272
+ `Run ${manifest.runId} is owned by session ${manifest.ownerSessionId}. ` +
273
+ `Cannot mutate from session ${sessionId}. Use force=true to override.`
274
+ );
275
+ }
276
+ }
277
+ ```
25
278
 
26
279
  ## Anti-patterns
27
280
 
28
- - Resuming non-waiting tasks via `respond`.
29
- - Injecting mailbox messages into a foreign owned run.
30
- - Treating every progress update as a blocking supervisor decision.
31
- - Reading large mailbox files synchronously in hot render paths.
281
+ - **Resuming non-waiting tasks**: `respond` only works on `waiting` tasks. Resuming `running` tasks corrupts state.
282
+ - **Injecting mailbox messages into foreign runs**: Always verify `ownerSessionId` before mutating.
283
+ - **Treating every progress update as blocking**: Use `followUp` (non-blocking) instead of `respond` for status updates.
284
+ - **Reading large mailbox files in hot paths**: Cache mailbox counts; don't read JSONL on every render tick.
285
+ - **Not handling corrupt JSONL**: Skip malformed lines; don't fail the whole read.
286
+ - **Losing pending messages on session switch**: Pending steers/followups are stored in-memory in the handle. They survive session fork but not session death.
287
+
288
+ ---
289
+
290
+ ## Source patterns
291
+
292
+ - `src/state/mailbox.ts` — appendInboxMessage, appendSteeringMessage, readMailboxMessages
293
+ - `src/extension/team-tool/respond.ts` — respond tool handler, ownership verification
294
+ - `src/extension/team-tool/cancel.ts` — cancel with mailbox cleanup
295
+ - `src/extension/team-tool/api.ts` — steer-agent, follow-up-agent, nudge-agent
296
+ - `src/runtime/live-agent-manager.ts` — pendingSteers, pendingFollowUps, steerLiveAgent, followUpLiveAgent
297
+ - `src/runtime/supervisor-contact.ts` — parseSupervisorContactFromLine, recordSupervisorContact
298
+ - `src/ui/overlays/mailbox-detail-overlay.ts` — mailbox UI
299
+
300
+ ---
32
301
 
33
302
  ## Verification
34
303
 
35
304
  ```bash
36
305
  cd pi-crew
306
+
307
+ # Verify mailbox structure
308
+ ls .crew/state/runs/<runId>/mailbox/ 2>/dev/null || echo "No mailbox yet"
309
+
310
+ # Test respond tool
311
+ node --experimental-strip-types --test test/unit/respond-tool.test.ts
312
+
313
+ # Test mailbox overlay
314
+ node --experimental-strip-types --test test/unit/mailbox-detail-overlay.test.ts
315
+
316
+ # TypeScript
37
317
  npx tsc --noEmit
38
- node --experimental-strip-types --test test/unit/respond-tool.test.ts test/unit/mailbox-detail-overlay.test.ts test/unit/mailbox-compose-overlay.test.ts test/unit/supervisor-contact.test.ts
318
+
319
+ # All tests
39
320
  npm test
40
- ```
321
+ ```
@@ -29,6 +29,100 @@ Use this skill when working on model/context propagation.
29
29
  - Passing full session transcripts to every child by default.
30
30
  - Losing thinking level or model changes across session switch/fork flows.
31
31
 
32
+ ## Worked Examples
33
+
34
+ ### Model precedence chain with all fields
35
+
36
+ When every level provides a model:
37
+
38
+ ```typescript
39
+ // Requested by user/tool: "sonnet-4-2025-01-16"
40
+ // Step model (workflow): undefined
41
+ // Team role model: undefined
42
+ // Agent model: "haiku-4"
43
+ // Parent model: "sonnet-4-2025-01-16"
44
+ // Model registry: { default: "claude-sonnet-4" }
45
+
46
+ const result = buildConfiguredModelRouting({
47
+ overrideModel: "sonnet-4-2025-01-16", // tool override wins
48
+ stepModel: undefined,
49
+ teamRoleModel: undefined,
50
+ agentModel: "haiku-4",
51
+ fallbackModels: ["haiku-3"],
52
+ parentModel: "sonnet-4-2025-01-16",
53
+ modelRegistry: { default: "claude-sonnet-4" },
54
+ cwd,
55
+ });
56
+
57
+ // Result: candidates = ["sonnet-4-2025-01-16"]
58
+ // resolved = "sonnet-4-2025-01-16" (override wins)
59
+ // reason = "tool override"
60
+ ```
61
+
62
+ ### Override at each level
63
+
64
+ ```typescript
65
+ // Level 1: tool override (highest)
66
+ buildConfiguredModelRouting({ overrideModel: "sonnet-4-2025-01-16" });
67
+ // → candidates = ["sonnet-4-2025-01-16"]
68
+
69
+ // Level 2: step model
70
+ buildConfiguredModelRouting({ overrideModel: undefined, stepModel: "haiku-4" });
71
+ // → candidates = ["haiku-4"]
72
+
73
+ // Level 3: team role model
74
+ buildConfiguredModelRouting({ overrideModel: undefined, stepModel: undefined, teamRoleModel: "sonnet-3.5" });
75
+ // → candidates = ["sonnet-3.5"]
76
+
77
+ // Level 4: agent model with fallback
78
+ buildConfiguredModelRouting({ overrideModel: undefined, stepModel: undefined, teamRoleModel: undefined, agentModel: "haiku-3", fallbackModels: ["claude-3-5-haiku-20241022"] });
79
+ // → candidates = ["haiku-3", "claude-3-5-haiku-20241022"]
80
+ ```
81
+
82
+ ### Empty/whitespace/null handling
83
+
84
+ ```typescript
85
+ // Empty string treated as absent
86
+ buildConfiguredModelRouting({ agentModel: "" });
87
+ // → agentModel ignored, falls through to parent
88
+
89
+ // Whitespace treated as absent
90
+ buildConfiguredModelRouting({ agentModel: " " });
91
+ // → agentModel ignored
92
+
93
+ // null/undefined treated as absent
94
+ buildConfiguredModelRouting({ agentModel: undefined });
95
+ // → agentModel ignored
96
+
97
+ // With thinking level suffix
98
+ applyThinkingSuffix("sonnet-4-2025-01-16", "medium")
99
+ // → "sonnet-4-2025-01-16:medium"
100
+
101
+ // Invalid thinking level falls back to model without suffix
102
+ applyThinkingSuffix("sonnet-4-2025-01-16", "invalid")
103
+ // → "sonnet-4-2025-01-16" (suffix ignored)
104
+ ```
105
+
106
+ ## Common Mistakes
107
+
108
+ 1. **Empty string blocking parent fallback**:
109
+ ```typescript
110
+ // ❌ agentModel: "" blocks parent fallback
111
+ buildConfiguredModelRouting({ agentModel: "" });
112
+
113
+ // ✅ Empty string treated as absent
114
+ buildConfiguredModelRouting({ agentModel: undefined });
115
+ ```
116
+
117
+ 2. **Losing thinking level on session switch**:
118
+ ```typescript
119
+ // ❌ Thinking level not persisted in config
120
+ const config = { model: "sonnet-4" }; // no thinking
121
+
122
+ // ✅ Thinking level in model suffix
123
+ const config = { model: "sonnet-4:medium" };
124
+ ```
125
+
32
126
  ## Verification
33
127
 
34
128
  ```bash
@@ -39,6 +39,94 @@ Severity:
39
39
  - medium: important regression, flaky test, confusing recoverable behavior;
40
40
  - low: polish, maintainability, docs.
41
41
 
42
+ ## Example Findings by Perspective
43
+
44
+ ### Spec Compliance
45
+
46
+ ```
47
+ [medium] src/runtime/task-runner.ts:89
48
+ Issue: `executeWorkers` is checked once at top of runTeamTask but the value
49
+ is passed through an untyped parameter. The function comment says "workers
50
+ are disabled in scaffold mode" but the actual behavior is driven by `runtimeKind`.
51
+ Impact: If someone changes the comment but not the code, the mismatch is invisible.
52
+ Fix: Add a runtimeKind guard and deprecate the executeWorkers parameter.
53
+ Verification: `npx tsc --noEmit` passes; test with `PI_TEAMS_MOCK_CHILD_PI=scaffold`.
54
+ ```
55
+
56
+ ### Correctness
57
+
58
+ ```
59
+ [high] src/runtime/live-agent-manager.ts:47
60
+ Issue: `registerLiveAgent` returns the new handle but callers may use the
61
+ old handle reference if they captured it before the call.
62
+ Impact: Status updates may apply to the wrong handle if the agent re-registers.
63
+ Fix: Always call `getLiveAgent` after `registerLiveAgent` to get the canonical handle.
64
+ Verification: Add test that verifies status after re-registration.
65
+ ```
66
+
67
+ ### Regression Risk
68
+
69
+ ```
70
+ [medium] src/state/state-store.ts:150
71
+ Issue: `saveRunTasks` uses `atomicWriteJson` but the file may grow large.
72
+ No pagination or archiving strategy for long-running runs.
73
+ Impact: Tasks file could exceed 10MB with many updates, causing slow I/O.
74
+ Fix: Consider splitting into per-task files or adding a size warning.
75
+ Verification: Load test with 10,000 task updates.
76
+ ```
77
+
78
+ ### Security
79
+
80
+ ```
81
+ [critical] src/utils/safe-paths.ts:20
82
+ Issue: `resolveRealContainedPath` follows symlinks but doesn't verify the
83
+ resolved path stays under the allowed base.
84
+ Impact: A malicious symlink could escape the workspace boundary.
85
+ Fix: Compare resolved path against allowed base after following symlinks.
86
+ Verification: Unit test with malicious symlink pointing outside workspace.
87
+ ```
88
+
89
+ ### Tests
90
+
91
+ ```
92
+ [medium] test/unit/live-agent-manager.test.ts:45
93
+ Issue: Test only checks the happy path. Missing: re-registration, workspaceId
94
+ mismatch, evict on timeout, cross-workspace access prevention.
95
+ Impact: Edge cases are not covered; future changes could break silently.
96
+ Fix: Add tests for re-registration, cross-workspace rejection, stale eviction.
97
+ Verification: `npm test` with new test cases.
98
+ ```
99
+
100
+ ### Maintainability
101
+
102
+ ```
103
+ [low] src/runtime/task-runner.ts:250
104
+ Issue: `runTeamTask` is 400+ lines with deeply nested if/else. Hard to follow.
105
+ Impact: Future changes require understanding all branches simultaneously.
106
+ Fix: Extract inner logic into helper functions (spawn, execute, complete).
107
+ Verification: No functional change; `npx tsc --noEmit` passes.
108
+ ```
109
+
110
+ ### Operator Experience
111
+
112
+ ```
113
+ [medium] src/extension/team-tool/api.ts:80
114
+ Issue: Error message for missing `agentId` doesn't show available agent IDs.
115
+ Impact: Operator must manually look up agent IDs to fix the error.
116
+ Fix: Include list of available agent IDs in the error message.
117
+ Verification: Call steer-agent without agentId and verify error lists IDs.
118
+ ```
119
+
120
+ ### Compatibility
121
+
122
+ ```
123
+ [high] src/runtime/child-pi.ts:45
124
+ Issue: `spawn("cmd", ["/c", ...])` on Windows fails with `&&` in commands.
125
+ Impact: Background runs with multiple commands silently fail on Windows.
126
+ Fix: Use explicit argv array instead of shell string concatenation.
127
+ Verification: Test background run with multiple commands on Windows.
128
+ ```
129
+
42
130
  ## Handling Review Feedback
43
131
 
44
132
  When receiving feedback: