pi-crew 0.9.16 → 0.9.17

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 (432) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/README.md +19 -0
  3. package/dist/build-meta.json +21790 -0
  4. package/dist/index.mjs +83070 -0
  5. package/dist/index.mjs.map +7 -0
  6. package/docs/A +358 -0
  7. package/docs/M-A +357 -0
  8. package/docs/REVIEW-FINDINGS-2026-06 +357 -0
  9. package/docs/Y +357 -0
  10. package/docs/a +357 -0
  11. package/docs/aA +358 -0
  12. package/docs/archive/README.md +91 -0
  13. package/docs/patterns/command-agent-skill.md +1 -1
  14. package/docs/skills/REFERENCE.md +0 -17
  15. package/docs//303/242mmaAAA/303/242 +357 -0
  16. package/index.bundle.ts +25 -0
  17. package/index.ts +95 -4
  18. package/package.json +15 -4
  19. package/skills/iterative-audit/SKILL.md +0 -1
  20. package/skills/widget-rendering/SKILL.md +17 -0
  21. package/src/adapters/claude-adapter.ts +1 -3
  22. package/src/adapters/export-util.ts +16 -16
  23. package/src/adapters/index.ts +5 -5
  24. package/src/agents/agent-config.ts +20 -14
  25. package/src/agents/agent-serializer.ts +1 -1
  26. package/src/agents/discover-agents.ts +83 -39
  27. package/src/benchmark/benchmark-runner.ts +51 -51
  28. package/src/benchmark/feedback-loop.ts +1 -1
  29. package/src/config/config.ts +166 -590
  30. package/src/config/defaults.ts +28 -2
  31. package/src/config/drift-detector.ts +11 -14
  32. package/src/config/markers.ts +201 -203
  33. package/src/config/resilient-parser.ts +14 -6
  34. package/src/config/role-tools.ts +3 -3
  35. package/src/config/suggestions.ts +5 -12
  36. package/src/config/types.ts +9 -25
  37. package/src/errors.ts +151 -157
  38. package/src/extension/action-suggestions.ts +54 -9
  39. package/src/extension/async-notifier.ts +43 -13
  40. package/src/extension/autonomous-policy.ts +77 -37
  41. package/src/extension/command-completions.ts +9 -8
  42. package/src/extension/context-status-injection.ts +14 -12
  43. package/src/extension/crew-autocomplete.ts +8 -16
  44. package/src/extension/crew-cleanup.ts +2 -1
  45. package/src/extension/crew-shortcuts.ts +9 -6
  46. package/src/extension/cross-extension-rpc.ts +136 -42
  47. package/src/extension/help.ts +1 -1
  48. package/src/extension/import-index.ts +10 -5
  49. package/src/extension/knowledge-injection.ts +88 -15
  50. package/src/extension/management.ts +89 -349
  51. package/src/extension/message-renderers.ts +3 -4
  52. package/src/extension/notification-router.ts +22 -5
  53. package/src/extension/notification-sink.ts +6 -3
  54. package/src/extension/pi-api.ts +17 -8
  55. package/src/extension/plan-orchestrate.ts +8 -27
  56. package/src/extension/project-init.ts +21 -6
  57. package/src/extension/register.ts +329 -975
  58. package/src/extension/registration/artifact-cleanup.ts +9 -4
  59. package/src/extension/registration/command-utils.ts +5 -1
  60. package/src/extension/registration/commands.ts +806 -314
  61. package/src/extension/registration/compaction-guard.ts +15 -15
  62. package/src/extension/registration/lifecycle.ts +259 -0
  63. package/src/extension/registration/observability.ts +293 -0
  64. package/src/extension/registration/subagent-helpers.ts +29 -7
  65. package/src/extension/registration/subagent-tools.ts +253 -44
  66. package/src/extension/registration/team-tool.ts +19 -84
  67. package/src/extension/registration/ui.ts +168 -0
  68. package/src/extension/registration/viewers.ts +64 -24
  69. package/src/extension/result-watcher.ts +18 -7
  70. package/src/extension/run-bundle-schema.ts +21 -6
  71. package/src/extension/run-export.ts +15 -6
  72. package/src/extension/run-import.ts +64 -29
  73. package/src/extension/run-index.ts +28 -9
  74. package/src/extension/run-maintenance.ts +32 -12
  75. package/src/extension/session-summary.ts +1 -1
  76. package/src/extension/team-manager-command.ts +64 -7
  77. package/src/extension/team-onboard.ts +151 -150
  78. package/src/extension/team-recommendation.ts +121 -21
  79. package/src/extension/team-tool/anchor.ts +31 -64
  80. package/src/extension/team-tool/api.ts +929 -141
  81. package/src/extension/team-tool/auto-summarize.ts +14 -26
  82. package/src/extension/team-tool/cache-control.ts +1 -5
  83. package/src/extension/team-tool/cancel.ts +138 -38
  84. package/src/extension/team-tool/chain-dispatch.ts +5 -13
  85. package/src/extension/team-tool/chain-executor.ts +29 -51
  86. package/src/extension/team-tool/config-patch.ts +1 -1
  87. package/src/extension/team-tool/context.ts +40 -20
  88. package/src/extension/team-tool/destructive-gate.ts +10 -5
  89. package/src/extension/team-tool/doctor.ts +170 -51
  90. package/src/extension/team-tool/explain.ts +228 -214
  91. package/src/extension/team-tool/failure-patterns.ts +3 -9
  92. package/src/extension/team-tool/goal-wrap.ts +71 -29
  93. package/src/extension/team-tool/goal.ts +185 -35
  94. package/src/extension/team-tool/handle-schedule.ts +34 -15
  95. package/src/extension/team-tool/handle-settings.ts +94 -56
  96. package/src/extension/team-tool/health-monitor.ts +27 -108
  97. package/src/extension/team-tool/inspect.ts +42 -9
  98. package/src/extension/team-tool/intent-policy.ts +4 -1
  99. package/src/extension/team-tool/lifecycle-actions.ts +244 -48
  100. package/src/extension/team-tool/orchestrate.ts +7 -18
  101. package/src/extension/team-tool/parallel-dispatch.ts +51 -29
  102. package/src/extension/team-tool/plan.ts +29 -5
  103. package/src/extension/team-tool/respond.ts +49 -16
  104. package/src/extension/team-tool/run-not-found.ts +3 -8
  105. package/src/extension/team-tool/run.ts +80 -317
  106. package/src/extension/team-tool/status.ts +135 -43
  107. package/src/extension/team-tool/workflow-manage.ts +92 -25
  108. package/src/extension/team-tool-types.ts +8 -1
  109. package/src/extension/team-tool.ts +142 -551
  110. package/src/extension/validate-resources.ts +39 -8
  111. package/src/hooks/registry.ts +66 -17
  112. package/src/hooks/types.ts +1 -1
  113. package/src/i18n.ts +25 -11
  114. package/src/observability/correlation.ts +17 -3
  115. package/src/observability/event-bus.ts +51 -56
  116. package/src/observability/event-to-metric.ts +117 -15
  117. package/src/observability/exporters/otlp-exporter.ts +56 -17
  118. package/src/observability/exporters/prometheus-exporter.ts +1 -1
  119. package/src/observability/metric-registry.ts +16 -4
  120. package/src/observability/metric-retention.ts +8 -2
  121. package/src/observability/metric-sink.ts +11 -3
  122. package/src/observability/metrics-primitives.ts +42 -9
  123. package/src/plugins/plugin-define.ts +2 -2
  124. package/src/plugins/plugin-registry.ts +25 -25
  125. package/src/plugins/plugins/index.ts +1 -1
  126. package/src/plugins/plugins/nextjs.ts +16 -16
  127. package/src/plugins/plugins/vite.ts +7 -11
  128. package/src/plugins/plugins/vitest.ts +6 -11
  129. package/src/runtime/adaptive-plan.ts +225 -40
  130. package/src/runtime/agent-control.ts +58 -15
  131. package/src/runtime/agent-memory.ts +15 -9
  132. package/src/runtime/agent-observability.ts +10 -2
  133. package/src/runtime/anchor-manager.ts +27 -25
  134. package/src/runtime/async-marker.ts +7 -1
  135. package/src/runtime/async-runner.ts +27 -23
  136. package/src/runtime/auto-summarize.ts +7 -13
  137. package/src/runtime/background-runner.ts +189 -251
  138. package/src/runtime/batch-barrier.ts +18 -16
  139. package/src/runtime/cancellation-token.ts +16 -6
  140. package/src/runtime/cancellation.ts +46 -8
  141. package/src/runtime/capability-inventory.ts +6 -4
  142. package/src/runtime/chain-parser.ts +44 -11
  143. package/src/runtime/chain-runner.ts +63 -69
  144. package/src/runtime/checkpoint.ts +12 -56
  145. package/src/runtime/child-pi.ts +343 -78
  146. package/src/runtime/coalesce-tasks.ts +268 -0
  147. package/src/runtime/code-summary.ts +71 -26
  148. package/src/runtime/compact-stages/index.ts +15 -5
  149. package/src/runtime/compact-stages/tail-capture-stage.ts +7 -2
  150. package/src/runtime/compact-stages/truncation-stage.ts +4 -1
  151. package/src/runtime/compaction-summary.ts +17 -10
  152. package/src/runtime/completion-guard.ts +33 -16
  153. package/src/runtime/crash-classification.ts +28 -7
  154. package/src/runtime/crash-recovery.ts +177 -37
  155. package/src/runtime/crew-agent-records.ts +145 -47
  156. package/src/runtime/crew-hooks.ts +9 -24
  157. package/src/runtime/cross-extension-rpc.ts +25 -23
  158. package/src/runtime/custom-tools/irc-tool.ts +43 -15
  159. package/src/runtime/custom-tools/submit-result-tool.ts +16 -5
  160. package/src/runtime/delivery-coordinator.ts +34 -7
  161. package/src/runtime/delta-conflict.ts +9 -21
  162. package/src/runtime/deterministic-ast.ts +1 -1
  163. package/src/runtime/diagnostic-export.ts +53 -20
  164. package/src/runtime/direct-run.ts +12 -2
  165. package/src/runtime/dwf-state-store.ts +1 -1
  166. package/src/runtime/dynamic-workflow-context.ts +186 -58
  167. package/src/runtime/dynamic-workflow-runner.ts +42 -20
  168. package/src/runtime/effectiveness.ts +16 -8
  169. package/src/runtime/errors/crew-errors.ts +7 -11
  170. package/src/runtime/event-stream-bridge.ts +9 -3
  171. package/src/runtime/foreground-control.ts +54 -14
  172. package/src/runtime/foreground-watchdog.ts +9 -6
  173. package/src/runtime/goal-achievement.ts +27 -10
  174. package/src/runtime/goal-evaluator.ts +54 -19
  175. package/src/runtime/goal-loop-runner.ts +280 -99
  176. package/src/runtime/goal-state-store.ts +27 -17
  177. package/src/runtime/green-contract.ts +11 -2
  178. package/src/runtime/group-join.ts +64 -31
  179. package/src/runtime/handoff-manager.ts +37 -42
  180. package/src/runtime/heartbeat-gradient.ts +10 -2
  181. package/src/runtime/heartbeat-watcher.ts +32 -6
  182. package/src/runtime/hidden-handoff.ts +12 -30
  183. package/src/runtime/important-line-classifier.ts +12 -2
  184. package/src/runtime/iteration-hooks.ts +25 -15
  185. package/src/runtime/live-agent-control.ts +55 -7
  186. package/src/runtime/live-agent-manager.ts +130 -27
  187. package/src/runtime/live-control-realtime.ts +23 -3
  188. package/src/runtime/live-irc.ts +4 -1
  189. package/src/runtime/live-session-health.ts +12 -4
  190. package/src/runtime/live-session-runtime.ts +379 -117
  191. package/src/runtime/manifest-cache.ts +28 -12
  192. package/src/runtime/mcp-proxy.ts +8 -16
  193. package/src/runtime/metric-parser.ts +1 -5
  194. package/src/runtime/model-fallback.ts +55 -18
  195. package/src/runtime/model-resolver.ts +2 -6
  196. package/src/runtime/model-scope.ts +19 -3
  197. package/src/runtime/notebook-helpers.ts +60 -62
  198. package/src/runtime/orphan-worker-registry.ts +37 -26
  199. package/src/runtime/output-validator.ts +18 -3
  200. package/src/runtime/overflow-recovery.ts +5 -4
  201. package/src/runtime/parallel-research.ts +29 -5
  202. package/src/runtime/parallel-utils.ts +9 -11
  203. package/src/runtime/path-overlap.ts +150 -0
  204. package/src/runtime/peer-dep.ts +12 -17
  205. package/src/runtime/per-write-validator.ts +1 -3
  206. package/src/runtime/phase-tracker.ts +342 -330
  207. package/src/runtime/pi-args.ts +26 -8
  208. package/src/runtime/pi-json-output.ts +1 -1
  209. package/src/runtime/pi-spawn.ts +30 -19
  210. package/src/runtime/pipeline-runner.ts +56 -55
  211. package/src/runtime/plan-templates.ts +5 -6
  212. package/src/runtime/policy-engine.ts +43 -7
  213. package/src/runtime/post-checks.ts +12 -4
  214. package/src/runtime/post-exit-stdio-guard.ts +2 -2
  215. package/src/runtime/process-lifecycle.ts +20 -10
  216. package/src/runtime/process-status.ts +16 -5
  217. package/src/runtime/progress-event-coalescer.ts +2 -1
  218. package/src/runtime/progress-tracker.ts +103 -103
  219. package/src/runtime/prose-compressor.ts +9 -11
  220. package/src/runtime/recovery-recipes.ts +118 -24
  221. package/src/runtime/replace.ts +25 -10
  222. package/src/runtime/resilient-edit.ts +10 -25
  223. package/src/runtime/result-extractor.ts +1 -2
  224. package/src/runtime/retry-executor.ts +20 -4
  225. package/src/runtime/retry-runner.ts +26 -50
  226. package/src/runtime/role-permission.ts +6 -1
  227. package/src/runtime/run-coalesced-task-group.ts +256 -0
  228. package/src/runtime/run-drift.ts +14 -15
  229. package/src/runtime/run-tracker.ts +6 -28
  230. package/src/runtime/runtime-policy.ts +1 -6
  231. package/src/runtime/runtime-resolver.ts +80 -15
  232. package/src/runtime/scheduler.ts +47 -18
  233. package/src/runtime/semaphore.ts +5 -7
  234. package/src/runtime/sensitive-paths.ts +2 -1
  235. package/src/runtime/session-usage.ts +1 -1
  236. package/src/runtime/settings-store.ts +16 -12
  237. package/src/runtime/sidechain-output.ts +6 -2
  238. package/src/runtime/single-agent-compose.ts +1 -4
  239. package/src/runtime/skill-effectiveness.ts +29 -97
  240. package/src/runtime/skill-instructions.ts +40 -83
  241. package/src/runtime/stale-reconciler.ts +73 -197
  242. package/src/runtime/stream-preview.ts +1 -1
  243. package/src/runtime/streaming-output.ts +1 -1
  244. package/src/runtime/subagent-manager.ts +44 -169
  245. package/src/runtime/subprocess-tool-registry.ts +4 -1
  246. package/src/runtime/supervisor-contact.ts +10 -5
  247. package/src/runtime/task-display.ts +19 -5
  248. package/src/runtime/task-graph-scheduler.ts +95 -21
  249. package/src/runtime/task-graph.ts +5 -11
  250. package/src/runtime/task-health.ts +54 -47
  251. package/src/runtime/task-id.ts +11 -18
  252. package/src/runtime/task-output-context.ts +265 -81
  253. package/src/runtime/task-packet.ts +12 -20
  254. package/src/runtime/task-quality.ts +6 -14
  255. package/src/runtime/task-runner/context-retrieval.ts +4 -13
  256. package/src/runtime/task-runner/live-executor.ts +114 -36
  257. package/src/runtime/task-runner/output-splitter.ts +152 -0
  258. package/src/runtime/task-runner/progress.ts +50 -12
  259. package/src/runtime/task-runner/prompt-builder.ts +31 -7
  260. package/src/runtime/task-runner/prompt-pipeline.ts +31 -7
  261. package/src/runtime/task-runner/result-utils.ts +3 -1
  262. package/src/runtime/task-runner/retrieval-orchestrator.ts +310 -0
  263. package/src/runtime/task-runner/run-projection.ts +27 -8
  264. package/src/runtime/task-runner/state-helpers.ts +29 -8
  265. package/src/runtime/task-runner/tail-read.ts +2 -6
  266. package/src/runtime/task-runner.ts +180 -326
  267. package/src/runtime/team-runner-artifacts.ts +13 -0
  268. package/src/runtime/team-runner.ts +456 -974
  269. package/src/runtime/tool-output-pruner.ts +6 -9
  270. package/src/runtime/tool-progress.ts +11 -21
  271. package/src/runtime/verification-gates.ts +33 -24
  272. package/src/runtime/verification-integrity.ts +1 -4
  273. package/src/runtime/verification-worktree.ts +62 -12
  274. package/src/runtime/worker-heartbeat.ts +5 -1
  275. package/src/runtime/worker-startup.ts +29 -5
  276. package/src/runtime/workflow-state.ts +17 -9
  277. package/src/runtime/workspace-lock.ts +30 -35
  278. package/src/runtime/workspace-tree.ts +20 -32
  279. package/src/runtime/yield-handler.ts +43 -9
  280. package/src/runtime/zombie-scanner.ts +5 -4
  281. package/src/schema/config-schema.ts +266 -172
  282. package/src/schema/team-tool-schema.ts +29 -74
  283. package/src/schema/validation-types.ts +25 -17
  284. package/src/skills/discover-skills.ts +35 -10
  285. package/src/skills/skill-templates.ts +109 -27
  286. package/src/skills/validate.ts +26 -8
  287. package/src/state/active-run-registry.ts +87 -28
  288. package/src/state/artifact-store.ts +9 -5
  289. package/src/state/atomic-write-v2.ts +85 -63
  290. package/src/state/atomic-write.ts +105 -26
  291. package/src/state/blob-store.ts +47 -20
  292. package/src/state/contracts.ts +20 -5
  293. package/src/state/crew-init.ts +5 -22
  294. package/src/state/decision-ledger.ts +19 -73
  295. package/src/state/event-log-rotation.ts +41 -15
  296. package/src/state/event-log.ts +168 -53
  297. package/src/state/event-reconstructor.ts +11 -1
  298. package/src/state/gitignore-manager.ts +2 -8
  299. package/src/state/health-store.ts +57 -57
  300. package/src/state/hook-instinct-bridge.ts +1 -1
  301. package/src/state/hook-integrations.ts +1 -1
  302. package/src/state/instinct-store.ts +17 -5
  303. package/src/state/jsonl-writer.ts +1 -1
  304. package/src/state/locks.ts +23 -9
  305. package/src/state/mailbox.ts +151 -28
  306. package/src/state/observation-store.ts +20 -14
  307. package/src/state/run-cache.ts +142 -135
  308. package/src/state/run-graph.ts +6 -15
  309. package/src/state/run-metrics.ts +5 -18
  310. package/src/state/schedule.ts +15 -9
  311. package/src/state/state-store.ts +129 -45
  312. package/src/state/task-claims.ts +12 -2
  313. package/src/state/tiered-eval.ts +52 -43
  314. package/src/state/types-eval.ts +2 -2
  315. package/src/state/types.ts +24 -20
  316. package/src/state/usage.ts +20 -4
  317. package/src/state/worker-atomic-writer.ts +6 -3
  318. package/src/subagents/index.ts +2 -2
  319. package/src/teams/discover-teams.ts +21 -6
  320. package/src/tools/safe-bash-extension.ts +5 -6
  321. package/src/tools/safe-bash.ts +10 -11
  322. package/src/types/new-api-types.ts +6 -10
  323. package/src/ui/agent-management-overlay.ts +52 -40
  324. package/src/ui/card-colors.ts +13 -4
  325. package/src/ui/crew-footer.ts +8 -7
  326. package/src/ui/crew-select-list.ts +1 -1
  327. package/src/ui/dashboard-panes/agents-pane.ts +41 -25
  328. package/src/ui/dashboard-panes/cancellation-pane.ts +1 -1
  329. package/src/ui/dashboard-panes/capability-pane.ts +32 -15
  330. package/src/ui/dashboard-panes/health-pane.ts +2 -1
  331. package/src/ui/dashboard-panes/metrics-pane.ts +4 -1
  332. package/src/ui/dashboard-panes/progress-pane.ts +12 -9
  333. package/src/ui/heartbeat-aggregator.ts +15 -4
  334. package/src/ui/keybinding-map.ts +40 -7
  335. package/src/ui/live-conversation-overlay.ts +36 -20
  336. package/src/ui/live-duration.ts +1 -4
  337. package/src/ui/live-run-sidebar.ts +88 -25
  338. package/src/ui/loaders.ts +2 -8
  339. package/src/ui/mascot.ts +20 -36
  340. package/src/ui/overlays/agent-picker-overlay.ts +11 -3
  341. package/src/ui/overlays/confirm-overlay.ts +4 -2
  342. package/src/ui/overlays/help-overlay.ts +25 -14
  343. package/src/ui/overlays/mailbox-compose-overlay.ts +48 -11
  344. package/src/ui/overlays/mailbox-compose-preview.ts +20 -5
  345. package/src/ui/overlays/mailbox-detail-overlay.ts +27 -6
  346. package/src/ui/pi-ui-compat.ts +7 -7
  347. package/src/ui/powerbar-publisher.ts +120 -42
  348. package/src/ui/render-diff.ts +10 -3
  349. package/src/ui/render-scheduler.ts +12 -4
  350. package/src/ui/run-action-dispatcher.ts +81 -18
  351. package/src/ui/run-dashboard.ts +172 -76
  352. package/src/ui/run-event-bus.ts +59 -37
  353. package/src/ui/run-snapshot-cache.ts +276 -86
  354. package/src/ui/settings-overlay.ts +361 -74
  355. package/src/ui/status-colors.ts +12 -1
  356. package/src/ui/syntax-highlight.ts +1 -1
  357. package/src/ui/theme-adapter.ts +16 -14
  358. package/src/ui/theme-discovery.ts +13 -2
  359. package/src/ui/tool-progress-formatter.ts +7 -7
  360. package/src/ui/tool-render.ts +128 -56
  361. package/src/ui/tool-renderers/brief-mode.ts +45 -27
  362. package/src/ui/tool-renderers/index.ts +109 -43
  363. package/src/ui/transcript-cache.ts +32 -6
  364. package/src/ui/transcript-entries.ts +25 -23
  365. package/src/ui/transcript-viewer.ts +78 -29
  366. package/src/ui/widget/index.ts +99 -40
  367. package/src/ui/widget/widget-formatters.ts +13 -6
  368. package/src/ui/widget/widget-model.ts +19 -8
  369. package/src/ui/widget/widget-renderer.ts +23 -13
  370. package/src/ui/widget/widget-types.ts +1 -1
  371. package/src/utils/bm25-search.ts +199 -199
  372. package/src/utils/conflict-detect.ts +22 -21
  373. package/src/utils/env-filter.ts +14 -7
  374. package/src/utils/file-coalescer.ts +5 -1
  375. package/src/utils/fingerprint.ts +3 -6
  376. package/src/utils/frontmatter.ts +3 -1
  377. package/src/utils/fs-watch.ts +2 -6
  378. package/src/utils/gh-protocol.ts +119 -44
  379. package/src/utils/git.ts +13 -15
  380. package/src/utils/guards.ts +2 -5
  381. package/src/utils/ids.ts +9 -2
  382. package/src/utils/incremental-reader.ts +14 -3
  383. package/src/utils/internal-error.ts +2 -1
  384. package/src/utils/names.ts +12 -3
  385. package/src/utils/paths.ts +49 -5
  386. package/src/utils/project-detector.ts +2 -2
  387. package/src/utils/redaction.ts +29 -19
  388. package/src/utils/resolve-shell.ts +9 -7
  389. package/src/utils/run-watcher-registry.ts +19 -31
  390. package/src/utils/safe-paths.ts +45 -24
  391. package/src/utils/scan-cache.ts +9 -2
  392. package/src/utils/session-utils.ts +2 -4
  393. package/src/utils/sleep.ts +12 -5
  394. package/src/utils/sse-parser.ts +5 -17
  395. package/src/utils/visual.ts +52 -32
  396. package/src/workflows/discover-workflows.ts +41 -109
  397. package/src/workflows/intermediate-store.ts +5 -21
  398. package/src/workflows/preflight-validator.ts +6 -33
  399. package/src/workflows/topology-analyzer.ts +5 -21
  400. package/src/workflows/workflow-config.ts +7 -6
  401. package/src/worktree/branch-freshness.ts +66 -8
  402. package/src/worktree/cleanup.ts +130 -20
  403. package/src/worktree/worktree-manager.ts +212 -69
  404. package/skills/artifact-analysis-loop/SKILL.md +0 -303
  405. package/skills/detection-pipeline-design/SKILL.md +0 -286
  406. package/skills/hunting-investigation-loop/SKILL.md +0 -402
  407. package/skills/incident-playbook-construction/SKILL.md +0 -384
  408. package/skills/security-review/SKILL.md +0 -561
  409. package/skills/threat-hypothesis-framework/SKILL.md +0 -176
  410. package/skills/ui-render-performance/SKILL.md +0 -58
  411. /package/docs/{followup-review-round3-2026-05-12.md → archive/followup-review-round3-2026-05-12.md} +0 -0
  412. /package/docs/{followup-review-round4-2026-05-13.md → archive/followup-review-round4-2026-05-13.md} +0 -0
  413. /package/docs/{pi-crew-bugs.md → archive/pi-crew-bugs.md} +0 -0
  414. /package/docs/{pi-crew-test-final.md → archive/pi-crew-test-final.md} +0 -0
  415. /package/docs/{pi-crew-test-results.md → archive/pi-crew-test-results.md} +0 -0
  416. /package/docs/{pi-crew-test-round2.md → archive/pi-crew-test-round2.md} +0 -0
  417. /package/docs/{pi-crew-test-round4.md → archive/pi-crew-test-round4.md} +0 -0
  418. /package/docs/{pi-crew-test-round5.md → archive/pi-crew-test-round5.md} +0 -0
  419. /package/docs/{pi-crew-test-round6.md → archive/pi-crew-test-round6.md} +0 -0
  420. /package/docs/{pi-crew-v0.5.10-audit-fix-plan.md → archive/pi-crew-v0.5.10-audit-fix-plan.md} +0 -0
  421. /package/docs/{pi-crew-v0.5.11-audit-fix-plan.md → archive/pi-crew-v0.5.11-audit-fix-plan.md} +0 -0
  422. /package/docs/{pi-crew-v0.5.12-audit-fix-plan.md → archive/pi-crew-v0.5.12-audit-fix-plan.md} +0 -0
  423. /package/docs/{pi-crew-v0.5.13-audit-fix-plan.md → archive/pi-crew-v0.5.13-audit-fix-plan.md} +0 -0
  424. /package/docs/{pi-crew-v0.5.14-audit-fix-plan.md → archive/pi-crew-v0.5.14-audit-fix-plan.md} +0 -0
  425. /package/docs/{pi-crew-v0.5.16-audit-fix-plan.md → archive/pi-crew-v0.5.16-audit-fix-plan.md} +0 -0
  426. /package/docs/{pi-crew-v0.5.17-audit-fix-plan.md → archive/pi-crew-v0.5.17-audit-fix-plan.md} +0 -0
  427. /package/docs/{pi-crew-v0.5.5-audit-fix-plan.md → archive/pi-crew-v0.5.5-audit-fix-plan.md} +0 -0
  428. /package/docs/{pi-crew-v0.5.9-audit-fix-plan.md → archive/pi-crew-v0.5.9-audit-fix-plan.md} +0 -0
  429. /package/docs/{pi-mono-opportunities.md → archive/pi-mono-opportunities.md} +0 -0
  430. /package/docs/{pi-mono-review.md → archive/pi-mono-review.md} +0 -0
  431. /package/docs/{pi-subagent4-comparison.md → archive/pi-subagent4-comparison.md} +0 -0
  432. /package/docs/{pi-subagents3-deep-analysis.md → archive/pi-subagents3-deep-analysis.md} +0 -0
