pi-crew 0.2.2 → 0.2.4

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 (354) hide show
  1. package/AGENTS.md +57 -32
  2. package/CHANGELOG.md +466 -413
  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 -0
  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-plan-2026-05-12.md +463 -0
  25. package/docs/followup-review-2026-05-12.md +297 -0
  26. package/docs/followup-review-round3-2026-05-12.md +342 -0
  27. package/docs/followup-review-round4-2026-05-13.md +107 -0
  28. package/docs/implementation-plan-top3.md +333 -0
  29. package/docs/live-mailbox-runtime.md +36 -36
  30. package/docs/next-upgrade-roadmap.md +808 -808
  31. package/docs/oh-my-pi-research.md +509 -0
  32. package/docs/perf/baseline-2026-05.md +113 -0
  33. package/docs/perf/final-report-2026-05.md +206 -0
  34. package/docs/perf/sprint-1-report.md +71 -0
  35. package/docs/perf/sprint-2-report.md +81 -0
  36. package/docs/perf/sprint-2.5-report.md +53 -0
  37. package/docs/perf/sprint-3-report.md +36 -0
  38. package/docs/perf/sprint-4-report.md +47 -0
  39. package/docs/perf/sprint-5-report.md +51 -0
  40. package/docs/perf/sprint-6-report.md +94 -0
  41. package/docs/perf/sprint-7-report.md +74 -0
  42. package/docs/perf/upgrade-plan-2026-05.md +147 -0
  43. package/docs/pi-subagents3-deep-analysis.md +508 -0
  44. package/docs/product/README.md +31 -0
  45. package/docs/product/platform.md +27 -0
  46. package/docs/product/runtime-safety.md +37 -0
  47. package/docs/product/team-run.md +39 -0
  48. package/docs/product/team-tool.md +37 -0
  49. package/docs/publishing.md +65 -65
  50. package/docs/resource-formats.md +134 -134
  51. package/docs/runtime-analysis-child-vs-live.md +171 -0
  52. package/docs/runtime-flow.md +148 -148
  53. package/docs/runtime-migration-in-process-analysis.md +250 -0
  54. package/docs/stories/README.md +30 -0
  55. package/docs/stories/backlog.md +36 -0
  56. package/docs/templates/decision.md +27 -0
  57. package/docs/templates/story.md +44 -0
  58. package/docs/templates/validation-report.md +32 -0
  59. package/docs/usage.md +238 -238
  60. package/index.ts +7 -6
  61. package/install.mjs +65 -65
  62. package/package.json +107 -99
  63. package/schema.json +222 -222
  64. package/skills/child-pi-spawning/SKILL.md +213 -0
  65. package/skills/context-artifact-hygiene/SKILL.md +32 -0
  66. package/skills/event-log-tracing/SKILL.md +299 -0
  67. package/skills/git-master/SKILL.md +225 -24
  68. package/skills/live-agent-lifecycle/SKILL.md +192 -0
  69. package/skills/mailbox-interactive/SKILL.md +300 -19
  70. package/skills/model-routing-context/SKILL.md +94 -0
  71. package/skills/multi-perspective-review/SKILL.md +88 -0
  72. package/skills/read-only-explorer/SKILL.md +250 -26
  73. package/skills/safe-bash/SKILL.md +307 -21
  74. package/skills/verification-before-done/SKILL.md +11 -2
  75. package/skills/widget-rendering/SKILL.md +258 -0
  76. package/skills/workspace-isolation/SKILL.md +202 -0
  77. package/skills/worktree-isolation/SKILL.md +202 -18
  78. package/src/adapters/claude-adapter.ts +25 -25
  79. package/src/adapters/codex-adapter.ts +21 -21
  80. package/src/adapters/cursor-adapter.ts +17 -17
  81. package/src/adapters/export-util.ts +137 -137
  82. package/src/adapters/index.ts +15 -15
  83. package/src/adapters/registry.ts +18 -18
  84. package/src/adapters/types.ts +23 -23
  85. package/src/agents/agent-config.ts +38 -38
  86. package/src/agents/agent-serializer.ts +38 -38
  87. package/src/agents/discover-agents.ts +121 -118
  88. package/src/config/config.ts +740 -858
  89. package/src/config/defaults.ts +96 -96
  90. package/src/config/drift-detector.ts +211 -211
  91. package/src/config/markers.ts +327 -327
  92. package/src/config/resilient-parser.ts +109 -108
  93. package/src/config/suggestions.ts +74 -74
  94. package/src/config/types.ts +199 -0
  95. package/src/extension/async-notifier.ts +123 -89
  96. package/src/extension/autonomous-policy.ts +169 -169
  97. package/src/extension/cross-extension-rpc.ts +104 -103
  98. package/src/extension/help.ts +47 -47
  99. package/src/extension/import-index.ts +69 -69
  100. package/src/extension/management.ts +395 -382
  101. package/src/extension/notification-router.ts +116 -116
  102. package/src/extension/notification-sink.ts +51 -51
  103. package/src/extension/project-init.ts +168 -168
  104. package/src/extension/register.ts +859 -668
  105. package/src/extension/registration/artifact-cleanup.ts +15 -15
  106. package/src/extension/registration/command-utils.ts +54 -54
  107. package/src/extension/registration/commands.ts +559 -452
  108. package/src/extension/registration/compaction-guard.ts +125 -125
  109. package/src/extension/registration/subagent-helpers.ts +102 -102
  110. package/src/extension/registration/subagent-tools.ts +220 -158
  111. package/src/extension/registration/team-tool.ts +159 -98
  112. package/src/extension/registration/viewers.ts +29 -0
  113. package/src/extension/result-watcher.ts +128 -128
  114. package/src/extension/run-bundle-schema.ts +89 -89
  115. package/src/extension/run-export.ts +73 -73
  116. package/src/extension/run-import.ts +84 -84
  117. package/src/extension/run-index.ts +94 -94
  118. package/src/extension/run-maintenance.ts +142 -142
  119. package/src/extension/session-summary.ts +8 -8
  120. package/src/extension/team-manager-command.ts +96 -95
  121. package/src/extension/team-recommendation.ts +188 -188
  122. package/src/extension/team-tool/api.ts +5 -2
  123. package/src/extension/team-tool/cancel.ts +224 -209
  124. package/src/extension/team-tool/config-patch.ts +36 -36
  125. package/src/extension/team-tool/context.ts +60 -60
  126. package/src/extension/team-tool/doctor.ts +242 -242
  127. package/src/extension/team-tool/handle-settings.ts +421 -195
  128. package/src/extension/team-tool/inspect.ts +41 -41
  129. package/src/extension/team-tool/lifecycle-actions.ts +139 -139
  130. package/src/extension/team-tool/parallel-dispatch.ts +156 -156
  131. package/src/extension/team-tool/plan.ts +19 -19
  132. package/src/extension/team-tool/respond.ts +112 -111
  133. package/src/extension/team-tool/run.ts +246 -228
  134. package/src/extension/team-tool/status.ts +110 -110
  135. package/src/extension/team-tool-types.ts +13 -13
  136. package/src/extension/team-tool.ts +16 -4
  137. package/src/extension/tool-result.ts +16 -16
  138. package/src/extension/validate-resources.ts +77 -77
  139. package/src/hooks/registry.ts +61 -61
  140. package/src/hooks/types.ts +40 -40
  141. package/src/i18n.ts +184 -184
  142. package/src/observability/correlation.ts +35 -35
  143. package/src/observability/event-to-metric.ts +68 -68
  144. package/src/observability/exporters/adapter.ts +30 -30
  145. package/src/observability/exporters/otlp-exporter.ts +106 -92
  146. package/src/observability/exporters/prometheus-exporter.ts +54 -54
  147. package/src/observability/metric-registry.ts +87 -87
  148. package/src/observability/metric-retention.ts +54 -54
  149. package/src/observability/metric-sink.ts +81 -56
  150. package/src/observability/metrics-primitives.ts +167 -167
  151. package/src/prompt/prompt-runtime.ts +72 -72
  152. package/src/runtime/adaptive-plan.ts +338 -0
  153. package/src/runtime/agent-control.ts +169 -169
  154. package/src/runtime/agent-memory.ts +72 -72
  155. package/src/runtime/agent-observability.ts +114 -114
  156. package/src/runtime/async-marker.ts +26 -26
  157. package/src/runtime/async-runner.ts +153 -79
  158. package/src/runtime/attention-events.ts +28 -28
  159. package/src/runtime/auto-resume.ts +100 -100
  160. package/src/runtime/background-runner.ts +122 -88
  161. package/src/runtime/cancellation.ts +61 -61
  162. package/src/runtime/capability-inventory.ts +116 -116
  163. package/src/runtime/child-pi-pool.ts +68 -0
  164. package/src/runtime/child-pi.ts +541 -463
  165. package/src/runtime/code-summary.ts +247 -247
  166. package/src/runtime/compaction-summary.ts +271 -271
  167. package/src/runtime/concurrency.ts +58 -58
  168. package/src/runtime/crash-recovery.ts +317 -301
  169. package/src/runtime/crew-agent-records.ts +379 -281
  170. package/src/runtime/crew-agent-runtime.ts +60 -60
  171. package/src/runtime/cross-extension-rpc.ts +72 -0
  172. package/src/runtime/custom-tools/irc-tool.ts +201 -201
  173. package/src/runtime/custom-tools/submit-result-tool.ts +90 -90
  174. package/src/runtime/deadletter.ts +47 -47
  175. package/src/runtime/delivery-coordinator.ts +176 -176
  176. package/src/runtime/delta-conflict.ts +360 -360
  177. package/src/runtime/diagnostic-export.ts +102 -102
  178. package/src/runtime/direct-run.ts +35 -35
  179. package/src/runtime/effectiveness.ts +82 -81
  180. package/src/runtime/errors/crew-errors.ts +166 -0
  181. package/src/runtime/event-stream-bridge.ts +92 -92
  182. package/src/runtime/foreground-control.ts +82 -82
  183. package/src/runtime/green-contract.ts +46 -46
  184. package/src/runtime/group-join.ts +234 -106
  185. package/src/runtime/heartbeat-watcher.ts +145 -124
  186. package/src/runtime/iteration-hooks.ts +267 -264
  187. package/src/runtime/live-agent-control.ts +88 -88
  188. package/src/runtime/live-agent-manager.ts +377 -179
  189. package/src/runtime/live-control-realtime.ts +36 -36
  190. package/src/runtime/live-session-runtime.ts +676 -599
  191. package/src/runtime/loop-gates.ts +129 -129
  192. package/src/runtime/manifest-cache.ts +263 -263
  193. package/src/runtime/mcp-proxy.ts +113 -113
  194. package/src/runtime/metric-parser.ts +40 -40
  195. package/src/runtime/model-fallback.ts +282 -274
  196. package/src/runtime/model-resolver.ts +118 -0
  197. package/src/runtime/output-validator.ts +187 -187
  198. package/src/runtime/overflow-recovery.ts +175 -175
  199. package/src/runtime/parallel-research.ts +44 -44
  200. package/src/runtime/parallel-utils.ts +156 -156
  201. package/src/runtime/parent-guard.ts +80 -80
  202. package/src/runtime/phase-progress.ts +217 -217
  203. package/src/runtime/pi-args.ts +165 -165
  204. package/src/runtime/pi-json-output.ts +111 -111
  205. package/src/runtime/pi-spawn.ts +167 -167
  206. package/src/runtime/policy-engine.ts +79 -79
  207. package/src/runtime/post-checks.ts +125 -122
  208. package/src/runtime/post-exit-stdio-guard.ts +86 -86
  209. package/src/runtime/process-status.ts +97 -73
  210. package/src/runtime/progress-event-coalescer.ts +43 -43
  211. package/src/runtime/recovery-recipes.ts +74 -74
  212. package/src/runtime/retry-executor.ts +81 -81
  213. package/src/runtime/role-permission.ts +39 -39
  214. package/src/runtime/run-tracker.ts +99 -0
  215. package/src/runtime/runtime-policy.ts +21 -0
  216. package/src/runtime/runtime-resolver.ts +94 -90
  217. package/src/runtime/scheduler.ts +294 -0
  218. package/src/runtime/semaphore.ts +131 -131
  219. package/src/runtime/sensitive-paths.ts +92 -92
  220. package/src/runtime/session-usage.ts +79 -79
  221. package/src/runtime/settings-store.ts +103 -0
  222. package/src/runtime/sidechain-output.ts +29 -29
  223. package/src/runtime/skill-instructions.ts +222 -222
  224. package/src/runtime/stale-reconciler.ts +198 -189
  225. package/src/runtime/streaming-output.ts +47 -0
  226. package/src/runtime/subagent-manager.ts +404 -395
  227. package/src/runtime/subprocess-tool-registry.ts +67 -67
  228. package/src/runtime/task-display.ts +38 -38
  229. package/src/runtime/task-graph-scheduler.ts +122 -122
  230. package/src/runtime/task-graph.ts +207 -207
  231. package/src/runtime/task-output-context.ts +177 -177
  232. package/src/runtime/task-packet.ts +93 -93
  233. package/src/runtime/task-quality.ts +207 -207
  234. package/src/runtime/task-runner/capabilities.ts +78 -78
  235. package/src/runtime/task-runner/live-executor.ts +131 -113
  236. package/src/runtime/task-runner/progress.ts +119 -119
  237. package/src/runtime/task-runner/prompt-builder.ts +139 -139
  238. package/src/runtime/task-runner/prompt-pipeline.ts +64 -64
  239. package/src/runtime/task-runner/result-utils.ts +14 -14
  240. package/src/runtime/task-runner/run-projection.ts +103 -103
  241. package/src/runtime/task-runner/state-helpers.ts +22 -22
  242. package/src/runtime/task-runner.ts +469 -458
  243. package/src/runtime/team-runner.ts +693 -945
  244. package/src/runtime/usage-tracker.ts +71 -0
  245. package/src/runtime/worker-heartbeat.ts +21 -21
  246. package/src/runtime/worker-startup.ts +57 -57
  247. package/src/runtime/workflow-state.ts +187 -187
  248. package/src/runtime/yield-handler.ts +190 -189
  249. package/src/schema/config-schema.ts +172 -168
  250. package/src/schema/team-tool-schema.ts +126 -125
  251. package/src/schema/validation-types.ts +151 -148
  252. package/src/skills/discover-skills.ts +67 -67
  253. package/src/skills/skill-templates.ts +374 -374
  254. package/src/state/active-run-registry.ts +227 -191
  255. package/src/state/artifact-store.ts +130 -129
  256. package/src/state/atomic-write.ts +262 -178
  257. package/src/state/blob-store.ts +116 -116
  258. package/src/state/contracts.ts +111 -111
  259. package/src/state/event-log-rotation.ts +161 -158
  260. package/src/state/event-log.ts +383 -240
  261. package/src/state/event-reconstructor.ts +217 -217
  262. package/src/state/jsonl-writer.ts +82 -82
  263. package/src/state/locks.ts +146 -148
  264. package/src/state/mailbox.ts +446 -405
  265. package/src/state/state-store.ts +364 -351
  266. package/src/state/task-claims.ts +44 -44
  267. package/src/state/types.ts +285 -285
  268. package/src/state/usage.ts +29 -29
  269. package/src/subagents/async-entry.ts +1 -1
  270. package/src/subagents/index.ts +3 -3
  271. package/src/subagents/live/control.ts +1 -1
  272. package/src/subagents/live/manager.ts +1 -1
  273. package/src/subagents/live/realtime.ts +1 -1
  274. package/src/subagents/live/session-runtime.ts +1 -1
  275. package/src/subagents/manager.ts +1 -1
  276. package/src/subagents/spawn.ts +1 -1
  277. package/src/teams/discover-teams.ts +116 -116
  278. package/src/teams/team-config.ts +27 -27
  279. package/src/teams/team-serializer.ts +38 -38
  280. package/src/types/diff.d.ts +18 -18
  281. package/src/ui/agent-management-overlay.ts +144 -144
  282. package/src/ui/crew-widget.ts +487 -370
  283. package/src/ui/dashboard-panes/agents-pane.ts +109 -28
  284. package/src/ui/dashboard-panes/cancellation-pane.ts +42 -42
  285. package/src/ui/dashboard-panes/capability-pane.ts +59 -59
  286. package/src/ui/dashboard-panes/health-pane.ts +30 -30
  287. package/src/ui/dashboard-panes/mailbox-pane.ts +35 -35
  288. package/src/ui/dashboard-panes/progress-pane.ts +30 -30
  289. package/src/ui/dashboard-panes/transcript-pane.ts +10 -10
  290. package/src/ui/heartbeat-aggregator.ts +63 -63
  291. package/src/ui/keybinding-map.ts +97 -94
  292. package/src/ui/live-conversation-overlay.ts +152 -0
  293. package/src/ui/live-run-sidebar.ts +180 -180
  294. package/src/ui/mascot.ts +442 -442
  295. package/src/ui/overlays/agent-picker-overlay.ts +57 -57
  296. package/src/ui/overlays/confirm-overlay.ts +58 -58
  297. package/src/ui/overlays/mailbox-compose-overlay.ts +144 -144
  298. package/src/ui/overlays/mailbox-compose-preview.ts +63 -63
  299. package/src/ui/overlays/mailbox-detail-overlay.ts +122 -122
  300. package/src/ui/pi-ui-compat.ts +57 -57
  301. package/src/ui/powerbar-publisher.ts +221 -197
  302. package/src/ui/render-scheduler.ts +216 -143
  303. package/src/ui/run-action-dispatcher.ts +118 -117
  304. package/src/ui/run-dashboard.ts +526 -464
  305. package/src/ui/run-event-bus.ts +208 -208
  306. package/src/ui/run-snapshot-cache.ts +826 -777
  307. package/src/ui/settings-overlay.ts +721 -0
  308. package/src/ui/snapshot-types.ts +86 -70
  309. package/src/ui/theme-adapter.ts +190 -190
  310. package/src/ui/tool-progress-formatter.ts +89 -0
  311. package/src/ui/transcript-cache.ts +94 -94
  312. package/src/ui/transcript-viewer.ts +335 -335
  313. package/src/utils/conflict-detect.ts +662 -0
  314. package/src/utils/env-filter.ts +30 -0
  315. package/src/utils/file-coalescer.ts +86 -86
  316. package/src/utils/frontmatter.ts +68 -68
  317. package/src/utils/fs-watch.ts +88 -31
  318. package/src/utils/gh-protocol.ts +479 -0
  319. package/src/utils/ids.ts +17 -17
  320. package/src/utils/incremental-reader.ts +104 -104
  321. package/src/utils/internal-error.ts +6 -6
  322. package/src/utils/names.ts +27 -27
  323. package/src/utils/paths.ts +102 -63
  324. package/src/utils/redaction.ts +44 -44
  325. package/src/utils/resolve-shell.ts +34 -0
  326. package/src/utils/safe-paths.ts +47 -47
  327. package/src/utils/scan-cache.ts +136 -136
  328. package/src/utils/sleep.ts +2 -1
  329. package/src/utils/sse-parser.ts +134 -134
  330. package/src/utils/task-name-generator.ts +337 -337
  331. package/src/utils/timings.ts +33 -33
  332. package/src/utils/visual.ts +243 -198
  333. package/src/workflows/discover-workflows.ts +139 -139
  334. package/src/workflows/validate-workflow.ts +40 -40
  335. package/src/workflows/workflow-config.ts +26 -26
  336. package/src/workflows/workflow-serializer.ts +32 -32
  337. package/src/worktree/branch-freshness.ts +45 -45
  338. package/src/worktree/cleanup.ts +75 -72
  339. package/src/worktree/worktree-manager.ts +188 -146
  340. package/teams/default.team.md +12 -12
  341. package/teams/fast-fix.team.md +11 -11
  342. package/teams/implementation.team.md +18 -18
  343. package/teams/parallel-research.team.md +14 -14
  344. package/teams/research.team.md +11 -11
  345. package/teams/review.team.md +12 -12
  346. package/tsconfig.json +19 -19
  347. package/workflows/default.workflow.md +30 -30
  348. package/workflows/fast-fix.workflow.md +23 -23
  349. package/workflows/implementation.workflow.md +43 -43
  350. package/workflows/parallel-research.workflow.md +46 -46
  351. package/workflows/research.workflow.md +22 -22
  352. package/workflows/review.workflow.md +30 -30
  353. package/skills/task-packet/SKILL.md +0 -28
  354. 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