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,61 @@
1
+ # 0008 Child-pi Warm Pool
2
+
3
+ Date: 2026-05-14
4
+
5
+ ## Status
6
+
7
+ Proposed — not yet implemented.
8
+
9
+ ## Context
10
+
11
+ Each task in a parallel team run spawns a fresh `pi` child process.
12
+ Cold-start of each child takes 2–5 s on Windows (most of that is Node
13
+ startup + module load). For a phase with 4 parallel tasks the spawn
14
+ cost serialises into the wall-clock floor.
15
+
16
+ ## Decision (proposed)
17
+
18
+ Add an opt-in warm pool managed by `child-pi.ts`:
19
+
20
+ - Config: `runtime.warmPool.enabled: false` (default), `runtime.warmPool.size: 2`.
21
+ - Pool process is spawned with a `PI_CREW_POOL_HEALTH=1` ping handshake
22
+ on startup; it parks in a `wait-for-prompt` state.
23
+ - On task dispatch, the parent writes the prompt + skill paths over
24
+ stdin and reads stdout normally.
25
+ - Each pool process is single-use: after one task completes, the
26
+ process exits and the pool refills in the background.
27
+ - A health check on reuse rejects any process that has unread stderr,
28
+ is past `maxIdleMs`, or has an open file handle outside its
29
+ scratch dir.
30
+
31
+ ## Alternatives considered
32
+
33
+ 1. Long-lived shared pool with state — unsafe (one task can pollute
34
+ the next); rejected.
35
+ 2. Pre-warm only when team-runner predicts a parallel batch — saves
36
+ pool size but adds prediction logic; defer to later optimisation.
37
+ 3. Status quo — retain the 2–5 s per task floor.
38
+
39
+ ## Consequences
40
+
41
+ Positive:
42
+ - Wall-clock floor of parallel batches drops by 2–4 s per pool slot.
43
+ - Behaviour identical from the worker's perspective (single prompt
44
+ per process).
45
+
46
+ Tradeoffs / risks:
47
+ - Pool processes are zombies until used. CPU cost is negligible but
48
+ RAM cost is ~30–60 MB per slot.
49
+ - Crash-recovery semantics need an extra branch: `child-stdout-final`
50
+ marker valid only after prompt was actually sent.
51
+ - Disabled by default for one release; enable globally once 50
52
+ consecutive runs pass on the dogfood machine.
53
+
54
+ ## Next steps
55
+
56
+ 1. Implement pool inside `src/runtime/child-pi.ts`; expose
57
+ `getPooledChild()` / `releasePooledChild()`.
58
+ 2. Add health-check protocol over stdin/stdout JSON.
59
+ 3. Stress test: 50 consecutive runs on a single pool, measure leak.
60
+ 4. Default off; flip default after one stable release window.
61
+ 5. Land ADR as "Accepted" after default-on rollout.
@@ -0,0 +1,23 @@
1
+ # Decisions
2
+
3
+ Decision records explain why important product, architecture, or harness choices were made.
4
+
5
+ Add a decision when:
6
+ - Runtime mode changes (child-process vs live-session)
7
+ - State format changes
8
+ - New dependency introduced
9
+ - API contract changes
10
+ - Security hardening applied
11
+ - Validation requirements added/removed/changed
12
+
13
+ Current decisions derived from 9 review rounds and 13 bug fixes.
14
+
15
+ ## Index
16
+
17
+ | ID | Title | Status |
18
+ |----|-------|--------|
19
+ | 0001 | Durable state as source of truth | Accepted |
20
+ | 0002 | Child-process for async runners | Accepted |
21
+ | 0003 | Depth guard for nested live-session | Accepted |
22
+ | 0004 | execFileSync over execSync | Accepted |
23
+ | 0005 | No TypeScript parameter properties | Accepted |
@@ -0,0 +1,107 @@
1
+ # Follow-up Review Round 4 — 2026-05-13
2
+
3
+ Review of commits `c7bd455` through `5f47e92` (7 commits on top of `faa81e4`).
4
+
5
+ ## Summary
6
+
7
+ These commits harden live-session runtime cleanup, async runner lifecycle, crew-agent persistence, and Windows test flakiness. Overall quality is high and the fixes address real production issues. However, one commit introduces a **regression** that breaks the resume/follow-up capability for completed live-session agents. Two other issues could cause crashes or races in edge cases.
8
+
9
+ **All identified bugs have been fixed in commits `a8a43b4` through current working tree.**
10
+
11
+ ---
12
+
13
+ ## Critical — FIXED
14
+
15
+ ### BUG-014: `removeLiveAgentHandle` on normal completion destroys resume capability
16
+
17
+ **File:** `src/runtime/live-session-runtime.ts` (finally block, line ~610)
18
+ **Commit:** `7a25644` → **Fixed in a8a43b4**
19
+
20
+ The finally block calls `removeLiveAgentHandle(agentId)` for non-aborted completions. This **deletes the live-agent handle from the registry entirely**, including its terminal status.
21
+
22
+ **Impact:** After a live-session task completes normally, `steerLiveAgent`, `followUpLiveAgent`, and `resumeLiveAgent` all fail with "Live agent '...' is not registered in this process."
23
+
24
+ **Fix:** Added `disposeLiveAgentSession()` in `live-agent-manager.ts` — disposes session resources but keeps the handle in the registry for resume/follow-up.
25
+
26
+ ---
27
+
28
+ ## High — FIXED
29
+
30
+ ### BUG-015: `withAgentsLock` crashes on `EISDIR` from corrupted lock path
31
+
32
+ **File:** `src/runtime/crew-agent-records.ts`
33
+ **Commit:** `c7bd455` → **Fixed in a8a43b4**
34
+
35
+ `withAgentsLock` only caught `EEXIST`; if lock path was a directory, `EISDIR` crashed the process.
36
+
37
+ **Fix:** Handle `EISDIR` by removing the directory and retrying.
38
+
39
+ ---
40
+
41
+ ## Medium — FIXED
42
+
43
+ ### BUG-016: `markActiveTasksAndAgentsFailed` lacks run-level lock, races with crash recovery
44
+
45
+ **File:** `src/extension/async-notifier.ts`
46
+ **Commit:** `d6d466d` → **Fixed in current working tree**
47
+
48
+ `markActiveTasksAndAgentsFailed` called `saveRunTasks` and `saveCrewAgents` without `withRunLockSync`. Crash recovery (`cancelOrphanedRuns`) uses `withRunLockSync`. Concurrent execution on the same run risks lost updates.
49
+
50
+ **Fix:** Wrapped `markDeadAsyncRunIfNeeded` mutations inside `withRunLockSync(run, () => { ... })`. Also reloaded fresh manifest inside the lock to avoid operating on stale data.
51
+
52
+ ---
53
+
54
+ ## Low — FIXED
55
+
56
+ ### BUG-017: `safeDisposeLiveSession` catches all errors silently
57
+
58
+ **File:** `src/runtime/live-agent-manager.ts`
59
+ **Commit:** `7a25644` → **Fixed in current working tree**
60
+
61
+ Any exception from `dispose()` was swallowed without logging.
62
+
63
+ **Fix:** Log disposal errors via `logInternalError`.
64
+
65
+ ### BUG-018: `effectiveRuntime` in `run.ts` is manually constructed
66
+
67
+ **File:** `src/extension/team-tool/run.ts`
68
+ **Commit:** `2486051` → **Fixed in current working tree**
69
+
70
+ The async fallback runtime was manually built field-by-field. If `CrewRuntimeCapabilities` gains a new required field, this site won't inherit it.
71
+
72
+ **Fix:** Use spread of original runtime with overrides: `{ ...runtime, kind: "child-process", steer: false, resume: false, liveToolActivity: false, fallback: "child-process", reason: "..." }`.
73
+
74
+ ### NIT-007: `removeStaleAgentsLock` reads unlimited file size
75
+
76
+ **File:** `src/runtime/crew-agent-records.ts`
77
+ **Commit:** `c7bd455` → **Fixed in current working tree**
78
+
79
+ `fs.readFileSync(lockPath, "utf-8")` reads entire file into memory. Corrupted multi-megabyte file causes memory pressure.
80
+
81
+ **Fix:** Check `fs.statSync(lockPath).size > 1024` before reading; skip stale removal if oversized.
82
+
83
+ ### NIT-008: `maxCollectedJsonEvents` cap is hardcoded at 200
84
+
85
+ **File:** `src/runtime/live-session-runtime.ts`
86
+ **Commit:** `c7bd455` → **Fixed in current working tree**
87
+
88
+ Long-running agents drop older JSON events needed for debugging/yield detection.
89
+
90
+ **Fix:** Increased cap from 200 to 1000.
91
+
92
+ ---
93
+
94
+ ## Verification
95
+
96
+ - `npm run typecheck` passes.
97
+ - Targeted tests (`async-notifier`, `isolation-policy`, `live-agent-manager`, `live-session-runtime`, `team-tool-dispatch`) pass: **31 pass / 0 fail**.
98
+ - Full unit test suite not run due to time constraints; no new failures observed in targeted runs.
99
+
100
+ ## Files Changed in Fixes
101
+
102
+ - `src/extension/async-notifier.ts` — BUG-016 (run lock)
103
+ - `src/runtime/live-agent-manager.ts` — BUG-014 (disposeLiveAgentSession), BUG-017 (log dispose errors)
104
+ - `src/runtime/live-session-runtime.ts` — BUG-014 (use disposeLiveAgentSession), NIT-008 (cap 1000)
105
+ - `src/runtime/crew-agent-records.ts` — BUG-015 (EISDIR), NIT-007 (size cap)
106
+ - `src/extension/team-tool/run.ts` — BUG-018 (spread runtime)
107
+ - `test/unit/live-agent-manager.test.ts` — test for disposeLiveAgentSession
@@ -0,0 +1,333 @@
1
+ # Implementation Plan: Top 3 Features from oh-my-pi v15
2
+
3
+ > Date: 2026-05-13
4
+ > Based on: `D:/my/my_project/source/oh-my-pi` research
5
+ > Target: pi-crew v0.2.x
6
+
7
+ ---
8
+
9
+ ## Priority Order
10
+
11
+ 1. **Typed Crew Errors** — Quick win, no dependencies
12
+ 2. **Conflict Detection** — High value, standalone module
13
+ 3. **Issue-PR Protocol** — Medium complexity, GitHub integration
14
+
15
+ ---
16
+
17
+ ## 1. Typed Crew Errors
18
+
19
+ ### Why
20
+ Current pi-crew uses generic `Error` types with string matching:
21
+ ```typescript
22
+ catch (e) {
23
+ if (e instanceof Error && e.message.includes("deadletter")) { ... }
24
+ }
25
+ ```
26
+
27
+ Pattern from oh-my-pi: use typed sentinel errors with `instanceof` discrimination.
28
+
29
+ ### Files to create/modify
30
+
31
+ **Create:** `src/runtime/errors/crew-errors.ts`
32
+
33
+ ```typescript
34
+ /**
35
+ * Typed error sentinels for pi-crew operations.
36
+ * Follows oh-my-pi pattern from compaction/errors.ts.
37
+ */
38
+
39
+ export class CrewCancelledError extends Error {
40
+ readonly name = "CrewCancelledError" as const;
41
+ constructor(message = "Crew run cancelled") { super(message); }
42
+ }
43
+
44
+ export class CrewTimeoutError extends Error {
45
+ readonly name = "CrewTimeoutError" as const;
46
+ constructor(public readonly maxDurationMs: number) {
47
+ super(`Crew run exceeded timeout of ${maxDurationMs}ms`);
48
+ }
49
+ }
50
+
51
+ export class CrewDeadletterError extends Error {
52
+ readonly name = "CrewDeadletterError" as const;
53
+ constructor(
54
+ public readonly agentId: string,
55
+ public readonly reason: string,
56
+ ) {
57
+ super(`Agent ${agentId} deadlettered: ${reason}`);
58
+ }
59
+ }
60
+
61
+ export class CrewAbortError extends Error {
62
+ readonly name = "CrewAbortError" as const;
63
+ constructor(message = "Crew run aborted") { super(message); }
64
+ }
65
+
66
+ export class CrewManifestError extends Error {
67
+ readonly name = "CrewManifestError" as const;
68
+ constructor(message: string, public readonly runId?: string) { super(message); }
69
+ }
70
+
71
+ export class CrewLockError extends Error {
72
+ readonly name = "CrewLockError" as const;
73
+ constructor(message: string, public readonly lockPath?: string) { super(message); }
74
+ }
75
+
76
+ /**
77
+ * Outcome of a crew run attempt.
78
+ * Used by RunTracker and HealthWatcher.
79
+ */
80
+ export type CrewRunOutcome = "ok" | "cancelled" | "deadletter" | "failed" | "timeout" | "aborted";
81
+ ```
82
+
83
+ **Update:** `src/runtime/task-runner.ts`, `src/runtime/team-runner.ts`, `src/runtime/crash-recovery.ts`
84
+
85
+ Replace string matching with `instanceof` checks.
86
+
87
+ ### Implementation
88
+
89
+ ```bash
90
+ # 1. Create file
91
+ cat > src/runtime/errors/crew-errors.ts << 'EOF'
92
+ // (content above)
93
+ EOF
94
+
95
+ # 2. Update imports in affected files
96
+ # From: catch (e) { if (e instanceof Error && e.message.includes("deadletter")) ... }
97
+ # To: catch (e) { if (e instanceof CrewDeadletterError) ... }
98
+ ```
99
+
100
+ ### Effort: LOW (1-2 hours)
101
+
102
+ ---
103
+
104
+ ## 2. Conflict Detection
105
+
106
+ ### Why
107
+ When multiple pi-crew agents edit the same file in a worktree, git merge conflicts can occur. Current pi-crew has no conflict detection — agents see garbled `<<<<<<< HEAD` markers with no structured way to resolve them.
108
+
109
+ ### Architecture
110
+
111
+ ```
112
+ pi-crew worktree agents edit files
113
+
114
+ WorktreeManager detects file change
115
+
116
+ ConflictDetector.scanFileForConflicts(path)
117
+
118
+ Returns ConflictBlock[] + registers in ConflictHistory
119
+
120
+ Read tool appends conflict warning footer
121
+
122
+ Agent calls write({ path: "conflict://<id>", content })
123
+
124
+ ConflictResolver.spliceConflict() → clean file
125
+ ```
126
+
127
+ ### Files to create
128
+
129
+ **Create:** `src/utils/conflict-detect.ts` (fork from oh-my-pi, ~400 lines)
130
+
131
+ Key exports:
132
+ - `scanConflictLines(lines, firstLineNumber)` → `ConflictBlock[]`
133
+ - `scanFileForConflicts(path)` → `{ blocks, scanTruncated }`
134
+ - `ConflictHistory` class
135
+ - `ConflictEntry` interface
136
+ - `parseConflictUri(raw)` → `ParsedConflictUri | null`
137
+ - `spliceConflict(text, entry, replacement)` → `string`
138
+ - `expandContentTokens(content, entry)` → `string` (handles @ours/@theirs/@base/@both)
139
+ - `renderConflictRegion(entry, scope)` → `{ lines, startLine }`
140
+ - `formatConflictWarning(entries)` → `string`
141
+
142
+ **Create:** `src/runtime/conflict-registry.ts`
143
+
144
+ ```typescript
145
+ /**
146
+ * Global conflict registry for pi-crew.
147
+ * Attaches ConflictHistory to each live session.
148
+ */
149
+ import { ConflictHistory, getConflictHistory } from "../utils/conflict-detect.ts";
150
+ import type { LiveAgentHandle } from "./live-agent-manager.ts";
151
+
152
+ export function getAgentConflicts(handle: LiveAgentHandle): ConflictHistory {
153
+ if (!handle.conflictHistory) {
154
+ handle.conflictHistory = new ConflictHistory();
155
+ }
156
+ return handle.conflictHistory;
157
+ }
158
+ ```
159
+
160
+ **Modify:** `src/extension/registration/tools/read-tool.ts`
161
+
162
+ After reading file content:
163
+ 1. Call `scanConflictLines(lines, 1)`
164
+ 2. For each block, call `conflictHistory.register(...)`
165
+ 3. Append `formatConflictWarning(entries)` to output
166
+
167
+ **Modify:** `src/extension/registration/tools/write-tool.ts`
168
+
169
+ Add `conflict://<N>` handling:
170
+ 1. Parse URI with `parseConflictUri(path)`
171
+ 2. Look up `ConflictEntry` from `ConflictHistory`
172
+ 3. Call `expandContentTokens(content, entry)`
173
+ 4. Call `spliceConflict(originalText, entry, expandedContent)`
174
+ 5. Write result to `entry.absolutePath`
175
+
176
+ ### Integration points
177
+
178
+ | File | Change |
179
+ |------|--------|
180
+ | `src/extension/registration/tools/read-tool.ts` | Append conflict warning to file content |
181
+ | `src/extension/registration/tools/write-tool.ts` | Handle `conflict://` protocol |
182
+ | `src/runtime/live-agent-manager.ts` | Add `conflictHistory?: ConflictHistory` to handle |
183
+ | `src/utils/conflict-detect.ts` | New file (fork from oh-my-pi) |
184
+ | `src/runtime/conflict-registry.ts` | New file (global registry) |
185
+
186
+ ### Edge cases to handle
187
+
188
+ 1. **Nested conflicts** — oh-my-pi handles by requiring strict marker shape
189
+ 2. **Multi-file conflicts** — `ConflictHistory.invalidatePath()` when file is resolved
190
+ 3. **Retry after partial resolution** — `ConflictEntry` id stays stable
191
+ 4. **Large files** — `scanFileForConflicts` caps at 10MB
192
+ 5. **Diff3 conflicts** — Support `|||||||` base section
193
+
194
+ ### Test plan
195
+
196
+ ```typescript
197
+ // test/unit/conflict-detect.test.ts
198
+ test("scanConflictLines detects single 2-way block", () => {
199
+ const lines = ["<<<<<<< HEAD", "our changes", "=======", "their changes", ">>>>>>> feature"];
200
+ const blocks = scanConflictLines(lines, 1);
201
+ assert(blocks.length === 1);
202
+ assert(blocks[0].oursLines[0] === "our changes");
203
+ });
204
+
205
+ test("scanConflictLines ignores non-column-0 markers", () => {
206
+ const lines = [" <<<<<<< indented", "=======", ">>>>>>>"];
207
+ const blocks = scanConflictLines(lines, 1);
208
+ assert(blocks.length === 0);
209
+ });
210
+
211
+ test("scanConflictLines detects diff3 3-way block", () => {
212
+ // ...with ||||||| base marker
213
+ });
214
+ ```
215
+
216
+ ### Effort: MEDIUM (4-8 hours)
217
+
218
+ ---
219
+
220
+ ## 3. Issue-PR Protocol
221
+
222
+ ### Why
223
+ pi-crew workflow agents can benefit from issue/PR integration:
224
+ - Create issue from failed task
225
+ - Link workflow tasks to GitHub issues
226
+ - PR review workflow (`pr://` protocol)
227
+
228
+ ### URL shapes to support
229
+
230
+ ```
231
+ issue:// — list recent issues (default repo from cwd)
232
+ issue://owner/repo — list issues for repo
233
+ issue://123 — single issue (repo from cwd)
234
+ issue://owner/repo/123 — fully qualified
235
+ issue://owner/repo/123?comments=0 — suppress comments
236
+
237
+ pr:// — list recent PRs
238
+ pr://owner/repo — list PRs for repo
239
+ pr://owner/repo/456 — single PR
240
+ pr://owner/repo/456/diff — PR diff
241
+ ```
242
+
243
+ ### Files to create/modify
244
+
245
+ **Create:** `src/internal-urls/issue-pr-protocol.ts` (port from oh-my-pi, ~577 lines)
246
+
247
+ Key exports:
248
+ - `IssuePrProtocol` class implementing `ProtocolHandler`
249
+ - `parseIssueUrl(url)` → `ParsedIssue`
250
+ - `parsePrUrl(url)` → `ParsedPr`
251
+ - `fetchIssue(parsed)` → `string` (markdown)
252
+ - `fetchPr(parsed)` → `string` (markdown)
253
+ - `fetchPrDiff(parsed)` → `string` (unified diff)
254
+
255
+ **Modify:** `src/internal-urls/router.ts`
256
+
257
+ Register `issue://` and `pr://` handlers.
258
+
259
+ **Create:** `src/tools/gh-cache.ts` (fork from oh-my-pi `tools/github-cache.ts`)
260
+
261
+ SQLite-backed cache for GitHub API responses. Shared across sessions.
262
+
263
+ ### Dependencies
264
+
265
+ 1. **GitHub CLI (`gh`)** — oh-my-pi uses `gh issue list`, `gh pr list`, `gh api`
266
+ 2. **SQLite** — via `better-sqlite3` or similar
267
+ 3. **Git config** — Need to resolve default repo from `git remote get-url origin`
268
+
269
+ ### Implementation details
270
+
271
+ ```typescript
272
+ interface ParsedIssue {
273
+ kind: "single" | "list";
274
+ repo?: string; // undefined = derive from cwd
275
+ number?: number;
276
+ state?: "open" | "closed" | "all";
277
+ limit?: number;
278
+ comments?: boolean;
279
+ }
280
+
281
+ interface ParsedPr {
282
+ kind: "single" | "list" | "diff";
283
+ repo?: string;
284
+ number?: number;
285
+ state?: "open" | "closed" | "merged" | "all";
286
+ limit?: number;
287
+ diffMode?: "list" | "all";
288
+ }
289
+ ```
290
+
291
+ **Fetching:**
292
+ - List: `gh issue list --repo owner/repo --state open --limit 30`
293
+ - Single: `gh issue view 123 --repo owner/repo --comments`
294
+ - PR: `gh pr view 456 --repo owner/repo --comments`
295
+ - Diff: `gh pr diff 456 --repo owner/repo`
296
+
297
+ **Caching:**
298
+ - Cache key: `{repo, number, type}` hash
299
+ - TTL: 5 minutes for list, 1 hour for single items
300
+ - Invalidate on write operations (create/close/reopen)
301
+
302
+ ### Integration with pi-crew
303
+
304
+ **New tool:** `read-issue` / `read-pr`
305
+ ```typescript
306
+ // agents có thể gọi:
307
+ // read({ path: "issue://123" }) → markdown của issue
308
+ // read({ path: "pr://456" }) → markdown của PR
309
+ ```
310
+
311
+ **New slash command:** `/issue` hoặc dùng existing `/crew`:
312
+ ```
313
+ /crew create-issue "Task failed: fix memory leak in cache" --labels=bug --assignee=me
314
+ /crew link-issue TICKET-123 --task=explorer-1
315
+ ```
316
+
317
+ ### Effort: MEDIUM-HIGH (8-12 hours)
318
+
319
+ ---
320
+
321
+ ## Summary
322
+
323
+ | Feature | Effort | Risk | Priority |
324
+ |---------|--------|------|----------|
325
+ | Typed Crew Errors | LOW | None | 1 |
326
+ | Conflict Detection | MEDIUM | Git operations, large file handling | 2 |
327
+ | Issue-PR Protocol | MEDIUM-HIGH | GitHub auth, gh CLI dependency | 3 |
328
+
329
+ ## Recommended execution order
330
+
331
+ 1. **Day 1:** Typed Crew Errors (quick win)
332
+ 2. **Day 2-3:** Conflict Detection
333
+ 3. **Day 4-5:** Issue-PR Protocol (if time permits)
@@ -1,36 +1,36 @@
1
- # Live Mailbox Runtime Direction
2
-
3
- `pi-crew` currently uses workflow child-process orchestration: a run materializes tasks, executes them through the scheduler, writes artifacts/events, and optionally launches child Pi workers.
4
-
5
- A full live mailbox runtime is intentionally out of scope for the current stable surface. Current foundational mailbox files are intentionally simple and local:
6
-
7
- ```text
8
- {stateRoot}/mailbox/inbox.jsonl
9
- {stateRoot}/mailbox/outbox.jsonl
10
- {stateRoot}/mailbox/delivery.json
11
- {stateRoot}/mailbox/tasks/{taskId}/inbox.jsonl
12
- {stateRoot}/mailbox/tasks/{taskId}/outbox.jsonl
13
- ```
14
-
15
- They are exposed through safe API operations (`read-mailbox`, `send-message`, `ack-message`, `read-delivery`, `validate-mailbox`) but do not yet imply always-on long-lived workers. If a full runtime is added later, it should build on the foundations already present:
16
-
17
- - `src/state/contracts.ts` for status/event contracts
18
- - `src/state/task-claims.ts` for claim/lease safety
19
- - `src/runtime/worker-heartbeat.ts` for liveness
20
- - `src/state/locks.ts` for run-level mutation safety
21
- - `action: "api"` for safe interop boundaries
22
-
23
- ## Proposed phases
24
-
25
- 1. **Read-only interop** — already started with `api` operations.
26
- 2. **Heartbeat writers** — allow workers to update heartbeat/progress safely.
27
- 3. **Claim-safe task lifecycle** — expose claim/release/transition operations with tokens.
28
- 4. **Mailbox** — add worker inbox/leader inbox files and delivery state.
29
- 5. **Live workers** — only after the above contracts are stable.
30
-
31
- ## Non-goals for now
32
-
33
- - No always-on background worker pool.
34
- - No automatic destructive cleanup of dirty worktrees.
35
- - No recursive team spawning by workers.
36
- - No mailbox mutation without locks and schema validation.
1
+ # Live Mailbox Runtime Direction
2
+
3
+ `pi-crew` currently uses workflow child-process orchestration: a run materializes tasks, executes them through the scheduler, writes artifacts/events, and optionally launches child Pi workers.
4
+
5
+ A full live mailbox runtime is intentionally out of scope for the current stable surface. Current foundational mailbox files are intentionally simple and local:
6
+
7
+ ```text
8
+ {stateRoot}/mailbox/inbox.jsonl
9
+ {stateRoot}/mailbox/outbox.jsonl
10
+ {stateRoot}/mailbox/delivery.json
11
+ {stateRoot}/mailbox/tasks/{taskId}/inbox.jsonl
12
+ {stateRoot}/mailbox/tasks/{taskId}/outbox.jsonl
13
+ ```
14
+
15
+ They are exposed through safe API operations (`read-mailbox`, `send-message`, `ack-message`, `read-delivery`, `validate-mailbox`) but do not yet imply always-on long-lived workers. If a full runtime is added later, it should build on the foundations already present:
16
+
17
+ - `src/state/contracts.ts` for status/event contracts
18
+ - `src/state/task-claims.ts` for claim/lease safety
19
+ - `src/runtime/worker-heartbeat.ts` for liveness
20
+ - `src/state/locks.ts` for run-level mutation safety
21
+ - `action: "api"` for safe interop boundaries
22
+
23
+ ## Proposed phases
24
+
25
+ 1. **Read-only interop** — already started with `api` operations.
26
+ 2. **Heartbeat writers** — allow workers to update heartbeat/progress safely.
27
+ 3. **Claim-safe task lifecycle** — expose claim/release/transition operations with tokens.
28
+ 4. **Mailbox** — add worker inbox/leader inbox files and delivery state.
29
+ 5. **Live workers** — only after the above contracts are stable.
30
+
31
+ ## Non-goals for now
32
+
33
+ - No always-on background worker pool.
34
+ - No automatic destructive cleanup of dirty worktrees.
35
+ - No recursive team spawning by workers.
36
+ - No mailbox mutation without locks and schema validation.