@@ -0,0 +1,310 @@
1
+ /**
2
+ * M3: Iterative file-retrieval orchestrator.
3
+ *
4
+ * Pattern: workers progressively discover relevant context files
5
+ * (e.g. "which source file handles X?") using ripgrep-driven keyword
6
+ * search + the existing context-retrieval.ts scoring/convergence
7
+ * helpers. Max 3 cycles, fall back to in-memory heuristic when
8
+ * ripgrep is not available (e.g. minimal Windows CI runners).
9
+ *
10
+ * Signal flow:
11
+ * renderTaskPrompt (in prompt-builder.ts)
12
+ * → runRetrievalCycle(task, goal, cwd)
13
+ * → cycle 1: rg --files, then score each file
14
+ * → cycle 2: refine query, rg --json for keyword filter
15
+ * → cycle 3: same; if !shouldContinue, stop early
16
+ * → returns top-N files (5..10)
17
+ * renderTaskPrompt injects "Suggested files to read (top-N by
18
+ * retrieval score):" section before final prompt assembly.
19
+ *
20
+ * Production code path — not @experimental. Fallback is mandatory so
21
+ * the prompt is never blocked by a missing ripgrep binary.
22
+ */
23
+ import { spawn } from "node:child_process";
24
+ import * as fs from "node:fs";
25
+ import * as path from "node:path";
26
+ import type { RelevanceEvaluation } from "./context-retrieval.ts";
27
+ import { hasConverged, scoreRelevance, shouldContinue } from "./context-retrieval.ts";
28
+
29
+ /** Max retrieval cycles per prompt render. Matches context-retrieval.MAX_CYCLES. */
30
+ export const MAX_CYCLES = 3;
31
+
32
+ /** Hard cap on suggested files injected into the worker prompt. */
33
+ export const MAX_SUGGESTED_FILES = 10;
34
+
35
+ /** Minimum files suggested when retrieval returns anything. */
36
+ export const MIN_SUGGESTED_FILES = 5;
37
+
38
+ /** Stopwords dropped during keyword tokenization (lowercase comparison). */
39
+ const STOPWORDS: ReadonlySet<string> = new Set(["the", "a", "an", "and", "or", "to", "of", "in", "for", "on", "is", "are", "be", "with"]);
40
+
41
+ /** File extensions considered relevant for retrieval. */
42
+ const RELEVANT_EXTS: ReadonlySet<string> = new Set([
43
+ ".ts",
44
+ ".tsx",
45
+ ".js",
46
+ ".jsx",
47
+ ".mjs",
48
+ ".cjs",
49
+ ".md",
50
+ ".markdown",
51
+ ".json",
52
+ ".yaml",
53
+ ".yml",
54
+ ]);
55
+
56
+ /** Result of a single runRetrievalCycle call. */
57
+ export interface RetrievalResult {
58
+ files: Array<{ path: string; score: number; reason: string }>;
59
+ cycles: number;
60
+ converged: boolean;
61
+ usedFallback: boolean;
62
+ }
63
+
64
+ interface RipgrepAvailable {
65
+ available: boolean;
66
+ version?: string;
67
+ }
68
+
69
+ let cachedRgCheck: RipgrepAvailable | undefined;
70
+
71
+ /**
72
+ * Detect ripgrep availability once per process. Uses `rg --version` and
73
+ * catches ENOENT or non-zero exit. Cached so the cost (one spawn) is
74
+ * paid only on the first retrieval cycle.
75
+ */
76
+ export async function detectRipgrep(): Promise<RipgrepAvailable> {
77
+ if (cachedRgCheck !== undefined) return cachedRgCheck;
78
+ return await new Promise<RipgrepAvailable>((resolve) => {
79
+ let settled = false;
80
+ try {
81
+ const child = spawn("rg", ["--version"], { stdio: ["ignore", "pipe", "pipe"] });
82
+ let stdout = "";
83
+ child.stdout?.on("data", (chunk) => {
84
+ stdout += chunk.toString("utf-8");
85
+ });
86
+ child.on("error", () => {
87
+ if (settled) return;
88
+ settled = true;
89
+ cachedRgCheck = { available: false };
90
+ resolve(cachedRgCheck);
91
+ });
92
+ child.on("close", (code) => {
93
+ if (settled) return;
94
+ settled = true;
95
+ if (code === 0) {
96
+ cachedRgCheck = { available: true, version: stdout.split("\n")[0] ?? undefined };
97
+ } else {
98
+ cachedRgCheck = { available: false };
99
+ }
100
+ resolve(cachedRgCheck);
101
+ });
102
+ } catch {
103
+ if (settled) return;
104
+ settled = true;
105
+ cachedRgCheck = { available: false };
106
+ resolve(cachedRgCheck);
107
+ }
108
+ });
109
+ }
110
+
111
+ /** @internal Test-only: reset the ripgrep detection cache. */
112
+ export function __test_resetRipgrepCache(): void {
113
+ cachedRgCheck = undefined;
114
+ }
115
+
116
+ /**
117
+ * Tokenize a task + goal string into lowercase keywords, dropping
118
+ * stopwords. Single-letter tokens and pure-punctuation tokens are
119
+ * dropped. Output is deduped, original-order preserved.
120
+ */
121
+ export function tokenizeQuery(task: string, goal: string): string[] {
122
+ const combined = `${task}\n${goal}`.toLowerCase();
123
+ const tokens = combined
124
+ .split(/[^a-z0-9_-]+/)
125
+ .map((t) => t.trim())
126
+ .filter((t) => t.length >= 2 && !STOPWORDS.has(t));
127
+ return [...new Set(tokens)];
128
+ }
129
+
130
+ /** Reason template for a discovery hit. Exported for tests. */
131
+ export function reasonFor(file: string, keywords: string[]): string {
132
+ const lower = file.toLowerCase();
133
+ const hits = keywords.filter((k) => lower.includes(k));
134
+ if (hits.length === 0) return `matched by relevance score (no direct keyword hit in path)`;
135
+ return `keyword match: ${hits.join(", ")}`;
136
+ }
137
+
138
+ /**
139
+ * Run ripgrep with the given args, returning stdout as a string.
140
+ * Throws on ENOENT / non-zero exit. Caller handles fallback.
141
+ */
142
+ function runRipgrep(args: string[], cwd: string): Promise<string> {
143
+ return new Promise<string>((resolve, reject) => {
144
+ let settled = false;
145
+ let stdout = "";
146
+ let stderr = "";
147
+ try {
148
+ const child = spawn("rg", args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
149
+ child.stdout?.on("data", (chunk) => {
150
+ stdout += chunk.toString("utf-8");
151
+ });
152
+ child.stderr?.on("data", (chunk) => {
153
+ stderr += chunk.toString("utf-8");
154
+ });
155
+ child.on("error", (err) => {
156
+ if (settled) return;
157
+ settled = true;
158
+ reject(err);
159
+ });
160
+ child.on("close", (code) => {
161
+ if (settled) return;
162
+ settled = true;
163
+ // rg exit code 1 = "no matches" (NOT an error). Any other
164
+ // non-zero exit IS an error.
165
+ if (code === 0 || code === 1) {
166
+ resolve(stdout);
167
+ } else {
168
+ reject(new Error(`rg exited ${code}: ${stderr.slice(0, 200)}`));
169
+ }
170
+ });
171
+ } catch (e) {
172
+ if (settled) return;
173
+ settled = true;
174
+ reject(e);
175
+ }
176
+ });
177
+ }
178
+
179
+ /**
180
+ * In-memory fallback: walk cwd with readdir({recursive:true}), filter
181
+ * to relevant extensions, score by filename keyword match. Used when
182
+ * ripgrep is not installed. Mirrors the rg --files path closely so
183
+ * downstream scoring behaves the same.
184
+ */
185
+ async function walkFilesFallback(cwd: string, keywords: string[]): Promise<Array<{ path: string; score: number; reason: string }>> {
186
+ const out: Array<{ path: string; score: number; reason: string }> = [];
187
+ const lowerCwd = cwd.toLowerCase();
188
+ async function walk(dir: string): Promise<void> {
189
+ let entries: fs.Dirent[];
190
+ try {
191
+ entries = await fs.promises.readdir(dir, { withFileTypes: true });
192
+ } catch {
193
+ return;
194
+ }
195
+ for (const entry of entries) {
196
+ if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
197
+ const full = path.join(dir, entry.name);
198
+ if (entry.isDirectory()) {
199
+ await walk(full);
200
+ continue;
201
+ }
202
+ if (!entry.isFile()) continue;
203
+ const ext = path.extname(entry.name).toLowerCase();
204
+ if (!RELEVANT_EXTS.has(ext)) continue;
205
+ // scoreRelevance expects file content, but for the fallback we
206
+ // only have the filename. Use the filename as a proxy (the
207
+ // existing scoreRelevance handles short content gracefully —
208
+ // path match contributes 0.3, content match 0.05 × log2(N)).
209
+ const content = "";
210
+ const score = scoreRelevance(full, content, keywords);
211
+ if (score > 0) {
212
+ out.push({ path: path.relative(lowerCwd, full), score, reason: reasonFor(full, keywords) });
213
+ }
214
+ }
215
+ }
216
+ await walk(cwd);
217
+ return out;
218
+ }
219
+
220
+ /**
221
+ * Iterate up to MAX_CYCLES times. Each cycle: discover files, score
222
+ * them, check convergence. Stop early on convergence or when
223
+ * shouldContinue returns false.
224
+ */
225
+ export async function runRetrievalCycle(task: string, goal: string, cwd: string): Promise<RetrievalResult> {
226
+ const keywords = tokenizeQuery(task, goal);
227
+ if (keywords.length === 0) {
228
+ return { files: [], cycles: 0, converged: true, usedFallback: false };
229
+ }
230
+ const rg = await detectRipgrep();
231
+ const useRg = rg.available;
232
+ let usedFallback = !useRg;
233
+ const evaluations: RelevanceEvaluation[] = [];
234
+ let cycle = 0;
235
+ let converged = false;
236
+ for (; cycle < MAX_CYCLES; cycle++) {
237
+ let discovered: string[] = [];
238
+ try {
239
+ if (useRg) {
240
+ // Cycle 0: enumerate all relevant files via `rg --files`.
241
+ // Later cycles: filter by keywords via `rg --files | rg pattern`.
242
+ // We use the simpler `rg --files` + filter strategy because
243
+ // `rg --json` parsing adds complexity for marginal gain.
244
+ // `rg --files` respects .gitignore by default; we add an
245
+ // explicit -g '!node_modules' and -g '!.git' to be safe on
246
+ // repos that don't ignore them.
247
+ const stdout = await runRipgrep(["--files", "-g", "!node_modules", "-g", "!.git", cwd], cwd);
248
+ discovered = stdout
249
+ .split("\n")
250
+ .map((p) => p.trim())
251
+ .filter((p) => p && RELEVANT_EXTS.has(path.extname(p).toLowerCase()))
252
+ .map((p) => path.relative(cwd, p));
253
+ } else {
254
+ discovered = (await walkFilesFallback(cwd, keywords)).map((f) => f.path);
255
+ }
256
+ } catch {
257
+ // rg errored mid-run — switch to fallback for this cycle.
258
+ usedFallback = true;
259
+ discovered = (await walkFilesFallback(cwd, keywords)).map((f) => f.path);
260
+ }
261
+ // Score each discovered file. Path-only scoring (no file read) so
262
+ // we don't slow down prompt building for hundreds of files.
263
+ const seenInThisCycle = new Set<string>();
264
+ for (const relPath of discovered) {
265
+ if (seenInThisCycle.has(relPath)) continue;
266
+ seenInThisCycle.add(relPath);
267
+ const absPath = path.isAbsolute(relPath) ? relPath : path.join(cwd, relPath);
268
+ const score = scoreRelevance(absPath, "", keywords);
269
+ if (score > 0) {
270
+ evaluations.push({
271
+ path: absPath,
272
+ relevance: score,
273
+ reason: reasonFor(absPath, keywords),
274
+ missingContext: [],
275
+ });
276
+ }
277
+ }
278
+ converged = hasConverged(evaluations);
279
+ if (converged) break;
280
+ if (!shouldContinue(evaluations, cycle)) break;
281
+ }
282
+ // Sort by score desc, take top N (5..10).
283
+ evaluations.sort((a, b) => b.relevance - a.relevance);
284
+ const cap = Math.min(MAX_SUGGESTED_FILES, Math.max(MIN_SUGGESTED_FILES, evaluations.length));
285
+ const top = evaluations.slice(0, cap).map((e) => ({
286
+ path: path.isAbsolute(e.path) ? path.relative(cwd, e.path) : e.path,
287
+ score: e.relevance,
288
+ reason: e.reason,
289
+ }));
290
+ return { files: top, cycles: cycle, converged, usedFallback };
291
+ }
292
+
293
+ /**
294
+ * Render the "Suggested files to read" section for injection into the
295
+ * worker prompt. Returns an empty string when retrieval returned no
296
+ * files. Format is a markdown bullet list (one line per file) prefixed
297
+ * with a heading so the worker can `grep` for it.
298
+ */
299
+ export function renderSuggestedFilesSection(result: RetrievalResult): string {
300
+ if (result.files.length === 0) return "";
301
+ const lines: string[] = [
302
+ `# Suggested files to read (top-${result.files.length} by retrieval score)`,
303
+ `Retrieval ran for ${result.cycles} cycle(s)${result.usedFallback ? " (in-memory fallback, rg unavailable)" : ""}${result.converged ? " and converged" : ""}.`,
304
+ "",
305
+ ];
306
+ for (const file of result.files) {
307
+ lines.push(`- ${file.path} — ${file.reason} (score ${file.score.toFixed(2)})`);
308
+ }
309
+ return lines.join("\n");
310
+ }
@@ -1,6 +1,5 @@
1
- import type { TeamRunManifest, TeamTaskState } from "../../state/types.ts";
2
1
  import type { MailboxMessage } from "../../state/mailbox.ts";
3
- import type { ArtifactDescriptor } from "../../state/types.ts";
2
+ import type { ArtifactDescriptor, TeamRunManifest, TeamTaskState } from "../../state/types.ts";
4
3
 
5
4
  export interface RunProjectionSource {
6
5
  kind: "events" | "mailbox" | "artifacts" | "ui_metadata" | "runtime_metadata";
@@ -44,7 +43,11 @@ export function transformRunContextBeforeWorkerStart(input: {
44
43
  const completedTasks = input.tasks.filter((t) => t.status === "completed" || t.status === "failed");
45
44
  if (completedTasks.length > 0) {
46
45
  const tasks = completedTasks.slice(0, maxEvents);
47
- sources.push({ kind: "events", bounded: true, reference: `tasks:${tasks.length}/${completedTasks.length}` });
46
+ sources.push({
47
+ kind: "events",
48
+ bounded: true,
49
+ reference: `tasks:${tasks.length}/${completedTasks.length}`,
50
+ });
48
51
  lines.push(`Previous tasks (${tasks.length}/${completedTasks.length}):`);
49
52
  for (const task of tasks) {
50
53
  lines.push(`- ${task.id}: ${task.status}${task.error ? ` (${task.error})` : ""}`);
@@ -54,7 +57,11 @@ export function transformRunContextBeforeWorkerStart(input: {
54
57
  // Project pending mailbox that is relevant to this worker
55
58
  if (input.pendingMailbox.length > 0) {
56
59
  const messages = input.pendingMailbox.slice(0, maxMailbox);
57
- sources.push({ kind: "mailbox", bounded: true, reference: `mailbox:${messages.length}/${input.pendingMailbox.length}` });
60
+ sources.push({
61
+ kind: "mailbox",
62
+ bounded: true,
63
+ reference: `mailbox:${messages.length}/${input.pendingMailbox.length}`,
64
+ });
58
65
  lines.push(`Pending messages (${messages.length}/${input.pendingMailbox.length}):`);
59
66
  for (const msg of messages) {
60
67
  lines.push(`- ${msg.kind ?? "message"}: ${msg.body.slice(0, 100)}`);
@@ -64,7 +71,11 @@ export function transformRunContextBeforeWorkerStart(input: {
64
71
  // Project artifact references (not content)
65
72
  if (input.artifacts.length > 0) {
66
73
  const artifacts = input.artifacts.slice(0, maxArtifacts);
67
- sources.push({ kind: "artifacts", bounded: true, reference: `artifacts:${artifacts.length}/${input.artifacts.length}` });
74
+ sources.push({
75
+ kind: "artifacts",
76
+ bounded: true,
77
+ reference: `artifacts:${artifacts.length}/${input.artifacts.length}`,
78
+ });
68
79
  lines.push(`Available artifacts (${artifacts.length}/${input.artifacts.length}):`);
69
80
  for (const art of artifacts) {
70
81
  lines.push(`- ${art.kind} (${art.producer})`);
@@ -72,8 +83,16 @@ export function transformRunContextBeforeWorkerStart(input: {
72
83
  }
73
84
 
74
85
  // Metadata markers — not injected as prompt instructions
75
- sources.push({ kind: "ui_metadata", bounded: false, reference: "excluded_from_prompt" });
76
- sources.push({ kind: "runtime_metadata", bounded: false, reference: "excluded_from_prompt" });
86
+ sources.push({
87
+ kind: "ui_metadata",
88
+ bounded: false,
89
+ reference: "excluded_from_prompt",
90
+ });
91
+ sources.push({
92
+ kind: "runtime_metadata",
93
+ bounded: false,
94
+ reference: "excluded_from_prompt",
95
+ });
77
96
 
78
97
  return {
79
98
  sources,
@@ -101,4 +120,4 @@ export function convertRunHistoryToWorkerPrompt(input: {
101
120
  "",
102
121
  `Projection sources: ${projection.sources.map((s) => s.kind).join(", ")}`,
103
122
  ].join("\n");
104
- }
123
+ }
@@ -1,12 +1,12 @@
1
1
  import * as fs from "node:fs";
2
- import type { TaskCheckpointState, TeamRunManifest, TeamTaskState } from "../../state/types.ts";
2
+ import { withRunLockSync } from "../../state/locks.ts";
3
3
  import { loadRunManifestById, saveRunTasks } from "../../state/state-store.ts";
4
- import { recordFromTask, upsertCrewAgent } from "../crew-agent-records.ts";
4
+ import type { TaskCheckpointState, TeamRunManifest, TeamTaskState } from "../../state/types.ts";
5
5
  import { logInternalError } from "../../utils/internal-error.ts";
6
- import { withRunLockSync } from "../../state/locks.ts";
6
+ import { recordFromTask, upsertCrewAgent } from "../crew-agent-records.ts";
7
7
 
8
8
  export function updateTask(tasks: TeamTaskState[], updated: TeamTaskState): TeamTaskState[] {
9
- return tasks.map((task) => task.id === updated.id ? updated : task);
9
+ return tasks.map((task) => (task.id === updated.id ? updated : task));
10
10
  }
11
11
 
12
12
  /**
@@ -25,7 +25,12 @@ export function updateTask(tasks: TeamTaskState[], updated: TeamTaskState): Team
25
25
  *
26
26
  * @param checkpointPhase - Optional checkpoint phase to include in the task state alongside the update.
27
27
  */
28
- export function persistSingleTaskUpdate(manifest: TeamRunManifest, fallbackTasks: TeamTaskState[], updated: TeamTaskState, checkpointPhase?: TaskCheckpointState["phase"]): TeamTaskState[] {
28
+ export function persistSingleTaskUpdate(
29
+ manifest: TeamRunManifest,
30
+ fallbackTasks: TeamTaskState[],
31
+ updated: TeamTaskState,
32
+ checkpointPhase?: TaskCheckpointState["phase"],
33
+ ): TeamTaskState[] {
29
34
  let baseMtime = 0;
30
35
  try {
31
36
  baseMtime = fs.statSync(manifest.tasksPath).mtimeMs;
@@ -38,7 +43,13 @@ export function persistSingleTaskUpdate(manifest: TeamRunManifest, fallbackTasks
38
43
 
39
44
  // Build the task with optional checkpoint phase
40
45
  const taskWithCheckpoint = checkpointPhase
41
- ? { ...updated, checkpoint: { phase: checkpointPhase, updatedAt: new Date().toISOString() } }
46
+ ? {
47
+ ...updated,
48
+ checkpoint: {
49
+ phase: checkpointPhase,
50
+ updatedAt: new Date().toISOString(),
51
+ },
52
+ }
42
53
  : updated;
43
54
 
44
55
  try {
@@ -113,8 +124,18 @@ export function persistSingleTaskUpdate(manifest: TeamRunManifest, fallbackTasks
113
124
  }
114
125
  }
115
126
 
116
- export function checkpointTask(manifest: TeamRunManifest, tasks: TeamTaskState[], task: TeamTaskState, phase: TaskCheckpointState["phase"], childPid?: number): { task: TeamTaskState; tasks: TeamTaskState[] } {
117
- const checkpoint: TaskCheckpointState = { phase, updatedAt: new Date().toISOString(), ...(childPid ? { childPid } : task.checkpoint?.childPid ? { childPid: task.checkpoint.childPid } : {}) };
127
+ export function checkpointTask(
128
+ manifest: TeamRunManifest,
129
+ tasks: TeamTaskState[],
130
+ task: TeamTaskState,
131
+ phase: TaskCheckpointState["phase"],
132
+ childPid?: number,
133
+ ): { task: TeamTaskState; tasks: TeamTaskState[] } {
134
+ const checkpoint: TaskCheckpointState = {
135
+ phase,
136
+ updatedAt: new Date().toISOString(),
137
+ ...(childPid ? { childPid } : task.checkpoint?.childPid ? { childPid: task.checkpoint.childPid } : {}),
138
+ };
118
139
  const nextTask = { ...task, checkpoint };
119
140
  const nextTasks = persistSingleTaskUpdate(manifest, updateTask(tasks, nextTask), nextTask);
120
141
  try {
@@ -5,11 +5,7 @@ import * as fs from "node:fs";
5
5
  * If the file exceeds maxBytes, reads only the last maxBytes and snaps
6
6
  * to the nearest newline boundary to avoid partial JSONL lines.
7
7
  */
8
- export function tailReadWithLineSnap(
9
- filePath: string,
10
- maxBytes: number,
11
- fallbackContent: string,
12
- ): string {
8
+ export function tailReadWithLineSnap(filePath: string, maxBytes: number, fallbackContent: string): string {
13
9
  if (!fs.existsSync(filePath)) return fallbackContent;
14
10
  const stat = fs.statSync(filePath);
15
11
  if (stat.size <= maxBytes) return fs.readFileSync(filePath, "utf-8");
@@ -23,4 +19,4 @@ export function tailReadWithLineSnap(
23
19
  } finally {
24
20
  fs.closeSync(fd);
25
21
  }
26
- }
22
+ }