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
@@ -0,0 +1,508 @@
1
+ # pi-subagents3 Deep Analysis — Patterns for pi-crew In-Process Runtime
2
+
3
+ ## Executive Summary
4
+
5
+ After deep reading of `source/pi-subagents3/`, this document catalogs every production-ready pattern that pi-crew should adopt for its in-process (live-session) runtime. pi-subagents3 is a mature single-agent system with many features pi-crew's team orchestration currently lacks.
6
+
7
+ ---
8
+
9
+ ## 1. Promise-Based Agent Lifecycle ✅ DONE
10
+
11
+ ### pi-subagents3 Pattern
12
+ ```typescript
13
+ class AgentManager {
14
+ spawn(...) {
15
+ const record = { ... };
16
+ record.promise = runAgent(...).then(...);
17
+ return id;
18
+ }
19
+ async spawnAndWait(...) {
20
+ const id = this.spawn(...);
21
+ const record = this.agents.get(id)!;
22
+ await record.promise; // ← Await actual completion
23
+ return record;
24
+ }
25
+ async waitForAll() {
26
+ while (true) {
27
+ const pending = [...this.agents.values()]
28
+ .filter(r => r.status === "running" || r.status === "queued")
29
+ .map(r => r.promise);
30
+ if (pending.length === 0) break;
31
+ await Promise.allSettled(pending);
32
+ }
33
+ }
34
+ }
35
+ ```
36
+
37
+ ### pi-crew Implementation
38
+ **Status:** Done in `src/runtime/run-tracker.ts` (`a88e552`)
39
+ - `registerRunPromise()`, `resolveRunPromise()`, `waitForRun()`
40
+ - Fast path (disk terminal), medium path (foreground Promise), fallback (exponential backoff poll)
41
+
42
+ ---
43
+
44
+ ## 2. Soft Turn Limit + Graceful Steering ⬜ NOT IN PI-CREW
45
+
46
+ ### pi-subagents3 Pattern
47
+ ```typescript
48
+ let turnCount = 0;
49
+ const maxTurns = normalizeMaxTurns(options.maxTurns ?? agentConfig?.maxTurns ?? defaultMaxTurns);
50
+ let softLimitReached = false;
51
+ let aborted = false;
52
+
53
+ session.subscribe((event) => {
54
+ if (event.type === "turn_end") {
55
+ turnCount++;
56
+ if (maxTurns != null) {
57
+ if (!softLimitReached && turnCount >= maxTurns) {
58
+ softLimitReached = true;
59
+ session.steer("You have reached your turn limit. Wrap up immediately — provide your final answer now.");
60
+ } else if (softLimitReached && turnCount >= maxTurns + graceTurns) {
61
+ aborted = true;
62
+ session.abort();
63
+ }
64
+ }
65
+ }
66
+ });
67
+ ```
68
+
69
+ **Key insight:** Instead of hard cutoff, it steers the agent to wrap up. Only aborts after `graceTurns` (default 5) additional turns. This produces much better output than sudden termination.
70
+
71
+ **Settings:** `defaultMaxTurns`, `graceTurns` — persisted per project.
72
+
73
+ ### pi-crew Gap
74
+ - `maxTurns` exists but no soft-limit steering mechanism
75
+ - No `graceTurns` concept
76
+ - Hard abort at maxTurns causes incomplete responses
77
+
78
+ ### Implementation Sketch
79
+ Add to `live-session-runtime.ts`:
80
+ ```typescript
81
+ const turnCount = 0;
82
+ const maxTurns = agent.maxTurns ?? config.defaultMaxTurns;
83
+ const graceTurns = config.graceTurns ?? 5;
84
+ let softLimitReached = false;
85
+
86
+ session.subscribe((event) => {
87
+ if (event.type === "turn_end") {
88
+ turnCount++;
89
+ if (maxTurns != null && !softLimitReached && turnCount >= maxTurns) {
90
+ softLimitReached = true;
91
+ session.steer("You have reached your turn limit. Wrap up immediately — provide your final answer now.");
92
+ } else if (softLimitReached && turnCount >= maxTurns + graceTurns) {
93
+ session.abort();
94
+ }
95
+ }
96
+ });
97
+ ```
98
+
99
+ ---
100
+
101
+ ## 3. Persistent Agent Memory ⬜ NOT IN PI-CREW
102
+
103
+ ### pi-subagents3 Pattern
104
+ ```typescript
105
+ // Memory scopes: "user" | "project" | "local"
106
+ const memoryDir = resolveMemoryDir(agentName, scope, cwd);
107
+ // Agent gets a persistent directory and MEMORY.md instructions
108
+ // Agent can read/write/edit memory files using its tools
109
+ ```
110
+
111
+ **Memory block injected into system prompt:**
112
+ ```markdown
113
+ # Agent Memory
114
+ You have a persistent memory directory at: {memoryDir}/
115
+ Memory scope: {scope}
116
+ This memory persists across sessions. Use it to build up knowledge over time.
117
+ ```
118
+
119
+ **Features:**
120
+ - MEMORY.md index file (max 200 lines)
121
+ - Frontmatter format for structured memories
122
+ - Read-only mode for agents without write/edit tools
123
+ - Symlink attack prevention (`isSymlink`, `safeReadFile`)
124
+
125
+ ### pi-crew Gap
126
+ - No persistent memory per agent across runs
127
+ - Agents start fresh every time
128
+ - No MEMORY.md concept
129
+
130
+ ---
131
+
132
+ ## 4. Context % Indicator ⬜ NOT IN PI-CREW
133
+
134
+ ### pi-subagents3 Pattern
135
+ ```typescript
136
+ export function getSessionContextPercent(session: SessionLike | undefined): number | null {
137
+ if (!session) return null;
138
+ try { return session.getSessionStats().contextUsage?.percent ?? null; }
139
+ catch { return null; }
140
+ }
141
+ ```
142
+
143
+ **Used in:**
144
+ - Dashboard widget showing "Context: 67%" to warn before compaction
145
+ - Scheduling decisions (don't schedule if context is critically full)
146
+ - UI streaming display
147
+
148
+ ### pi-crew Gap
149
+ - No context usage percentage display
150
+ - No early warning before compaction
151
+ - Dashboard doesn't show "how full is the context window"
152
+
153
+ ---
154
+
155
+ ## 5. Skill Preloading (vs. Skill Path Passing) ⬜ PARTIAL IN PI-CREW
156
+
157
+ ### pi-subagents3 Pattern
158
+ ```typescript
159
+ // Load skill content INTO the prompt instead of passing paths to child
160
+ const loaded = preloadSkills(skills, effectiveCwd);
161
+ if (loaded.length > 0) {
162
+ extras.skillBlocks = loaded;
163
+ }
164
+
165
+ // In prompt:
166
+ // # Preloaded Skill: skill-name
167
+ // <skill content here>
168
+ ```
169
+
170
+ **Advantages over path passing:**
171
+ - No child-process skill loader dependency
172
+ - Content is visible to LLM immediately (no extra tool call)
173
+ - Works with `noSkills: true` (skills already in prompt)
174
+ - Graceful degradation: missing skills show "(Skill not found)" note instead of crash
175
+
176
+ ### pi-crew Gap
177
+ - pi-crew passes `--skill <path>` to child Pi process
178
+ - Child has to load skills separately
179
+ - For live-session, skills should be preloaded into prompt
180
+
181
+ ---
182
+
183
+ ## 6. Batch Notification Grouping (GroupJoinManager) ⬜ NOT IN PI-CREW
184
+
185
+ ### pi-subagents3 Pattern
186
+ ```typescript
187
+ class GroupJoinManager {
188
+ registerGroup(groupId, agentIds);
189
+ onAgentComplete(record) {
190
+ // Hold results until ALL agents in group complete
191
+ // OR timeout fires (default 30s)
192
+ // Then deliver ONE consolidated notification
193
+ }
194
+ }
195
+ ```
196
+
197
+ **Join modes:** `async` (individual), `group` (batch), `smart` (heuristic)
198
+
199
+ **Benefits:**
200
+ - 10 parallel research agents → 1 notification instead of 10
201
+ - Reduces parent context disruption
202
+ - Configurable timeout for stragglers
203
+
204
+ ### pi-crew Gap
205
+ - Each completed task sends individual notification
206
+ - No batch grouping for parallel tasks
207
+ - Parent gets spammed with completion messages
208
+
209
+ ---
210
+
211
+ ## 7. Scheduling (SubagentScheduler) ⬜ NOT IN PI-CREW
212
+
213
+ ### pi-subagents3 Pattern
214
+ ```typescript
215
+ class SubagentScheduler {
216
+ addJob({ name, schedule: "0 0 9 * * 1", subagent_type, prompt });
217
+ // Supports: cron | interval ("5m") | once ("+10m" | ISO)
218
+ // Persistence: session-scoped ScheduleStore with PID-locked atomic writes
219
+ // Bypasses concurrency queue when firing
220
+ }
221
+ ```
222
+
223
+ **Features:**
224
+ - Croner library for cron expressions
225
+ - Session-scoped persistence (survives `/resume`, resets on `/new`)
226
+ - PID-based file locking with stale lock detection
227
+ - Master switch: `schedulingEnabled` setting
228
+
229
+ ### pi-crew Gap
230
+ - No scheduling capability at all
231
+ - No cron/interval/once job support
232
+ - No session-scoped persistent job store
233
+
234
+ ---
235
+
236
+ ## 8. Settings Persistence with Sanitization ⬜ NOT IN PI-CREW
237
+
238
+ ### pi-subagents3 Pattern
239
+ ```typescript
240
+ // Global: ~/.pi/agent/subagents.json (defaults, never written here)
241
+ // Project: <cwd>/.pi/subagents.json (overrides)
242
+
243
+ export interface SubagentsSettings {
244
+ maxConcurrent?: number;
245
+ defaultMaxTurns?: number;
246
+ graceTurns?: number;
247
+ defaultJoinMode?: JoinMode;
248
+ schedulingEnabled?: boolean;
249
+ }
250
+
251
+ function sanitize(raw: unknown): SubagentsSettings {
252
+ // Drop invalid fields, apply ceilings
253
+ // maxConcurrent: 1-1024
254
+ // defaultMaxTurns: 0-10000 (0 = unlimited)
255
+ // graceTurns: 1-1000
256
+ }
257
+ ```
258
+
259
+ **Features:**
260
+ - Merged load: global defaults + project overrides
261
+ - Sanitization drops garbage silently
262
+ - Settings events: `subagents:settings_loaded`, `subagents:settings_changed`
263
+ - Toast formatting for persist success/failure
264
+
265
+ ### pi-crew Gap
266
+ - pi-crew has `CrewConfig` but no project-local `.pi/crew.json` persistence
267
+ - No sanitization with ceilings
268
+ - No settings change events
269
+
270
+ ---
271
+
272
+ ## 9. Usage Tracking (Survives Compaction) ⬜ NOT IN PI-CREW
273
+
274
+ ### pi-subagents3 Pattern
275
+ ```typescript
276
+ export type LifetimeUsage = { input: number; output: number; cacheWrite: number };
277
+
278
+ // Accumulated via message_end events (survives compaction)
279
+ session.subscribe((event) => {
280
+ if (event.type === "message_end" && event.message.role === "assistant") {
281
+ const u = event.message.usage;
282
+ if (u) options.onAssistantUsage?.({
283
+ input: u.input ?? 0,
284
+ output: u.output ?? 0,
285
+ cacheWrite: u.cacheWrite ?? 0,
286
+ });
287
+ }
288
+ });
289
+ ```
290
+
291
+ **Key design:** `getSessionTokens()` resets at compaction (upstream replaces messages array), but `LifetimeUsage` survives because it's independently accumulated.
292
+
293
+ **cacheRead deliberately excluded** — summing across turns counts the cached prefix N times (issue #38).
294
+
295
+ ### pi-crew Gap
296
+ - pi-crew tracks usage per task but doesn't survive compaction
297
+ - No lifetime usage across sessions
298
+ - No `cacheWrite`/`cacheRead` distinction logic
299
+
300
+ ---
301
+
302
+ ## 10. Worktree Isolation ⬜ NOT IN PI-CREW
303
+
304
+ ### pi-subagents3 Pattern
305
+ ```typescript
306
+ export function createWorktree(cwd: string, agentId: string): WorktreeInfo | undefined {
307
+ // git worktree add --detach <temp-path> HEAD
308
+ // Returns { path, branch }
309
+ }
310
+
311
+ export function cleanupWorktree(cwd, worktree, description) {
312
+ // No changes → remove worktree
313
+ // Changes → git add -A, git commit, create branch, remove worktree
314
+ // Returns { hasChanges, branch }
315
+ }
316
+ ```
317
+
318
+ **Features:**
319
+ - Strict: fails loud if not a git repo (no silent fallback)
320
+ - Crash recovery: `pruneWorktrees()` on dispose
321
+ - Branch naming: `pi-agent-{agentId}`, with timestamp suffix if conflict
322
+
323
+ ### pi-crew Gap
324
+ - pi-crew has worktree support but less robust
325
+ - No automatic branch creation for changes
326
+ - No worktree cleanup on error
327
+
328
+ ---
329
+
330
+ ## 11. Model Resolution (Fuzzy + Availability) ⬜ NOT IN PI-CREW
331
+
332
+ ### pi-subagents3 Pattern
333
+ ```typescript
334
+ export function resolveModel(input: string, registry: ModelRegistry): any | string {
335
+ // 1. Exact match "provider/modelId" — only if available (has auth)
336
+ // 2. Fuzzy match with scoring:
337
+ // - exact id match (100)
338
+ // - id contains query (60-90)
339
+ // - name contains query (40-60)
340
+ // - all parts present (20)
341
+ // 3. No match → return error message with available models list
342
+ }
343
+ ```
344
+
345
+ ### pi-crew Gap
346
+ - pi-crew passes model string directly to child Pi
347
+ - No fuzzy resolution
348
+ - No availability check before spawn
349
+
350
+ ---
351
+
352
+ ## 12. Agent Config System (Defaults + Override) ⬜ PARTIAL IN PI-CREW
353
+
354
+ ### pi-subagents3 Pattern
355
+ ```typescript
356
+ const DEFAULT_AGENTS = new Map([
357
+ ["general-purpose", { extensions: true, skills: true, promptMode: "append" }],
358
+ ["Explore", { builtinToolNames: ["read", "bash", "grep", "find", "ls"], model: "anthropic/claude-haiku-...", promptMode: "replace" }],
359
+ ["Plan", { builtinToolNames: ["read", "bash", "grep", "find", "ls"], promptMode: "replace" }],
360
+ ]);
361
+
362
+ // User-defined .md files with same name override defaults
363
+ // Resolution: explicit option > config.model > parent model
364
+ ```
365
+
366
+ **Features:**
367
+ - `builtinToolNames` — restrict tool set per agent type
368
+ - `disallowedTools` — denylist (removed even if extensions include them)
369
+ - `promptMode: "replace" | "append"` — full control vs. parent clone
370
+ - `extensions: true | string[] | false` — selective extension inheritance
371
+ - `skills: true | string[] | false` — selective skill inheritance
372
+ - `isolated: boolean` — no extension tools
373
+
374
+ ### pi-crew Gap
375
+ - pi-crew has agent configs but no `builtinToolNames` per agent
376
+ - No `disallowedTools` concept
377
+ - No `promptMode` (always append-ish)
378
+ - `extensions`/`skills` are boolean only (no selective)
379
+
380
+ ---
381
+
382
+ ## 13. Streaming Output (Real-Time Transcript) ⬜ NOT IN PI-CREW
383
+
384
+ ### pi-subagents3 Pattern
385
+ ```typescript
386
+ // AgentRecord has:
387
+ outputFile?: string;
388
+ outputCleanup?: () => void;
389
+
390
+ // In spawn:
391
+ const outputFile = path.join(stateDir, `${id}.output.md`);
392
+ const stream = createWriteStream(outputFile);
393
+ // Subscribe to session events, write text deltas to stream
394
+ // onComplete: flush stream, cleanup
395
+ ```
396
+
397
+ **Benefits:**
398
+ - Real-time transcript file for long-running agents
399
+ - Parent can `tail -f` the file for progress
400
+ - `outputCleanup` ensures stream is closed
401
+
402
+ ### pi-crew Gap
403
+ - pi-crew writes artifacts after task completes
404
+ - No real-time streaming transcript during task execution
405
+ - Parent must wait for completion to see output
406
+
407
+ ---
408
+
409
+ ## 14. Cross-Extension RPC ⬜ NOT IN PI-CREW
410
+
411
+ ### pi-subagents3 Pattern
412
+ ```typescript
413
+ export function registerRpcHandlers(deps: RpcDeps): RpcHandle {
414
+ const unsubPing = handleRpc(events, "subagents:rpc:ping", () => ({ version: PROTOCOL_VERSION }));
415
+ const unsubSpawn = handleRpc(events, "subagents:rpc:spawn", ({ type, prompt, options }) => {
416
+ const ctx = getCtx();
417
+ return { id: manager.spawn(pi, ctx, type, prompt, options ?? {}) };
418
+ });
419
+ const unsubStop = handleRpc(events, "subagents:rpc:stop", ({ agentId }) => {
420
+ if (!manager.abort(agentId)) throw new Error("Agent not found");
421
+ });
422
+ return { unsubPing, unsubSpawn, unsubStop };
423
+ }
424
+ ```
425
+
426
+ **Features:**
427
+ - Per-request scoped reply channels: `${channel}:reply:${requestId}`
428
+ - Envelope: `{ success: true, data? } | { success: false, error }`
429
+ - Protocol versioning
430
+
431
+ ### pi-crew Gap
432
+ - pi-crew has no RPC for external extensions to spawn team runs
433
+ - No protocol versioning
434
+ - Extensions can only use `team` tool
435
+
436
+ ---
437
+
438
+ ## 15. Concurrency Queue with Bypass ⬜ PARTIAL IN PI-CREW
439
+
440
+ ### pi-subagents3 Pattern
441
+ ```typescript
442
+ spawn(..., { isBackground: true, bypassQueue: false }) {
443
+ if (runningBackground >= maxConcurrent) {
444
+ record.status = "queued";
445
+ queue.push({ id, args });
446
+ return id;
447
+ }
448
+ startAgent(id, record, args);
449
+ }
450
+
451
+ // When agent completes:
452
+ this.runningBackground--;
453
+ this.drainQueue(); // Start next queued agent
454
+
455
+ // Scheduled jobs bypass queue:
456
+ manager.spawn(..., { bypassQueue: true }); // Always starts immediately
457
+ ```
458
+
459
+ ### pi-crew Status
460
+ - pi-crew has `SubagentManager` with `runningBackground` counter
461
+ - Has queue logic but no `bypassQueue` flag
462
+ - No `drainQueue()` — queued agents may not auto-start
463
+
464
+ ---
465
+
466
+ ## 16. Parent Signal Wiring ⬜ PARTIAL IN PI-CREW
467
+
468
+ ### pi-subagents3 Pattern
469
+ ```typescript
470
+ // In spawn:
471
+ if (options.signal) {
472
+ const onParentAbort = () => this.abort(id);
473
+ options.signal.addEventListener("abort", onParentAbort, { once: true });
474
+ detachParentSignal = () => options.signal!.removeEventListener("abort", onParentAbort);
475
+ }
476
+
477
+ // Cleanup in .then() and .catch():
478
+ detach(); // Remove listener to avoid leak
479
+ ```
480
+
481
+ ### pi-crew Status
482
+ - pi-crew passes `signal` to `runTeamTask` and `runLiveSessionTask`
483
+ - But no explicit detach cleanup after completion
484
+ - Listener may leak
485
+
486
+ ---
487
+
488
+ ## Priority Implementation Roadmap
489
+
490
+ ### P0 — Immediate (next commit)
491
+ 1. **Soft turn limit + grace steering** — Best output quality improvement
492
+ 2. **Context % indicator** — Dashboard enhancement, low effort
493
+
494
+ ### P1 — This Week
495
+ 3. **Skill preloading** — Required for live-session to work without child-process skill loader
496
+ 4. **Persistent agent memory** — Major differentiator, medium effort
497
+ 5. **Usage tracking (survives compaction)** — Metrics accuracy
498
+
499
+ ### P2 — Next Sprint
500
+ 6. **Batch notification grouping** — Parallel run UX
501
+ 7. **Settings persistence with sanitization** — Config robustness
502
+ 8. **Streaming output transcript** — Real-time progress visibility
503
+ 9. **Worktree auto-branch** — Isolation improvement
504
+
505
+ ### P3 — Future
506
+ 10. **Scheduling** — New feature category
507
+ 11. **Cross-extension RPC** — Ecosystem integration
508
+ 12. **Model fuzzy resolution** — UX polish
@@ -0,0 +1,31 @@
1
+ # Product Docs
2
+
3
+ Product documentation for pi-crew. Each file describes a product domain —
4
+ what it does, how it behaves, and what contracts it maintains.
5
+
6
+ ## Update Rule
7
+
8
+ When behavior changes:
9
+ 1. Update the affected product doc
10
+ 2. Update or create the story packet
11
+ 3. Update `docs/TEST_MATRIX.md`
12
+ 4. Record a decision if it affects architecture, scope, risk, or settled rules
13
+
14
+ ## Domain Index
15
+
16
+ | File | Domain | Description |
17
+ |------|--------|-------------|
18
+ | `team-run.md` | Core | Team run lifecycle: start, execute, complete |
19
+ | `team-tool.md` | API | Team tool actions: run, status, list, plan |
20
+ | `child-process.md` | Runtime | Child Pi process spawning and management |
21
+ | `live-session.md` | Runtime | In-process agent execution |
22
+ | `async-runner.md` | Runtime | Background/async run execution |
23
+ | `state.md` | State | Durable state: manifests, tasks, events |
24
+ | `worktree.md` | Isolation | Git worktree isolation for parallel work |
25
+ | `group-join.md` | Coordination | Agent result grouping and delivery |
26
+ | `model-fallback.md` | Runtime | Model selection and fallback chain |
27
+ | `conflict-detect.md` | Utils | Merge conflict detection in file edits |
28
+ | `crash-recovery.md` | Reliability | Crash recovery and stale reconciliation |
29
+ | `effectiveness.md` | Quality | Effectiveness guard for worker activity |
30
+ | `platform.md` | Platform | Cross-platform considerations (Windows) |
31
+ | `runtime-safety.md` | Safety | Runtime safety: depth guard, resource limits |
@@ -0,0 +1,27 @@
1
+ # Platform (Cross-Platform)
2
+
3
+ ## Behavior
4
+
5
+ pi-crew runs on Windows, macOS, and Linux. Primary development is on Windows.
6
+
7
+ ### Windows Considerations
8
+
9
+ - **EBUSY/EPERM**: Files locked by antivirus, shell, or indexer
10
+ - `rmSyncRetry()` with exponential backoff (50ms, 100ms, 200ms, 400ms)
11
+ - `existsSync` check before cleanup in finally blocks
12
+ - **Path separators**: Use `path.join()` everywhere, never hardcoded `/`
13
+ - **Shell**: `resolve-shell.ts` handles `cmd.exe` vs `bash` detection
14
+ - **Case sensitivity**: Windows is case-insensitive for file paths
15
+
16
+ ### Unix Considerations
17
+
18
+ - `unref()` on timers to prevent blocking process exit
19
+ - POSIX shell compatibility in any shell scripts
20
+ - Signal handling (SIGTERM, SIGINT) for graceful shutdown
21
+
22
+ ### CI Matrix
23
+
24
+ All changes validated on:
25
+ - `ubuntu-latest` / Node 22
26
+ - `windows-latest` / Node 22
27
+ - `macos-latest` / Node 22
@@ -0,0 +1,37 @@
1
+ # Runtime Safety
2
+
3
+ ## Behavior
4
+
5
+ pi-crew enforces multiple safety layers to prevent resource leaks, crashes,
6
+ and runaway execution.
7
+
8
+ ### Depth Guard
9
+
10
+ - Tracks `PI_CREW_SESSION_DEPTH` environment variable
11
+ - Depth >= 2 forces `child-process` mode instead of `live-session`
12
+ - Prevents stack overflow from nested team runs
13
+
14
+ ### Resource Limits
15
+
16
+ - Memory cap on live-session agents
17
+ - Prompt timeout for agent responses
18
+ - Tool count restoration after session error
19
+
20
+ ### Process Cleanup
21
+
22
+ - `cleanupTempDir()` with `existsSync` guard against double cleanup
23
+ - `safeDisposeLiveSession()` for clean resource teardown
24
+ - `removeLiveAgentHandle()` for registry cleanup
25
+
26
+ ### Error Handling
27
+
28
+ - `try/catch` around all I/O operations in UI code
29
+ - `rmSyncRetry()` with exponential backoff for Windows EBUSY
30
+ - `rejectRunPromise` (not `resolveRunPromise`) in error paths
31
+
32
+ ### State Integrity
33
+
34
+ - `withRunLockSync` for all state mutations
35
+ - Atomic write helpers (`writeJsonAtomic`, `appendJsonAtomic`)
36
+ - `markActiveTasksAndAgentsFailed()` for crash recovery
37
+ - Event log append-only for audit trail
@@ -0,0 +1,39 @@
1
+ # Team Run
2
+
3
+ ## Behavior
4
+
5
+ A team run executes a workflow with multiple agents, tracking progress through
6
+ durable state on disk.
7
+
8
+ ### Lifecycle
9
+
10
+ 1. User invokes `team action='run'` with a goal
11
+ 2. Team runner creates a manifest, resolves team/workflow
12
+ 3. Task graph is built from workflow steps
13
+ 4. Tasks execute (parallel or sequential per workflow)
14
+ 5. Results are collected, artifacts written
15
+ 6. Run completes with final status
16
+
17
+ ### Statuses
18
+
19
+ | Status | Meaning |
20
+ |--------|---------|
21
+ | pending | Manifest created, not yet executing |
22
+ | running | Tasks executing |
23
+ | completed | All tasks finished successfully |
24
+ | failed | One or more tasks failed |
25
+ | cancelled | User cancelled the run |
26
+ | partial | Some tasks completed, others still pending |
27
+
28
+ ### Concurrency
29
+
30
+ - Tasks without dependencies run in parallel (up to concurrency limit)
31
+ - Tasks with `dependsOn` wait for predecessors
32
+ - Workflow phases enforce ordering
33
+
34
+ ### Artifacts
35
+
36
+ - `results/{taskId}.txt` — task output
37
+ - `logs/{taskId}.log` — full transcript
38
+ - `metadata/` — task metadata files
39
+ - `shared/` — inter-agent shared context
@@ -0,0 +1,37 @@
1
+ # Team Tool API
2
+
3
+ ## Behavior
4
+
5
+ The `team` tool is the primary interface for users to interact with pi-crew.
6
+
7
+ ### Actions
8
+
9
+ | Action | Description |
10
+ |--------|-------------|
11
+ | `run` | Start a team run |
12
+ | `plan` | Create a plan without executing |
13
+ | `status` | Check run/task status |
14
+ | `list` | List teams, agents, workflows |
15
+ | `get` | Get resource details |
16
+ | `cancel` | Cancel a running task/run |
17
+ | `resume` | Resume a paused run |
18
+ | `respond` | Respond to a waiting task |
19
+ | `recommend` | Get team/workflow recommendations |
20
+ | `create/update/delete` | Manage resources |
21
+ | `doctor` | Diagnose configuration issues |
22
+
23
+ ### Parameters
24
+
25
+ - `action` (required): The action to perform
26
+ - `team`: Team name for run operations
27
+ - `goal`: High-level objective
28
+ - `runId`: Run ID for status/cancel/resume
29
+ - `taskId`: Task ID for respond operations
30
+ - `confirm: true`: Required for destructive actions
31
+
32
+ ### Safety Rules
33
+
34
+ - Delete operations require `confirm: true`
35
+ - Referenced resources blocked unless `force: true`
36
+ - Cancel requires explicit run ID
37
+ - Respond requires task ID + message