pi-crew 0.9.15 → 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 +145 -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 +193 -40
  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 +86 -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
@@ -7,15 +7,7 @@ import { logInternalError } from "../utils/internal-error.ts";
7
7
  import { projectCrewRoot } from "../utils/paths.ts";
8
8
  import { redactSecrets } from "../utils/redaction.ts";
9
9
 
10
- export type SubagentStatus =
11
- | "queued"
12
- | "running"
13
- | "completed"
14
- | "failed"
15
- | "cancelled"
16
- | "error"
17
- | "blocked"
18
- | "stopped";
10
+ export type SubagentStatus = "queued" | "running" | "completed" | "failed" | "cancelled" | "error" | "blocked" | "stopped";
19
11
 
20
12
  export interface SubagentSpawnOptions {
21
13
  cwd: string;
@@ -61,10 +53,7 @@ export interface SubagentRecord {
61
53
  lifetimeUsage?: { input: number; output: number; cacheWrite: number };
62
54
  }
63
55
 
64
- type SpawnRunner = (
65
- options: SubagentSpawnOptions,
66
- signal?: AbortSignal,
67
- ) => Promise<PiTeamsToolResult>;
56
+ type SpawnRunner = (options: SubagentSpawnOptions, signal?: AbortSignal) => Promise<PiTeamsToolResult>;
68
57
  type Notify = (record: SubagentRecord) => void;
69
58
  type NotifyEvent = (type: string, data: Record<string, unknown>) => void;
70
59
 
@@ -81,11 +70,7 @@ function isValidSubagentId(id: string): boolean {
81
70
 
82
71
  function persistedSubagentPath(cwd: string, id: string): string {
83
72
  if (!isValidSubagentId(id)) throw new Error(`Invalid subagent id: ${id}`);
84
- return path.join(
85
- projectCrewRoot(cwd),
86
- DEFAULT_PATHS.state.subagentsSubdir,
87
- `${id}.json`,
88
- );
73
+ return path.join(projectCrewRoot(cwd), DEFAULT_PATHS.state.subagentsSubdir, `${id}.json`);
89
74
  }
90
75
 
91
76
  function serializableRecord(record: SubagentRecord): SubagentRecord {
@@ -93,18 +78,11 @@ function serializableRecord(record: SubagentRecord): SubagentRecord {
93
78
  return rest;
94
79
  }
95
80
 
96
- export function savePersistedSubagentRecord(
97
- cwd: string,
98
- record: SubagentRecord,
99
- ): void {
81
+ export function savePersistedSubagentRecord(cwd: string, record: SubagentRecord): void {
100
82
  try {
101
83
  const filePath = persistedSubagentPath(cwd, record.id);
102
84
  fs.mkdirSync(path.dirname(filePath), { recursive: true });
103
- fs.writeFileSync(
104
- filePath,
105
- `${JSON.stringify(redactSecrets(serializableRecord(record)), null, 2)}\n`,
106
- "utf-8",
107
- );
85
+ fs.writeFileSync(filePath, `${JSON.stringify(redactSecrets(serializableRecord(record)), null, 2)}\n`, "utf-8");
108
86
  // SECURITY: Restrict permissions to owner-only (rw-------).
109
87
  // On multi-user systems, other users must not read task prompts,
110
88
  // agent descriptions, and run IDs from subagent record files.
@@ -114,6 +92,36 @@ export function savePersistedSubagentRecord(
114
92
  }
115
93
  }
116
94
 
95
+ /**
96
+ * Delete the persisted subagent record from disk.
97
+ * Used when a subagent is cancelled or terminated — the user wants no trace.
98
+ * Safe-fail: if the file does not exist (already deleted), this is a no-op.
99
+ * Any other I/O error is logged but not propagated.
100
+ */
101
+ export function removePersistedSubagentRecord(cwd: string, id: string): boolean {
102
+ try {
103
+ const filePath = persistedSubagentPath(cwd, id);
104
+ fs.unlinkSync(filePath);
105
+ return true;
106
+ } catch (error) {
107
+ const code = (error as NodeJS.ErrnoException)?.code;
108
+ if (code === "ENOENT") return false;
109
+ logInternalError("subagent-manager.remove", error, `id=${id}`);
110
+ return false;
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Predicate: should this record's persisted file be deleted on terminal status?
116
+ * Only abnormal terminations (cancelled / stopped / terminated-flag) are wiped.
117
+ * Successful runs (`completed`) and agent errors (`failed`, `error`) keep their audit trail.
118
+ */
119
+ export function shouldDeleteOnTerminalStatus(record: SubagentRecord): boolean {
120
+ if (record.terminated === true) return true;
121
+ const s = record.status;
122
+ return s === "cancelled" || s === "stopped";
123
+ }
124
+
117
125
  const ALLOWED_RECORD_FIELDS = new Set([
118
126
  "id",
119
127
  "agentId",
@@ -156,9 +164,7 @@ function sanitizePersistedRecord(raw: unknown): SubagentRecord | undefined {
156
164
  for (const key of Object.keys(obj)) {
157
165
  if (
158
166
  ALLOWED_RECORD_FIELDS.has(key) &&
159
- (typeof obj[key] === "string" ||
160
- typeof obj[key] === "number" ||
161
- typeof obj[key] === "boolean")
167
+ (typeof obj[key] === "string" || typeof obj[key] === "number" || typeof obj[key] === "boolean")
162
168
  ) {
163
169
  clean[key] = obj[key];
164
170
  }
@@ -168,14 +174,9 @@ function sanitizePersistedRecord(raw: unknown): SubagentRecord | undefined {
168
174
  return clean as unknown as SubagentRecord;
169
175
  }
170
176
 
171
- export function readPersistedSubagentRecord(
172
- cwd: string,
173
- id: string,
174
- ): SubagentRecord | undefined {
177
+ export function readPersistedSubagentRecord(cwd: string, id: string): SubagentRecord | undefined {
175
178
  try {
176
- const raw = JSON.parse(
177
- fs.readFileSync(persistedSubagentPath(cwd, id), "utf-8"),
178
- );
179
+ const raw = JSON.parse(fs.readFileSync(persistedSubagentPath(cwd, id), "utf-8"));
179
180
  return sanitizePersistedRecord(raw);
180
181
  } catch {
181
182
  return undefined;
@@ -196,10 +197,7 @@ function detailsRunId(result: PiTeamsToolResult): string | undefined {
196
197
  return typeof details?.runId === "string" ? details.runId : undefined;
197
198
  }
198
199
 
199
- function totalRunTurns(
200
- cwd: string,
201
- runId: string | undefined,
202
- ): number | undefined {
200
+ function totalRunTurns(cwd: string, runId: string | undefined): number | undefined {
203
201
  if (!runId) return undefined;
204
202
  const loaded = loadRunManifestById(cwd, runId); // NOTE: no withRunLock - best-effort only; concurrent writes may cause inconsistency
205
203
  if (!loaded) return undefined;
@@ -228,33 +226,20 @@ export class SubagentManager {
228
226
  private readonly onEvent?: NotifyEvent;
229
227
  private readonly pollIntervalMs: number;
230
228
 
231
- constructor(
232
- maxConcurrent = 4,
233
- onComplete?: Notify,
234
- pollIntervalMs = 1000,
235
- onEvent?: NotifyEvent,
236
- ) {
229
+ constructor(maxConcurrent = 4, onComplete?: Notify, pollIntervalMs = 1000, onEvent?: NotifyEvent) {
237
230
  this.maxConcurrent = maxConcurrent;
238
231
  this.onComplete = onComplete;
239
232
  this.onEvent = onEvent;
240
233
  this.pollIntervalMs = pollIntervalMs;
241
234
  }
242
235
 
243
- spawn(
244
- options: SubagentSpawnOptions,
245
- runner: SpawnRunner,
246
- signal?: AbortSignal,
247
- ): SubagentRecord {
236
+ spawn(options: SubagentSpawnOptions, runner: SpawnRunner, signal?: AbortSignal): SubagentRecord {
248
237
  const record: SubagentRecord = {
249
238
  id: `agent_${Date.now().toString(36)}_${(++this.counter).toString(36)}`,
250
239
  type: options.type,
251
240
  description: options.description,
252
241
  prompt: options.prompt,
253
- status:
254
- options.background &&
255
- this.runningBackground >= this.maxConcurrent
256
- ? "queued"
257
- : "running",
242
+ status: options.background && this.runningBackground >= this.maxConcurrent ? "queued" : "running",
258
243
  startedAt: Date.now(),
259
244
  model: options.model,
260
245
  skill: options.skill,
@@ -278,9 +263,7 @@ export class SubagentManager {
278
263
  }
279
264
 
280
265
  listAgents(): SubagentRecord[] {
281
- return [...this.records.values()].sort(
282
- (a, b) => b.startedAt - a.startedAt,
283
- );
266
+ return [...this.records.values()].sort((a, b) => b.startedAt - a.startedAt);
284
267
  }
285
268
 
286
269
  abort(id: string, reason?: string): boolean {
@@ -291,8 +274,7 @@ export class SubagentManager {
291
274
  this.markStopped(record, reason ?? "Aborted by caller.");
292
275
  return true;
293
276
  }
294
- if (record.status !== "running" && record.status !== "blocked")
295
- return false;
277
+ if (record.status !== "running" && record.status !== "blocked") return false;
296
278
  this.controllers.get(id)?.abort();
297
279
  this.markStopped(record, reason ?? "Aborted by caller.");
298
280
  return true;
@@ -320,15 +302,9 @@ export class SubagentManager {
320
302
  while (true) {
321
303
  this.drainQueue();
322
304
  const pending = this.listAgents()
323
- .filter(
324
- (record) =>
325
- record.status === "running" ||
326
- record.status === "queued",
327
- )
305
+ .filter((record) => record.status === "running" || record.status === "queued")
328
306
  .map((record) => record.promise)
329
- .filter((promise): promise is Promise<void> =>
330
- Boolean(promise),
331
- );
307
+ .filter((promise): promise is Promise<void> => Boolean(promise));
332
308
  if (!pending.length) break;
333
309
  await Promise.allSettled(pending);
334
310
  }
@@ -338,15 +314,10 @@ export class SubagentManager {
338
314
  while (true) {
339
315
  const record = this.records.get(id);
340
316
  if (!record) return undefined;
341
- if (record.status !== "running" && record.status !== "queued")
342
- return record;
317
+ if (record.status !== "running" && record.status !== "queued") return record;
343
318
  if (record.promise)
344
319
  await record.promise.catch((error) => {
345
- logInternalError(
346
- "subagent-manager.waitForRecord",
347
- error,
348
- `id=${id}`,
349
- );
320
+ logInternalError("subagent-manager.waitForRecord", error, `id=${id}`);
350
321
  });
351
322
  else await new Promise((resolve) => setTimeout(resolve, 100));
352
323
  }
@@ -357,12 +328,7 @@ export class SubagentManager {
357
328
  this.drainQueue();
358
329
  }
359
330
 
360
- private start(
361
- record: SubagentRecord,
362
- options: SubagentSpawnOptions,
363
- runner: SpawnRunner,
364
- signal?: AbortSignal,
365
- ): void {
331
+ private start(record: SubagentRecord, options: SubagentSpawnOptions, runner: SpawnRunner, signal?: AbortSignal): void {
366
332
  if (options.background) this.runningBackground++;
367
333
  record.status = "running";
368
334
  record.startedAt = Date.now();
@@ -381,8 +347,7 @@ export class SubagentManager {
381
347
  record.error = record.result;
382
348
  throw new Error(record.error);
383
349
  }
384
- if (record.runId)
385
- await this.pollRunToTerminal(options.cwd, record);
350
+ if (record.runId) await this.pollRunToTerminal(options.cwd, record);
386
351
  else record.status = "completed";
387
352
  } catch (error) {
388
353
  if (record.status === "stopped" || runSignal.aborted) {
@@ -390,27 +355,16 @@ export class SubagentManager {
390
355
  ? "Signal aborted — agent cancelled by parent (session switch, user cancel, or tool timeout)."
391
356
  : undefined;
392
357
  record.status = "stopped";
393
- if (!record.error)
394
- record.error =
395
- abortReason ??
396
- (error instanceof Error
397
- ? error.message
398
- : String(error));
358
+ if (!record.error) record.error = abortReason ?? (error instanceof Error ? error.message : String(error));
399
359
  return;
400
360
  }
401
361
  record.status = "error";
402
- record.error =
403
- error instanceof Error ? error.message : String(error);
362
+ record.error = error instanceof Error ? error.message : String(error);
404
363
  throw error; // H4: Propagate rejection so callers awaiting record.promise see the error
405
364
  } finally {
406
365
  this.cleanupRunSignal(record.id);
407
- if (options.background)
408
- this.runningBackground = Math.max(
409
- 0,
410
- this.runningBackground - 1,
411
- );
412
- if (record.status !== "blocked")
413
- record.completedAt = record.completedAt ?? Date.now();
366
+ if (options.background) this.runningBackground = Math.max(0, this.runningBackground - 1);
367
+ if (record.status !== "blocked") record.completedAt = record.completedAt ?? Date.now();
414
368
  savePersistedSubagentRecord(options.cwd, record);
415
369
  if (
416
370
  record.status === "completed" ||
@@ -420,13 +374,15 @@ export class SubagentManager {
420
374
  record.status === "stopped"
421
375
  ) {
422
376
  // Phase 1.6: Populate telemetry fields
423
- record.turnCount =
424
- record.turnCount ??
425
- totalRunTurns(options.cwd, record.runId);
426
- record.durationMs = record.completedAt
427
- ? Math.max(0, record.completedAt - record.startedAt)
428
- : undefined;
377
+ record.turnCount = record.turnCount ?? totalRunTurns(options.cwd, record.runId);
378
+ record.durationMs = record.completedAt ? Math.max(0, record.completedAt - record.startedAt) : undefined;
429
379
  savePersistedSubagentRecord(options.cwd, record);
380
+ // User policy (v0.9.16): cancelled / stopped subagents leave NO trace.
381
+ // Successful runs (`completed`) and agent errors (`failed`, `error`)
382
+ // keep their audit trail. See shouldDeleteOnTerminalStatus().
383
+ if (shouldDeleteOnTerminalStatus(record)) {
384
+ removePersistedSubagentRecord(options.cwd, record.id);
385
+ }
430
386
  this.onComplete?.(record);
431
387
  }
432
388
  this.drainQueue();
@@ -441,20 +397,22 @@ export class SubagentManager {
441
397
  // DO await (they still see the rejection) while preventing the
442
398
  // harness-killing failure mode for callers that don't.
443
399
  record.promise.catch((error) => {
444
- logInternalError(
445
- "subagent-manager.start.unhandled",
446
- error,
447
- `id=${record.id}`,
448
- );
400
+ logInternalError("subagent-manager.start.unhandled", error, `id=${record.id}`);
449
401
  });
450
402
  }
451
403
 
452
404
  private markStopped(record: SubagentRecord, reason?: string): void {
453
405
  record.status = "stopped";
406
+ record.terminated = true;
454
407
  record.completedAt = Date.now();
455
408
  if (reason && !record.error) record.error = reason;
456
409
  const cwd = this.cwdByRecord.get(record.id);
410
+ // User policy (v0.9.16): stopped subagents leave NO trace on disk.
411
+ // Save first (so any concurrent reader sees the final status), then
412
+ // unlink. The race window is microseconds and the file is gone before
413
+ // the next widget/dashboard tick.
457
414
  if (cwd) savePersistedSubagentRecord(cwd, record);
415
+ if (cwd) removePersistedSubagentRecord(cwd, record.id);
458
416
  }
459
417
 
460
418
  private createRunSignal(id: string, signal?: AbortSignal): AbortSignal {
@@ -467,9 +425,7 @@ export class SubagentManager {
467
425
  if (signal) {
468
426
  const abort = (): void => controller.abort();
469
427
  signal.addEventListener("abort", abort, { once: true });
470
- this.controllerCleanup.set(id, () =>
471
- signal.removeEventListener("abort", abort),
472
- );
428
+ this.controllerCleanup.set(id, () => signal.removeEventListener("abort", abort));
473
429
  }
474
430
  return controller.signal;
475
431
  }
@@ -481,48 +437,32 @@ export class SubagentManager {
481
437
  }
482
438
 
483
439
  private drainQueue(): void {
484
- while (
485
- this.queue.length > 0 &&
486
- this.runningBackground < this.maxConcurrent
487
- ) {
440
+ while (this.queue.length > 0 && this.runningBackground < this.maxConcurrent) {
488
441
  const next = this.queue.shift();
489
442
  if (!next || next.record.status !== "queued") continue;
490
443
  this.start(next.record, next.options, next.runner, next.signal);
491
444
  }
492
445
  }
493
446
 
494
- private async pollRunToTerminal(
495
- cwd: string,
496
- record: SubagentRecord,
497
- ): Promise<void> {
498
- while (
499
- record.runId &&
500
- (record.status === "running" || record.status === "blocked")
501
- ) {
447
+ private async pollRunToTerminal(cwd: string, record: SubagentRecord): Promise<void> {
448
+ while (record.runId && (record.status === "running" || record.status === "blocked")) {
502
449
  const loaded = loadRunManifestById(cwd, record.runId); // NOTE: no withRunLock - best-effort only; concurrent writes may cause inconsistency
503
450
  if (!loaded) {
504
- await new Promise((resolve) =>
505
- setTimeout(resolve, this.pollIntervalMs),
506
- );
451
+ await new Promise((resolve) => setTimeout(resolve, this.pollIntervalMs));
507
452
  continue;
508
453
  }
509
454
  if (loaded.manifest.status === "completed") {
510
455
  record.status = "completed";
511
456
  record.error = undefined;
512
- record.turnCount =
513
- record.turnCount ?? totalRunTurns(cwd, record.runId);
457
+ record.turnCount = record.turnCount ?? totalRunTurns(cwd, record.runId);
514
458
  record.completedAt = Date.now();
515
459
  savePersistedSubagentRecord(cwd, record);
516
460
  return;
517
461
  }
518
- if (
519
- loaded.manifest.status === "failed" ||
520
- loaded.manifest.status === "cancelled"
521
- ) {
462
+ if (loaded.manifest.status === "failed" || loaded.manifest.status === "cancelled") {
522
463
  record.status = loaded.manifest.status;
523
464
  record.error = loaded.manifest.summary;
524
- record.turnCount =
525
- record.turnCount ?? totalRunTurns(cwd, record.runId);
465
+ record.turnCount = record.turnCount ?? totalRunTurns(cwd, record.runId);
526
466
  record.completedAt = Date.now();
527
467
  savePersistedSubagentRecord(cwd, record);
528
468
  return;
@@ -541,20 +481,14 @@ export class SubagentManager {
541
481
  savePersistedSubagentRecord(cwd, record);
542
482
  return;
543
483
  }
544
- await new Promise((resolve) =>
545
- setTimeout(resolve, this.pollIntervalMs),
546
- );
484
+ await new Promise((resolve) => setTimeout(resolve, this.pollIntervalMs));
547
485
  }
548
486
  }
549
487
 
550
- private scheduleBlockedTerminalPoll(
551
- cwd: string,
552
- record: SubagentRecord,
553
- ): void {
488
+ private scheduleBlockedTerminalPoll(cwd: string, record: SubagentRecord): void {
554
489
  const poll = (): void => {
555
490
  const current = this.records.get(record.id);
556
- if (!current || current.status !== "blocked" || !current.runId)
557
- return;
491
+ if (!current || current.status !== "blocked" || !current.runId) return;
558
492
  const loaded = loadRunManifestById(cwd, current.runId); // NOTE: no withRunLock - best-effort only; concurrent writes may cause inconsistency
559
493
  if (
560
494
  !loaded ||
@@ -568,25 +502,17 @@ export class SubagentManager {
568
502
  return;
569
503
  }
570
504
  const persisted = readPersistedSubagentRecord(cwd, current.id);
571
- current.resultConsumed =
572
- current.resultConsumed || persisted?.resultConsumed;
505
+ current.resultConsumed = current.resultConsumed || persisted?.resultConsumed;
573
506
  if (loaded.manifest.status === "completed") {
574
507
  current.status = "completed";
575
508
  current.error = undefined;
576
- } else if (
577
- loaded.manifest.status === "failed" ||
578
- loaded.manifest.status === "cancelled"
579
- ) {
509
+ } else if (loaded.manifest.status === "failed" || loaded.manifest.status === "cancelled") {
580
510
  current.status = loaded.manifest.status;
581
511
  current.error = loaded.manifest.summary;
582
512
  } else return;
583
513
  current.completedAt = Date.now();
584
- current.turnCount =
585
- current.turnCount ?? totalRunTurns(cwd, current.runId);
586
- current.durationMs = Math.max(
587
- 0,
588
- current.completedAt - current.startedAt,
589
- );
514
+ current.turnCount = current.turnCount ?? totalRunTurns(cwd, current.runId);
515
+ current.durationMs = Math.max(0, current.completedAt - current.startedAt);
590
516
  savePersistedSubagentRecord(cwd, current);
591
517
  this.onComplete?.(current);
592
518
  };
@@ -594,20 +520,11 @@ export class SubagentManager {
594
520
  timer.unref();
595
521
  }
596
522
 
597
- private scheduleStuckBlockedNotify(
598
- cwd: string,
599
- record: SubagentRecord,
600
- ): void {
523
+ private scheduleStuckBlockedNotify(cwd: string, record: SubagentRecord): void {
601
524
  const threshold = DEFAULT_SUBAGENT.stuckBlockedNotifyMs;
602
525
  const fire = (): void => {
603
526
  const current = this.records.get(record.id);
604
- if (
605
- !current ||
606
- current.status !== "blocked" ||
607
- !current.blockedAt ||
608
- current.stuckNotified
609
- )
610
- return;
527
+ if (!current || current.status !== "blocked" || !current.blockedAt || current.stuckNotified) return;
611
528
  current.stuckNotified = true;
612
529
  this.onEvent?.("subagent.stuck-blocked", {
613
530
  event: "subagent.stuck-blocked",
@@ -2,7 +2,10 @@ export interface SubprocessToolEvent {
2
2
  toolName: string;
3
3
  toolCallId: string;
4
4
  args?: Record<string, unknown>;
5
- result?: { content: Array<{ type: string; text?: string }>; details?: unknown };
5
+ result?: {
6
+ content: Array<{ type: string; text?: string }>;
7
+ details?: unknown;
8
+ };
6
9
  isError?: boolean;
7
10
  }
8
11
 
@@ -1,5 +1,5 @@
1
- import type { TeamRunManifest } from "../state/types.ts";
2
1
  import { appendEvent } from "../state/event-log.ts";
2
+ import type { TeamRunManifest } from "../state/types.ts";
3
3
  import { logInternalError } from "../utils/internal-error.ts";
4
4
 
5
5
  export interface SupervisorContactPayload {
@@ -50,10 +50,15 @@ export function parseSupervisorContactFromLine(line: string): Omit<SupervisorCon
50
50
  if (record.type !== "supervisor_contact" && record.type !== "crew_supervisor_contact") return undefined;
51
51
  return {
52
52
  taskId: typeof record.taskId === "string" ? record.taskId : "",
53
- reason: typeof record.reason === "string" && ["decision_needed", "clarification", "approval", "error_escalation", "custom"].includes(record.reason)
54
- ? record.reason as SupervisorContactPayload["reason"]
55
- : "custom",
53
+ reason:
54
+ typeof record.reason === "string" &&
55
+ ["decision_needed", "clarification", "approval", "error_escalation", "custom"].includes(record.reason)
56
+ ? (record.reason as SupervisorContactPayload["reason"])
57
+ : "custom",
56
58
  message: typeof record.message === "string" ? record.message : String(record.message ?? ""),
57
- data: record.data && typeof record.data === "object" && !Array.isArray(record.data) ? record.data as Record<string, unknown> : undefined,
59
+ data:
60
+ record.data && typeof record.data === "object" && !Array.isArray(record.data)
61
+ ? (record.data as Record<string, unknown>)
62
+ : undefined,
58
63
  };
59
64
  }
@@ -1,13 +1,16 @@
1
- import type { TeamTaskState } from "../state/types.ts";
2
- import type { CrewAgentRecord, CrewRuntimeKind } from "./crew-agent-runtime.ts";
1
+ import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
3
2
  import { recordFromTask } from "./crew-agent-records.ts";
4
- import type { TeamRunManifest } from "../state/types.ts";
3
+ import type { CrewAgentRecord, CrewRuntimeKind } from "./crew-agent-runtime.ts";
5
4
 
6
5
  export function shouldMaterializeAgent(task: TeamTaskState): boolean {
7
6
  return task.status !== "queued" && task.status !== "skipped";
8
7
  }
9
8
 
10
- export function recordsForMaterializedTasks(manifest: TeamRunManifest, tasks: TeamTaskState[], runtime: CrewRuntimeKind): CrewAgentRecord[] {
9
+ export function recordsForMaterializedTasks(
10
+ manifest: TeamRunManifest,
11
+ tasks: TeamTaskState[],
12
+ runtime: CrewRuntimeKind,
13
+ ): CrewAgentRecord[] {
11
14
  return tasks.filter(shouldMaterializeAgent).map((task) => recordFromTask(manifest, task, runtime));
12
15
  }
13
16
 
@@ -31,7 +34,18 @@ export function waitingReason(task: TeamTaskState, tasks: TeamTaskState[]): stri
31
34
  export function formatTaskGraphLines(tasks: TeamTaskState[]): string[] {
32
35
  if (tasks.length === 0) return ["- (none)"];
33
36
  return tasks.map((task) => {
34
- const icon = task.status === "completed" ? "✓" : task.status === "running" ? "⠋" : task.status === "failed" ? "✗" : task.status === "cancelled" || task.status === "skipped" ? "■" : task.status === "needs_attention" ? "⚠" : "◦";
37
+ const icon =
38
+ task.status === "completed"
39
+ ? "✓"
40
+ : task.status === "running"
41
+ ? "⠋"
42
+ : task.status === "failed"
43
+ ? "✗"
44
+ : task.status === "cancelled" || task.status === "skipped"
45
+ ? "■"
46
+ : task.status === "needs_attention"
47
+ ? "⚠"
48
+ : "◦";
35
49
  const wait = waitingReason(task, tasks);
36
50
  return `- ${icon} ${task.id} [${task.status}] ${task.role}->${task.agent}${wait && wait !== "ready" ? ` (${wait})` : ""}`;
37
51
  });