pi-crew 0.9.16 → 0.9.18

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 (435) hide show
  1. package/CHANGELOG.md +130 -0
  2. package/README.md +19 -0
  3. package/dist/build-meta.json +21784 -0
  4. package/dist/index.mjs +83169 -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/migration/atomic-write-v2-migration.md +297 -0
  14. package/docs/patterns/command-agent-skill.md +1 -1
  15. package/docs/perf/performance-review-2026-07.md +287 -0
  16. package/docs/skills/REFERENCE.md +0 -17
  17. package/docs//303/242mmaAAA/303/242 +357 -0
  18. package/index.bundle.ts +25 -0
  19. package/index.ts +95 -4
  20. package/package.json +15 -4
  21. package/skills/iterative-audit/SKILL.md +0 -1
  22. package/skills/widget-rendering/SKILL.md +17 -0
  23. package/src/adapters/claude-adapter.ts +1 -3
  24. package/src/adapters/export-util.ts +16 -16
  25. package/src/adapters/index.ts +5 -5
  26. package/src/agents/agent-config.ts +20 -14
  27. package/src/agents/agent-serializer.ts +1 -1
  28. package/src/agents/discover-agents.ts +83 -39
  29. package/src/benchmark/benchmark-runner.ts +51 -51
  30. package/src/benchmark/feedback-loop.ts +1 -1
  31. package/src/config/config.ts +303 -591
  32. package/src/config/defaults.ts +28 -2
  33. package/src/config/drift-detector.ts +11 -14
  34. package/src/config/markers.ts +201 -203
  35. package/src/config/resilient-parser.ts +14 -6
  36. package/src/config/role-tools.ts +3 -3
  37. package/src/config/suggestions.ts +5 -12
  38. package/src/config/types.ts +9 -25
  39. package/src/errors.ts +151 -157
  40. package/src/extension/action-suggestions.ts +54 -9
  41. package/src/extension/async-notifier.ts +43 -13
  42. package/src/extension/autonomous-policy.ts +77 -37
  43. package/src/extension/command-completions.ts +9 -8
  44. package/src/extension/context-status-injection.ts +14 -12
  45. package/src/extension/crew-autocomplete.ts +8 -16
  46. package/src/extension/crew-cleanup.ts +2 -1
  47. package/src/extension/crew-shortcuts.ts +9 -6
  48. package/src/extension/cross-extension-rpc.ts +136 -42
  49. package/src/extension/help.ts +1 -1
  50. package/src/extension/import-index.ts +10 -5
  51. package/src/extension/knowledge-injection.ts +88 -15
  52. package/src/extension/management.ts +89 -349
  53. package/src/extension/message-renderers.ts +3 -4
  54. package/src/extension/notification-router.ts +22 -5
  55. package/src/extension/notification-sink.ts +6 -3
  56. package/src/extension/pi-api.ts +17 -8
  57. package/src/extension/plan-orchestrate.ts +8 -27
  58. package/src/extension/project-init.ts +21 -6
  59. package/src/extension/register.ts +329 -975
  60. package/src/extension/registration/artifact-cleanup.ts +9 -4
  61. package/src/extension/registration/command-utils.ts +5 -1
  62. package/src/extension/registration/commands.ts +806 -314
  63. package/src/extension/registration/compaction-guard.ts +15 -15
  64. package/src/extension/registration/lifecycle.ts +259 -0
  65. package/src/extension/registration/observability.ts +293 -0
  66. package/src/extension/registration/subagent-helpers.ts +29 -7
  67. package/src/extension/registration/subagent-tools.ts +253 -44
  68. package/src/extension/registration/team-tool.ts +19 -84
  69. package/src/extension/registration/ui.ts +168 -0
  70. package/src/extension/registration/viewers.ts +64 -24
  71. package/src/extension/result-watcher.ts +18 -7
  72. package/src/extension/run-bundle-schema.ts +21 -6
  73. package/src/extension/run-export.ts +15 -6
  74. package/src/extension/run-import.ts +64 -29
  75. package/src/extension/run-index.ts +28 -9
  76. package/src/extension/run-maintenance.ts +32 -12
  77. package/src/extension/session-summary.ts +1 -1
  78. package/src/extension/team-manager-command.ts +64 -7
  79. package/src/extension/team-onboard.ts +149 -150
  80. package/src/extension/team-recommendation.ts +121 -21
  81. package/src/extension/team-tool/anchor.ts +31 -64
  82. package/src/extension/team-tool/api.ts +929 -141
  83. package/src/extension/team-tool/auto-summarize.ts +14 -26
  84. package/src/extension/team-tool/cache-control.ts +1 -5
  85. package/src/extension/team-tool/cancel.ts +138 -38
  86. package/src/extension/team-tool/chain-dispatch.ts +5 -13
  87. package/src/extension/team-tool/chain-executor.ts +29 -51
  88. package/src/extension/team-tool/config-patch.ts +1 -1
  89. package/src/extension/team-tool/context.ts +40 -20
  90. package/src/extension/team-tool/destructive-gate.ts +10 -5
  91. package/src/extension/team-tool/doctor.ts +170 -51
  92. package/src/extension/team-tool/explain.ts +228 -214
  93. package/src/extension/team-tool/failure-patterns.ts +3 -9
  94. package/src/extension/team-tool/goal-wrap.ts +71 -29
  95. package/src/extension/team-tool/goal.ts +185 -35
  96. package/src/extension/team-tool/handle-schedule.ts +34 -15
  97. package/src/extension/team-tool/handle-settings.ts +94 -56
  98. package/src/extension/team-tool/health-monitor.ts +27 -108
  99. package/src/extension/team-tool/inspect.ts +42 -9
  100. package/src/extension/team-tool/intent-policy.ts +4 -1
  101. package/src/extension/team-tool/lifecycle-actions.ts +244 -48
  102. package/src/extension/team-tool/orchestrate.ts +7 -18
  103. package/src/extension/team-tool/parallel-dispatch.ts +51 -29
  104. package/src/extension/team-tool/plan.ts +29 -5
  105. package/src/extension/team-tool/respond.ts +49 -16
  106. package/src/extension/team-tool/run-not-found.ts +3 -8
  107. package/src/extension/team-tool/run.ts +80 -317
  108. package/src/extension/team-tool/status.ts +135 -43
  109. package/src/extension/team-tool/workflow-manage.ts +92 -25
  110. package/src/extension/team-tool-types.ts +8 -1
  111. package/src/extension/team-tool.ts +142 -551
  112. package/src/extension/validate-resources.ts +39 -8
  113. package/src/hooks/registry.ts +66 -17
  114. package/src/hooks/types.ts +1 -1
  115. package/src/i18n.ts +25 -11
  116. package/src/observability/correlation.ts +17 -3
  117. package/src/observability/event-bus.ts +51 -56
  118. package/src/observability/event-to-metric.ts +117 -15
  119. package/src/observability/exporters/otlp-exporter.ts +56 -17
  120. package/src/observability/exporters/prometheus-exporter.ts +1 -1
  121. package/src/observability/metric-registry.ts +16 -4
  122. package/src/observability/metric-retention.ts +8 -2
  123. package/src/observability/metric-sink.ts +11 -3
  124. package/src/observability/metrics-primitives.ts +42 -9
  125. package/src/plugins/plugin-define.ts +2 -2
  126. package/src/plugins/plugin-registry.ts +25 -25
  127. package/src/plugins/plugins/index.ts +1 -1
  128. package/src/plugins/plugins/nextjs.ts +16 -16
  129. package/src/plugins/plugins/vite.ts +7 -11
  130. package/src/plugins/plugins/vitest.ts +6 -11
  131. package/src/runtime/adaptive-plan.ts +225 -40
  132. package/src/runtime/agent-control.ts +58 -15
  133. package/src/runtime/agent-memory.ts +15 -9
  134. package/src/runtime/agent-observability.ts +10 -2
  135. package/src/runtime/anchor-manager.ts +27 -25
  136. package/src/runtime/async-marker.ts +7 -1
  137. package/src/runtime/async-runner.ts +39 -24
  138. package/src/runtime/auto-summarize.ts +7 -13
  139. package/src/runtime/background-runner.ts +189 -251
  140. package/src/runtime/batch-barrier.ts +18 -16
  141. package/src/runtime/cancellation-token.ts +16 -6
  142. package/src/runtime/cancellation.ts +46 -8
  143. package/src/runtime/capability-inventory.ts +6 -4
  144. package/src/runtime/chain-parser.ts +44 -11
  145. package/src/runtime/chain-runner.ts +63 -69
  146. package/src/runtime/checkpoint.ts +12 -56
  147. package/src/runtime/child-pi.ts +344 -79
  148. package/src/runtime/coalesce-tasks.ts +268 -0
  149. package/src/runtime/code-summary.ts +71 -26
  150. package/src/runtime/compact-stages/index.ts +15 -5
  151. package/src/runtime/compact-stages/tail-capture-stage.ts +7 -2
  152. package/src/runtime/compact-stages/truncation-stage.ts +4 -1
  153. package/src/runtime/compaction-summary.ts +17 -10
  154. package/src/runtime/completion-guard.ts +33 -16
  155. package/src/runtime/crash-classification.ts +28 -7
  156. package/src/runtime/crash-recovery.ts +177 -37
  157. package/src/runtime/crew-agent-records.ts +145 -47
  158. package/src/runtime/crew-hooks.ts +9 -24
  159. package/src/runtime/cross-extension-rpc.ts +25 -23
  160. package/src/runtime/custom-tools/irc-tool.ts +43 -15
  161. package/src/runtime/custom-tools/submit-result-tool.ts +16 -5
  162. package/src/runtime/delivery-coordinator.ts +34 -7
  163. package/src/runtime/delta-conflict.ts +9 -21
  164. package/src/runtime/deterministic-ast.ts +1 -1
  165. package/src/runtime/diagnostic-export.ts +53 -20
  166. package/src/runtime/direct-run.ts +12 -2
  167. package/src/runtime/dwf-state-store.ts +1 -1
  168. package/src/runtime/dynamic-workflow-context.ts +187 -59
  169. package/src/runtime/dynamic-workflow-runner.ts +42 -20
  170. package/src/runtime/effectiveness.ts +16 -8
  171. package/src/runtime/errors/crew-errors.ts +7 -11
  172. package/src/runtime/event-stream-bridge.ts +9 -3
  173. package/src/runtime/foreground-control.ts +54 -14
  174. package/src/runtime/foreground-watchdog.ts +9 -6
  175. package/src/runtime/goal-achievement.ts +27 -10
  176. package/src/runtime/goal-evaluator.ts +54 -19
  177. package/src/runtime/goal-loop-runner.ts +280 -99
  178. package/src/runtime/goal-state-store.ts +27 -17
  179. package/src/runtime/green-contract.ts +11 -2
  180. package/src/runtime/group-join.ts +64 -31
  181. package/src/runtime/handoff-manager.ts +37 -42
  182. package/src/runtime/heartbeat-gradient.ts +10 -2
  183. package/src/runtime/heartbeat-watcher.ts +32 -6
  184. package/src/runtime/hidden-handoff.ts +13 -31
  185. package/src/runtime/important-line-classifier.ts +12 -2
  186. package/src/runtime/iteration-hooks.ts +25 -15
  187. package/src/runtime/live-agent-control.ts +55 -7
  188. package/src/runtime/live-agent-manager.ts +130 -27
  189. package/src/runtime/live-control-realtime.ts +23 -3
  190. package/src/runtime/live-irc.ts +4 -1
  191. package/src/runtime/live-session-health.ts +12 -4
  192. package/src/runtime/live-session-runtime.ts +379 -117
  193. package/src/runtime/manifest-cache.ts +28 -12
  194. package/src/runtime/mcp-proxy.ts +10 -18
  195. package/src/runtime/metric-parser.ts +1 -5
  196. package/src/runtime/model-fallback.ts +55 -18
  197. package/src/runtime/model-resolver.ts +2 -6
  198. package/src/runtime/model-scope.ts +19 -3
  199. package/src/runtime/notebook-helpers.ts +60 -62
  200. package/src/runtime/orphan-worker-registry.ts +37 -26
  201. package/src/runtime/output-validator.ts +18 -3
  202. package/src/runtime/overflow-recovery.ts +5 -4
  203. package/src/runtime/parallel-research.ts +29 -5
  204. package/src/runtime/parallel-utils.ts +9 -11
  205. package/src/runtime/path-overlap.ts +150 -0
  206. package/src/runtime/peer-dep.ts +12 -17
  207. package/src/runtime/per-write-validator.ts +1 -3
  208. package/src/runtime/phase-tracker.ts +342 -330
  209. package/src/runtime/pi-args.ts +26 -8
  210. package/src/runtime/pi-json-output.ts +1 -1
  211. package/src/runtime/pi-spawn.ts +30 -19
  212. package/src/runtime/pipeline-runner.ts +56 -55
  213. package/src/runtime/plan-templates.ts +5 -6
  214. package/src/runtime/policy-engine.ts +43 -7
  215. package/src/runtime/post-checks.ts +12 -4
  216. package/src/runtime/post-exit-stdio-guard.ts +2 -2
  217. package/src/runtime/process-lifecycle.ts +20 -10
  218. package/src/runtime/process-status.ts +16 -5
  219. package/src/runtime/progress-event-coalescer.ts +2 -1
  220. package/src/runtime/progress-tracker.ts +103 -103
  221. package/src/runtime/prose-compressor.ts +9 -11
  222. package/src/runtime/recovery-recipes.ts +118 -24
  223. package/src/runtime/replace.ts +25 -10
  224. package/src/runtime/resilient-edit.ts +10 -25
  225. package/src/runtime/result-extractor.ts +2 -6
  226. package/src/runtime/retry-executor.ts +20 -4
  227. package/src/runtime/retry-runner.ts +27 -51
  228. package/src/runtime/role-permission.ts +6 -1
  229. package/src/runtime/run-coalesced-task-group.ts +256 -0
  230. package/src/runtime/run-drift.ts +14 -15
  231. package/src/runtime/run-tracker.ts +6 -28
  232. package/src/runtime/runtime-policy.ts +1 -6
  233. package/src/runtime/runtime-resolver.ts +80 -15
  234. package/src/runtime/scheduler.ts +47 -18
  235. package/src/runtime/semaphore.ts +5 -7
  236. package/src/runtime/sensitive-paths.ts +2 -1
  237. package/src/runtime/session-usage.ts +1 -1
  238. package/src/runtime/settings-store.ts +16 -12
  239. package/src/runtime/sidechain-output.ts +6 -2
  240. package/src/runtime/single-agent-compose.ts +1 -4
  241. package/src/runtime/skill-effectiveness.ts +29 -97
  242. package/src/runtime/skill-instructions.ts +40 -83
  243. package/src/runtime/stale-reconciler.ts +73 -197
  244. package/src/runtime/stream-preview.ts +1 -1
  245. package/src/runtime/streaming-output.ts +1 -1
  246. package/src/runtime/subagent-manager.ts +44 -169
  247. package/src/runtime/subprocess-tool-registry.ts +4 -1
  248. package/src/runtime/supervisor-contact.ts +10 -5
  249. package/src/runtime/task-display.ts +19 -5
  250. package/src/runtime/task-graph-scheduler.ts +95 -21
  251. package/src/runtime/task-graph.ts +5 -11
  252. package/src/runtime/task-health.ts +54 -47
  253. package/src/runtime/task-id.ts +12 -19
  254. package/src/runtime/task-output-context.ts +265 -81
  255. package/src/runtime/task-packet.ts +12 -20
  256. package/src/runtime/task-quality.ts +6 -14
  257. package/src/runtime/task-runner/context-retrieval.ts +4 -13
  258. package/src/runtime/task-runner/live-executor.ts +114 -36
  259. package/src/runtime/task-runner/output-splitter.ts +152 -0
  260. package/src/runtime/task-runner/progress.ts +50 -12
  261. package/src/runtime/task-runner/prompt-builder.ts +31 -7
  262. package/src/runtime/task-runner/prompt-pipeline.ts +31 -7
  263. package/src/runtime/task-runner/result-utils.ts +3 -1
  264. package/src/runtime/task-runner/retrieval-orchestrator.ts +310 -0
  265. package/src/runtime/task-runner/run-projection.ts +27 -8
  266. package/src/runtime/task-runner/state-helpers.ts +50 -14
  267. package/src/runtime/task-runner/tail-read.ts +2 -6
  268. package/src/runtime/task-runner.ts +180 -326
  269. package/src/runtime/team-runner-artifacts.ts +13 -0
  270. package/src/runtime/team-runner.ts +456 -974
  271. package/src/runtime/tool-output-pruner.ts +6 -9
  272. package/src/runtime/tool-progress.ts +11 -21
  273. package/src/runtime/verification-gates.ts +33 -24
  274. package/src/runtime/verification-integrity.ts +2 -7
  275. package/src/runtime/verification-worktree.ts +62 -12
  276. package/src/runtime/worker-heartbeat.ts +5 -1
  277. package/src/runtime/worker-startup.ts +29 -5
  278. package/src/runtime/workflow-state.ts +17 -9
  279. package/src/runtime/workspace-lock.ts +30 -35
  280. package/src/runtime/workspace-tree.ts +20 -32
  281. package/src/runtime/yield-handler.ts +43 -9
  282. package/src/runtime/zombie-scanner.ts +5 -4
  283. package/src/schema/config-schema.ts +266 -172
  284. package/src/schema/team-tool-schema.ts +29 -74
  285. package/src/schema/validation-types.ts +25 -17
  286. package/src/skills/discover-skills.ts +35 -10
  287. package/src/skills/skill-templates.ts +109 -27
  288. package/src/skills/validate.ts +26 -8
  289. package/src/state/active-run-registry.ts +87 -28
  290. package/src/state/artifact-store.ts +9 -5
  291. package/src/state/atomic-write-v2.ts +85 -63
  292. package/src/state/atomic-write.ts +106 -27
  293. package/src/state/blob-store.ts +47 -20
  294. package/src/state/contracts.ts +20 -5
  295. package/src/state/crew-init.ts +5 -22
  296. package/src/state/decision-ledger.ts +19 -73
  297. package/src/state/event-log-rotation.ts +41 -15
  298. package/src/state/event-log.ts +168 -53
  299. package/src/state/event-reconstructor.ts +11 -1
  300. package/src/state/gitignore-manager.ts +2 -8
  301. package/src/state/health-store.ts +57 -57
  302. package/src/state/hook-instinct-bridge.ts +1 -1
  303. package/src/state/hook-integrations.ts +1 -1
  304. package/src/state/instinct-store.ts +17 -5
  305. package/src/state/jsonl-writer.ts +1 -1
  306. package/src/state/locks.ts +23 -9
  307. package/src/state/mailbox.ts +151 -28
  308. package/src/state/observation-store.ts +20 -14
  309. package/src/state/run-cache.ts +142 -135
  310. package/src/state/run-graph.ts +6 -15
  311. package/src/state/run-metrics.ts +5 -18
  312. package/src/state/schedule.ts +15 -9
  313. package/src/state/state-store.ts +137 -47
  314. package/src/state/task-claims.ts +12 -2
  315. package/src/state/tiered-eval.ts +52 -43
  316. package/src/state/types-eval.ts +2 -2
  317. package/src/state/types.ts +24 -20
  318. package/src/state/usage.ts +20 -4
  319. package/src/state/worker-atomic-writer.ts +6 -3
  320. package/src/subagents/index.ts +2 -2
  321. package/src/teams/discover-teams.ts +21 -6
  322. package/src/tools/safe-bash-extension.ts +5 -6
  323. package/src/tools/safe-bash.ts +10 -11
  324. package/src/types/new-api-types.ts +6 -10
  325. package/src/ui/agent-management-overlay.ts +52 -40
  326. package/src/ui/card-colors.ts +13 -4
  327. package/src/ui/crew-footer.ts +8 -7
  328. package/src/ui/crew-select-list.ts +1 -1
  329. package/src/ui/dashboard-panes/agents-pane.ts +41 -25
  330. package/src/ui/dashboard-panes/cancellation-pane.ts +1 -1
  331. package/src/ui/dashboard-panes/capability-pane.ts +32 -15
  332. package/src/ui/dashboard-panes/health-pane.ts +2 -1
  333. package/src/ui/dashboard-panes/metrics-pane.ts +4 -1
  334. package/src/ui/dashboard-panes/progress-pane.ts +12 -9
  335. package/src/ui/heartbeat-aggregator.ts +15 -4
  336. package/src/ui/keybinding-map.ts +40 -7
  337. package/src/ui/live-conversation-overlay.ts +36 -20
  338. package/src/ui/live-duration.ts +1 -4
  339. package/src/ui/live-run-sidebar.ts +88 -25
  340. package/src/ui/loaders.ts +2 -8
  341. package/src/ui/mascot.ts +20 -36
  342. package/src/ui/overlays/agent-picker-overlay.ts +11 -3
  343. package/src/ui/overlays/confirm-overlay.ts +4 -2
  344. package/src/ui/overlays/help-overlay.ts +25 -14
  345. package/src/ui/overlays/mailbox-compose-overlay.ts +48 -11
  346. package/src/ui/overlays/mailbox-compose-preview.ts +20 -5
  347. package/src/ui/overlays/mailbox-detail-overlay.ts +27 -6
  348. package/src/ui/pi-ui-compat.ts +7 -7
  349. package/src/ui/powerbar-publisher.ts +120 -42
  350. package/src/ui/render-diff.ts +10 -3
  351. package/src/ui/render-scheduler.ts +12 -4
  352. package/src/ui/run-action-dispatcher.ts +81 -18
  353. package/src/ui/run-dashboard.ts +172 -76
  354. package/src/ui/run-event-bus.ts +59 -37
  355. package/src/ui/run-snapshot-cache.ts +276 -86
  356. package/src/ui/settings-overlay.ts +361 -74
  357. package/src/ui/status-colors.ts +12 -1
  358. package/src/ui/syntax-highlight.ts +1 -1
  359. package/src/ui/terminal-status.ts +1 -3
  360. package/src/ui/theme-adapter.ts +16 -14
  361. package/src/ui/theme-discovery.ts +13 -2
  362. package/src/ui/tool-progress-formatter.ts +7 -7
  363. package/src/ui/tool-render.ts +128 -56
  364. package/src/ui/tool-renderers/brief-mode.ts +45 -27
  365. package/src/ui/tool-renderers/index.ts +109 -43
  366. package/src/ui/transcript-cache.ts +32 -6
  367. package/src/ui/transcript-entries.ts +25 -23
  368. package/src/ui/transcript-viewer.ts +78 -29
  369. package/src/ui/widget/index.ts +99 -40
  370. package/src/ui/widget/widget-formatters.ts +13 -6
  371. package/src/ui/widget/widget-model.ts +19 -8
  372. package/src/ui/widget/widget-renderer.ts +23 -13
  373. package/src/ui/widget/widget-types.ts +1 -1
  374. package/src/utils/bm25-search.ts +199 -199
  375. package/src/utils/conflict-detect.ts +22 -21
  376. package/src/utils/env-filter.ts +14 -7
  377. package/src/utils/file-coalescer.ts +5 -1
  378. package/src/utils/fingerprint.ts +3 -6
  379. package/src/utils/frontmatter.ts +3 -1
  380. package/src/utils/fs-watch.ts +2 -6
  381. package/src/utils/gh-protocol.ts +119 -44
  382. package/src/utils/git.ts +13 -15
  383. package/src/utils/guards.ts +2 -5
  384. package/src/utils/ids.ts +9 -2
  385. package/src/utils/incremental-reader.ts +14 -3
  386. package/src/utils/internal-error.ts +2 -1
  387. package/src/utils/names.ts +12 -3
  388. package/src/utils/paths.ts +49 -5
  389. package/src/utils/project-detector.ts +2 -2
  390. package/src/utils/redaction.ts +29 -19
  391. package/src/utils/resolve-shell.ts +9 -7
  392. package/src/utils/run-watcher-registry.ts +19 -31
  393. package/src/utils/safe-paths.ts +46 -29
  394. package/src/utils/scan-cache.ts +9 -2
  395. package/src/utils/session-utils.ts +2 -4
  396. package/src/utils/sleep.ts +12 -5
  397. package/src/utils/sse-parser.ts +5 -17
  398. package/src/utils/visual.ts +52 -32
  399. package/src/workflows/discover-workflows.ts +41 -109
  400. package/src/workflows/intermediate-store.ts +5 -21
  401. package/src/workflows/preflight-validator.ts +6 -33
  402. package/src/workflows/topology-analyzer.ts +5 -21
  403. package/src/workflows/workflow-config.ts +7 -6
  404. package/src/worktree/branch-freshness.ts +66 -8
  405. package/src/worktree/cleanup.ts +130 -20
  406. package/src/worktree/worktree-manager.ts +212 -69
  407. package/skills/artifact-analysis-loop/SKILL.md +0 -303
  408. package/skills/detection-pipeline-design/SKILL.md +0 -286
  409. package/skills/hunting-investigation-loop/SKILL.md +0 -402
  410. package/skills/incident-playbook-construction/SKILL.md +0 -384
  411. package/skills/security-review/SKILL.md +0 -561
  412. package/skills/threat-hypothesis-framework/SKILL.md +0 -176
  413. package/skills/ui-render-performance/SKILL.md +0 -58
  414. /package/docs/{followup-review-round3-2026-05-12.md → archive/followup-review-round3-2026-05-12.md} +0 -0
  415. /package/docs/{followup-review-round4-2026-05-13.md → archive/followup-review-round4-2026-05-13.md} +0 -0
  416. /package/docs/{pi-crew-bugs.md → archive/pi-crew-bugs.md} +0 -0
  417. /package/docs/{pi-crew-test-final.md → archive/pi-crew-test-final.md} +0 -0
  418. /package/docs/{pi-crew-test-results.md → archive/pi-crew-test-results.md} +0 -0
  419. /package/docs/{pi-crew-test-round2.md → archive/pi-crew-test-round2.md} +0 -0
  420. /package/docs/{pi-crew-test-round4.md → archive/pi-crew-test-round4.md} +0 -0
  421. /package/docs/{pi-crew-test-round5.md → archive/pi-crew-test-round5.md} +0 -0
  422. /package/docs/{pi-crew-test-round6.md → archive/pi-crew-test-round6.md} +0 -0
  423. /package/docs/{pi-crew-v0.5.10-audit-fix-plan.md → archive/pi-crew-v0.5.10-audit-fix-plan.md} +0 -0
  424. /package/docs/{pi-crew-v0.5.11-audit-fix-plan.md → archive/pi-crew-v0.5.11-audit-fix-plan.md} +0 -0
  425. /package/docs/{pi-crew-v0.5.12-audit-fix-plan.md → archive/pi-crew-v0.5.12-audit-fix-plan.md} +0 -0
  426. /package/docs/{pi-crew-v0.5.13-audit-fix-plan.md → archive/pi-crew-v0.5.13-audit-fix-plan.md} +0 -0
  427. /package/docs/{pi-crew-v0.5.14-audit-fix-plan.md → archive/pi-crew-v0.5.14-audit-fix-plan.md} +0 -0
  428. /package/docs/{pi-crew-v0.5.16-audit-fix-plan.md → archive/pi-crew-v0.5.16-audit-fix-plan.md} +0 -0
  429. /package/docs/{pi-crew-v0.5.17-audit-fix-plan.md → archive/pi-crew-v0.5.17-audit-fix-plan.md} +0 -0
  430. /package/docs/{pi-crew-v0.5.5-audit-fix-plan.md → archive/pi-crew-v0.5.5-audit-fix-plan.md} +0 -0
  431. /package/docs/{pi-crew-v0.5.9-audit-fix-plan.md → archive/pi-crew-v0.5.9-audit-fix-plan.md} +0 -0
  432. /package/docs/{pi-mono-opportunities.md → archive/pi-mono-opportunities.md} +0 -0
  433. /package/docs/{pi-mono-review.md → archive/pi-mono-review.md} +0 -0
  434. /package/docs/{pi-subagent4-comparison.md → archive/pi-subagent4-comparison.md} +0 -0
  435. /package/docs/{pi-subagents3-deep-analysis.md → archive/pi-subagents3-deep-analysis.md} +0 -0
@@ -30,9 +30,9 @@ export function levenshtein(a: string, b: string): number {
30
30
  for (let j = 1; j <= lb; j++) {
31
31
  const cost = a[i - 1] === b[j - 1] ? 0 : 1;
32
32
  curr[j] = Math.min(
33
- prev[j] + 1, // deletion
34
- curr[j - 1] + 1, // insertion
35
- prev[j - 1] + cost // substitution
33
+ prev[j] + 1, // deletion
34
+ curr[j - 1] + 1, // insertion
35
+ prev[j - 1] + cost, // substitution
36
36
  );
37
37
  }
38
38
  const swap = prev;
@@ -49,11 +49,7 @@ const DEFAULT_MAX_DISTANCE = 3;
49
49
  * Find the closest matching key from a list of valid keys.
50
50
  * Case-insensitive. Returns null if no match within `maxDistance`.
51
51
  */
52
- export function findClosestKey(
53
- input: string,
54
- validKeys: readonly string[],
55
- maxDistance: number = DEFAULT_MAX_DISTANCE,
56
- ): string | null {
52
+ export function findClosestKey(input: string, validKeys: readonly string[], maxDistance: number = DEFAULT_MAX_DISTANCE): string | null {
57
53
  if (validKeys.length === 0) return null;
58
54
 
59
55
  const lower = input.toLowerCase();
@@ -74,9 +70,6 @@ export function findClosestKey(
74
70
  /**
75
71
  * Convenience wrapper — suggest the closest known config key for a potentially mistyped input.
76
72
  */
77
- export function suggestConfigKey(
78
- input: string,
79
- knownKeys: readonly string[],
80
- ): string | null {
73
+ export function suggestConfigKey(input: string, knownKeys: readonly string[]): string | null {
81
74
  return findClosestKey(input, knownKeys);
82
75
  }
@@ -6,11 +6,7 @@
6
6
  // file for backwards compat — existing `import { CrewUiConfig } from "../config/config.ts"`
7
7
  // continues to work.
8
8
 
9
- export type PiTeamsAutonomyProfile =
10
- | "manual"
11
- | "suggested"
12
- | "assisted"
13
- | "aggressive";
9
+ export type PiTeamsAutonomyProfile = "manual" | "suggested" | "assisted" | "aggressive";
14
10
 
15
11
  export interface PiTeamsAutonomousConfig {
16
12
  profile?: PiTeamsAutonomyProfile;
@@ -32,13 +28,14 @@ export interface CrewLimitsConfig {
32
28
  maxRetriesPerTask?: number;
33
29
  maxTasksPerRun?: number;
34
30
  heartbeatStaleMs?: number;
31
+ /** Round 25 (M5): serialize on write-path overlap. Default false (off).
32
+ * When true, the scheduler skips ready tasks whose declared `step.output`
33
+ * overlaps with already-picked tasks, so two workers never write the same
34
+ * file in parallel. See src/runtime/path-overlap.ts. */
35
+ serializeOnPathOverlap?: boolean;
35
36
  }
36
37
 
37
- export type CrewRuntimeMode =
38
- | "auto"
39
- | "scaffold"
40
- | "child-process"
41
- | "live-session";
38
+ export type CrewRuntimeMode = "auto" | "scaffold" | "child-process" | "live-session";
42
39
 
43
40
  export type CompletionMutationGuardMode = "off" | "warn" | "fail";
44
41
  export type EffectivenessGuardMode = "off" | "warn" | "block" | "fail";
@@ -109,16 +106,7 @@ export interface CrewUiConfig {
109
106
  showTools?: boolean;
110
107
  transcriptTailBytes?: number;
111
108
  mascotStyle?: "cat" | "armin";
112
- mascotEffect?:
113
- | "random"
114
- | "none"
115
- | "typewriter"
116
- | "scanline"
117
- | "rain"
118
- | "fade"
119
- | "crt"
120
- | "glitch"
121
- | "dissolve";
109
+ mascotEffect?: "random" | "none" | "typewriter" | "scanline" | "rain" | "fade" | "crt" | "glitch" | "dissolve";
122
110
  }
123
111
 
124
112
  export interface AgentOverrideConfig {
@@ -150,11 +138,7 @@ export interface CrewPolicyConfig {
150
138
  disabledCapabilities?: string[];
151
139
  }
152
140
 
153
- export type CrewNotificationSeverity =
154
- | "info"
155
- | "warning"
156
- | "error"
157
- | "critical";
141
+ export type CrewNotificationSeverity = "info" | "warning" | "error" | "critical";
158
142
 
159
143
  export interface CrewNotificationsConfig {
160
144
  enabled?: boolean;
package/src/errors.ts CHANGED
@@ -24,40 +24,47 @@
24
24
  // `--experimental-strip-types` can load this module. TypeScript `enum`
25
25
  // syntax is not supported in strip-only mode.
26
26
  export const ErrorCode = {
27
- FileReadError: "E001", // Cannot read a file
28
- FileWriteError: "E002", // Cannot write a file
29
- TaskNotFound: "E003", // Referenced task ID does not exist
30
- InvalidStatusTransition: "E004", // Run/task status cannot legally transition
31
- ConfigError: "E005", // Malformed config or missing required field
32
- ResourceNotFound: "E006", // Agent/team/workflow not found in discovery paths
33
- // E1 (Round 15): runtime failure categories that previously threw raw Error
34
- // with no code, no help hint, and no context. Surfaces actionable guidance.
35
- ChildTimeout: "E007", // Child Pi worker became unresponsive and was killed
36
- ModelExhausted: "E008", // All model candidates in the fallback chain failed
37
- PreStepFailed: "E009", // A pre-step hook script returned a non-zero exit
38
- EventLogLockTimeout: "E010", // Could not acquire the event-log file lock
39
- DepthLimitExceeded: "E011", // Pipeline/chain recursion depth limit hit (circular dep)
40
- RunStale: "E012", // Run reconciled as stale/zombie (heartbeat expired)
41
- ModelOutOfScope: "E013", // Caller-supplied model is not in pi's enabledModels allowlist (F7 scope gate)
27
+ FileReadError: "E001", // Cannot read a file
28
+ FileWriteError: "E002", // Cannot write a file
29
+ TaskNotFound: "E003", // Referenced task ID does not exist
30
+ InvalidStatusTransition: "E004", // Run/task status cannot legally transition
31
+ ConfigError: "E005", // Malformed config or missing required field
32
+ ResourceNotFound: "E006", // Agent/team/workflow not found in discovery paths
33
+ // E1 (Round 15): runtime failure categories that previously threw raw Error
34
+ // with no code, no help hint, and no context. Surfaces actionable guidance.
35
+ ChildTimeout: "E007", // Child Pi worker became unresponsive and was killed
36
+ ModelExhausted: "E008", // All model candidates in the fallback chain failed
37
+ PreStepFailed: "E009", // A pre-step hook script returned a non-zero exit
38
+ EventLogLockTimeout: "E010", // Could not acquire the event-log file lock
39
+ DepthLimitExceeded: "E011", // Pipeline/chain recursion depth limit hit (circular dep)
40
+ RunStale: "E012", // Run reconciled as stale/zombie (heartbeat expired)
41
+ ModelOutOfScope: "E013", // Caller-supplied model is not in pi's enabledModels allowlist (F7 scope gate)
42
42
  } as const;
43
43
 
44
- export type ErrorCode = typeof ErrorCode[keyof typeof ErrorCode];
44
+ export type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];
45
45
 
46
46
  const DEFAULT_HELP: Record<ErrorCode, string | undefined> = {
47
- [ErrorCode.FileReadError]: "Check that the file exists and that the process has read permission.",
48
- [ErrorCode.FileWriteError]: "Check that the disk is not full and that the process has write permission.",
49
- [ErrorCode.TaskNotFound]: "The task may have been removed or the run may be in an inconsistent state. Use `team status` to verify.",
50
- [ErrorCode.InvalidStatusTransition]: "Verify the run status using `team status` before retrying.",
51
- [ErrorCode.ConfigError]: "Check the configuration file for syntax errors or missing required fields.",
52
- [ErrorCode.ResourceNotFound]: "Use `team list` to see available agents, teams, and workflows.",
53
- // E1 (Round 15): help hints for the new runtime categories.
54
- [ErrorCode.ChildTimeout]: "The child Pi worker produced no output for too long and was terminated. Re-run the team; if it recurs, raise the response timeout in config or reduce the task scope.",
55
- [ErrorCode.ModelExhausted]: "Every model in the fallback chain failed. Check your API key/quota and the per-attempt errors, then retry or swap the model in config.",
56
- [ErrorCode.PreStepFailed]: "The pre-step hook script exited non-zero. Inspect its stderr, or mark it optional in the workflow step (preStepOptional).",
57
- [ErrorCode.EventLogLockTimeout]: "Another process holds the event-log lock. Check for orphaned `.lock` files or stale pi-crew processes, then retry.",
58
- [ErrorCode.DepthLimitExceeded]: "A pipeline/chain exceeded the recursion depth limit, which usually indicates a circular stage dependency. Review step `dependsOn` chains.",
59
- [ErrorCode.RunStale]: "The worker stopped heartbeating and was treated as a zombie. Re-run the team (resume or fresh); if it recurs, check `runtime.executeWorkers` / system load.",
60
- [ErrorCode.ModelOutOfScope]: "The requested model is not in your pi `enabledModels` allowlist. Either pick a model listed in `enabledModels` (settings.json) or extend the allowlist. The scope gate is opt-in — disable `runtime.reliability.scopeModels` to allow any model.",
47
+ [ErrorCode.FileReadError]: "Check that the file exists and that the process has read permission.",
48
+ [ErrorCode.FileWriteError]: "Check that the disk is not full and that the process has write permission.",
49
+ [ErrorCode.TaskNotFound]: "The task may have been removed or the run may be in an inconsistent state. Use `team status` to verify.",
50
+ [ErrorCode.InvalidStatusTransition]: "Verify the run status using `team status` before retrying.",
51
+ [ErrorCode.ConfigError]: "Check the configuration file for syntax errors or missing required fields.",
52
+ [ErrorCode.ResourceNotFound]: "Use `team list` to see available agents, teams, and workflows.",
53
+ // E1 (Round 15): help hints for the new runtime categories.
54
+ [ErrorCode.ChildTimeout]:
55
+ "The child Pi worker produced no output for too long and was terminated. Re-run the team; if it recurs, raise the response timeout in config or reduce the task scope.",
56
+ [ErrorCode.ModelExhausted]:
57
+ "Every model in the fallback chain failed. Check your API key/quota and the per-attempt errors, then retry or swap the model in config.",
58
+ [ErrorCode.PreStepFailed]:
59
+ "The pre-step hook script exited non-zero. Inspect its stderr, or mark it optional in the workflow step (preStepOptional).",
60
+ [ErrorCode.EventLogLockTimeout]:
61
+ "Another process holds the event-log lock. Check for orphaned `.lock` files or stale pi-crew processes, then retry.",
62
+ [ErrorCode.DepthLimitExceeded]:
63
+ "A pipeline/chain exceeded the recursion depth limit, which usually indicates a circular stage dependency. Review step `dependsOn` chains.",
64
+ [ErrorCode.RunStale]:
65
+ "The worker stopped heartbeating and was treated as a zombie. Re-run the team (resume or fresh); if it recurs, check `runtime.executeWorkers` / system load.",
66
+ [ErrorCode.ModelOutOfScope]:
67
+ "The requested model is not in your pi `enabledModels` allowlist. Either pick a model listed in `enabledModels` (settings.json) or extend the allowlist. The scope gate is opt-in — disable `runtime.reliability.scopeModels` to allow any model.",
61
68
  };
62
69
 
63
70
  /**
@@ -68,133 +75,120 @@ const DEFAULT_HELP: Record<ErrorCode, string | undefined> = {
68
75
  * help: Check that the file exists and that the process has read permission.
69
76
  */
70
77
  export class CrewError extends Error {
71
- readonly code: ErrorCode;
72
- help?: string;
73
- private _context?: string;
74
-
75
- constructor(code: ErrorCode, message: string, help?: string) {
76
- super(message);
77
- this.name = "CrewError";
78
- this.code = code;
79
- this.help = help ?? DEFAULT_HELP[code];
80
- Object.defineProperty(this, "message", { enumerable: true });
81
- Object.defineProperty(this, "code", { enumerable: true });
82
- }
83
-
84
- withContext(context: string): this {
85
- this._context = context;
86
- return this;
87
- }
88
-
89
- withHelp(help: string): this {
90
- this.help = help;
91
- return this;
92
- }
93
-
94
- toString(): string {
95
- let out = `error[${this.code}]: ${this.message}`;
96
- if (this._context) out += `\n context: ${this._context}`;
97
- if (this.help) out += `\n help: ${this.help}`;
98
- return out;
99
- }
78
+ readonly code: ErrorCode;
79
+ help?: string;
80
+ private _context?: string;
81
+
82
+ constructor(code: ErrorCode, message: string, help?: string) {
83
+ super(message);
84
+ this.name = "CrewError";
85
+ this.code = code;
86
+ this.help = help ?? DEFAULT_HELP[code];
87
+ Object.defineProperty(this, "message", { enumerable: true });
88
+ Object.defineProperty(this, "code", { enumerable: true });
89
+ }
90
+
91
+ withContext(context: string): this {
92
+ this._context = context;
93
+ return this;
94
+ }
95
+
96
+ withHelp(help: string): this {
97
+ this.help = help;
98
+ return this;
99
+ }
100
+
101
+ toString(): string {
102
+ let out = `error[${this.code}]: ${this.message}`;
103
+ if (this._context) out += `\n context: ${this._context}`;
104
+ if (this.help) out += `\n help: ${this.help}`;
105
+ return out;
106
+ }
100
107
  }
101
108
 
102
109
  export const errors = {
103
- fileRead(path: string, source: NodeJS.ErrnoException): CrewError {
104
- return new CrewError(
105
- ErrorCode.FileReadError,
106
- `Failed to read ${path}: ${source.code?.toLowerCase() ?? "unknown"}`,
107
- ).withContext("file system read operation");
108
- },
109
-
110
- fileWrite(path: string, source: NodeJS.ErrnoException): CrewError {
111
- return new CrewError(
112
- ErrorCode.FileWriteError,
113
- `Failed to write ${path}: ${source.code?.toLowerCase() ?? "unknown"}`,
114
- ).withContext("file system write operation");
115
- },
116
-
117
- taskNotFound(taskId: string, runId?: string): CrewError {
118
- const msg = runId
119
- ? `Task '${taskId}' not found in run '${runId}'`
120
- : `Task '${taskId}' not found`;
121
- return new CrewError(ErrorCode.TaskNotFound, msg);
122
- },
123
-
124
- invalidStatusTransition(from: string, to: string): CrewError {
125
- return new CrewError(
126
- ErrorCode.InvalidStatusTransition,
127
- `Invalid run status transition: ${from} -> ${to}`,
128
- );
129
- },
130
-
131
- config(message: string): CrewError {
132
- return new CrewError(ErrorCode.ConfigError, message)
133
- .withContext("configuration loading");
134
- },
135
-
136
- resourceNotFound(type: string, name: string): CrewError {
137
- return new CrewError(
138
- ErrorCode.ResourceNotFound,
139
- `${type} '${name}' not found in any discovery path`,
140
- );
141
- },
142
-
143
- // E1 (Round 15): runtime failure constructors. These wrap the raw-throw
144
- // sites identified in the Round 15 error-experience audit so failures carry
145
- // a machine-readable code, a help hint, and structured context.
146
- childTimeout(detail: { timeoutMs?: number; taskId?: string; stderr?: string }): CrewError {
147
- const tail = detail.stderr ? ` Stderr tail: ${detail.stderr.slice(-400)}` : "";
148
- const dur = detail.timeoutMs ? ` after ${detail.timeoutMs}ms of no output` : "";
149
- return new CrewError(
150
- ErrorCode.ChildTimeout,
151
- `Child Pi worker became unresponsive${dur} and was terminated.${tail}`,
152
- ).withContext(`worker execution${detail.taskId ? ` (task ${detail.taskId})` : ""}`);
153
- },
154
-
155
- modelExhausted(chain: string[], lastFailure?: string): CrewError {
156
- const tried = chain.join(" → ");
157
- const last = lastFailure ? ` Last failure: ${lastFailure}` : "";
158
- return new CrewError(
159
- ErrorCode.ModelExhausted,
160
- `All ${chain.length} model candidates exhausted (tried: ${tried}).${last}`,
161
- ).withContext("model fallback chain");
162
- },
163
-
164
- preStepFailed(script: string, exitCode: number | undefined, stderr?: string): CrewError {
165
- const tail = stderr ? ` Stderr: ${stderr.slice(-400)}` : "";
166
- return new CrewError(
167
- ErrorCode.PreStepFailed,
168
- `preStepScript '${script}' exited ${exitCode ?? "non-zero"}.${tail}`,
169
- ).withContext("pre-step hook execution");
170
- },
171
-
172
- eventLogLockTimeout(eventsPath: string, timeoutMs: number): CrewError {
173
- return new CrewError(
174
- ErrorCode.EventLogLockTimeout,
175
- `Event log lock timeout for ${eventsPath}: could not acquire lock within ${timeoutMs}ms`,
176
- ).withContext("event-log append");
177
- },
178
-
179
- depthLimitExceeded(depth: number, kind = "pipeline"): CrewError {
180
- return new CrewError(
181
- ErrorCode.DepthLimitExceeded,
182
- `${kind[0].toUpperCase() + kind.slice(1)} recursion depth limit exceeded (${depth}). Possible circular dependency.`,
183
- ).withContext(`${kind} execution`);
184
- },
185
-
186
- runStale(reason: string, heartbeatAgeSeconds?: number): CrewError {
187
- const age = heartbeatAgeSeconds !== undefined ? ` Last heartbeat was ${heartbeatAgeSeconds}s ago.` : "";
188
- return new CrewError(
189
- ErrorCode.RunStale,
190
- `Stale run reconciled (reason=${reason}).${age} The worker stopped heartbeating and was treated as dead/zombie.`,
191
- ).withContext("stale-run reconciliation");
192
- },
193
-
194
- modelOutOfScope(model: string, patterns: string[]): CrewError {
195
- return new CrewError(
196
- ErrorCode.ModelOutOfScope,
197
- `Requested model "${model}" is not in enabledModels scope (allowlist: [${patterns.join(", ")}])`,
198
- ).withContext("F7 model scope gate — caller override rejected");
199
- },
200
- } as const;
110
+ fileRead(path: string, source: NodeJS.ErrnoException): CrewError {
111
+ return new CrewError(ErrorCode.FileReadError, `Failed to read ${path}: ${source.code?.toLowerCase() ?? "unknown"}`).withContext(
112
+ "file system read operation",
113
+ );
114
+ },
115
+
116
+ fileWrite(path: string, source: NodeJS.ErrnoException): CrewError {
117
+ return new CrewError(ErrorCode.FileWriteError, `Failed to write ${path}: ${source.code?.toLowerCase() ?? "unknown"}`).withContext(
118
+ "file system write operation",
119
+ );
120
+ },
121
+
122
+ taskNotFound(taskId: string, runId?: string): CrewError {
123
+ const msg = runId ? `Task '${taskId}' not found in run '${runId}'` : `Task '${taskId}' not found`;
124
+ return new CrewError(ErrorCode.TaskNotFound, msg);
125
+ },
126
+
127
+ invalidStatusTransition(from: string, to: string): CrewError {
128
+ return new CrewError(ErrorCode.InvalidStatusTransition, `Invalid run status transition: ${from} -> ${to}`);
129
+ },
130
+
131
+ config(message: string): CrewError {
132
+ return new CrewError(ErrorCode.ConfigError, message).withContext("configuration loading");
133
+ },
134
+
135
+ resourceNotFound(type: string, name: string): CrewError {
136
+ return new CrewError(ErrorCode.ResourceNotFound, `${type} '${name}' not found in any discovery path`);
137
+ },
138
+
139
+ // E1 (Round 15): runtime failure constructors. These wrap the raw-throw
140
+ // sites identified in the Round 15 error-experience audit so failures carry
141
+ // a machine-readable code, a help hint, and structured context.
142
+ childTimeout(detail: { timeoutMs?: number; taskId?: string; stderr?: string }): CrewError {
143
+ const tail = detail.stderr ? ` Stderr tail: ${detail.stderr.slice(-400)}` : "";
144
+ const dur = detail.timeoutMs ? ` after ${detail.timeoutMs}ms of no output` : "";
145
+ return new CrewError(ErrorCode.ChildTimeout, `Child Pi worker became unresponsive${dur} and was terminated.${tail}`).withContext(
146
+ `worker execution${detail.taskId ? ` (task ${detail.taskId})` : ""}`,
147
+ );
148
+ },
149
+
150
+ modelExhausted(chain: string[], lastFailure?: string): CrewError {
151
+ const tried = chain.join(" ");
152
+ const last = lastFailure ? ` Last failure: ${lastFailure}` : "";
153
+ return new CrewError(
154
+ ErrorCode.ModelExhausted,
155
+ `All ${chain.length} model candidates exhausted (tried: ${tried}).${last}`,
156
+ ).withContext("model fallback chain");
157
+ },
158
+
159
+ preStepFailed(script: string, exitCode: number | undefined, stderr?: string): CrewError {
160
+ const tail = stderr ? ` Stderr: ${stderr.slice(-400)}` : "";
161
+ return new CrewError(ErrorCode.PreStepFailed, `preStepScript '${script}' exited ${exitCode ?? "non-zero"}.${tail}`).withContext(
162
+ "pre-step hook execution",
163
+ );
164
+ },
165
+
166
+ eventLogLockTimeout(eventsPath: string, timeoutMs: number): CrewError {
167
+ return new CrewError(
168
+ ErrorCode.EventLogLockTimeout,
169
+ `Event log lock timeout for ${eventsPath}: could not acquire lock within ${timeoutMs}ms`,
170
+ ).withContext("event-log append");
171
+ },
172
+
173
+ depthLimitExceeded(depth: number, kind = "pipeline"): CrewError {
174
+ return new CrewError(
175
+ ErrorCode.DepthLimitExceeded,
176
+ `${kind[0].toUpperCase() + kind.slice(1)} recursion depth limit exceeded (${depth}). Possible circular dependency.`,
177
+ ).withContext(`${kind} execution`);
178
+ },
179
+
180
+ runStale(reason: string, heartbeatAgeSeconds?: number): CrewError {
181
+ const age = heartbeatAgeSeconds !== undefined ? ` Last heartbeat was ${heartbeatAgeSeconds}s ago.` : "";
182
+ return new CrewError(
183
+ ErrorCode.RunStale,
184
+ `Stale run reconciled (reason=${reason}).${age} The worker stopped heartbeating and was treated as dead/zombie.`,
185
+ ).withContext("stale-run reconciliation");
186
+ },
187
+
188
+ modelOutOfScope(model: string, patterns: string[]): CrewError {
189
+ return new CrewError(
190
+ ErrorCode.ModelOutOfScope,
191
+ `Requested model "${model}" is not in enabledModels scope (allowlist: [${patterns.join(", ")}])`,
192
+ ).withContext("F7 model scope gate — caller override rejected");
193
+ },
194
+ } as const;
@@ -21,15 +21,60 @@ import { findClosestKey } from "../config/suggestions.ts";
21
21
  * the single source of truth.
22
22
  */
23
23
  export const KNOWN_TEAM_ACTIONS = [
24
- "run", "parallel", "plan", "status", "wait", "list", "get",
25
- "cancel", "retry", "resume", "respond", "create", "update", "delete",
26
- "doctor", "cleanup", "events", "artifacts", "worktrees", "forget",
27
- "summary", "prune", "export", "import", "imports", "help", "validate",
28
- "config", "init", "recommend", "autonomy", "api", "settings", "steer",
29
- "invalidate", "health", "graph", "onboard", "explain", "cache",
30
- "checkpoint", "search", "orchestrate", "schedule", "scheduled", "anchor",
31
- "auto-summarize", "auto_boomerang", "goal",
32
- "workflow-create", "workflow-get", "workflow-list", "workflow-save", "workflow-delete",
24
+ "run",
25
+ "parallel",
26
+ "plan",
27
+ "status",
28
+ "wait",
29
+ "list",
30
+ "get",
31
+ "cancel",
32
+ "retry",
33
+ "resume",
34
+ "respond",
35
+ "create",
36
+ "update",
37
+ "delete",
38
+ "doctor",
39
+ "cleanup",
40
+ "events",
41
+ "artifacts",
42
+ "worktrees",
43
+ "forget",
44
+ "summary",
45
+ "prune",
46
+ "export",
47
+ "import",
48
+ "imports",
49
+ "help",
50
+ "validate",
51
+ "config",
52
+ "init",
53
+ "recommend",
54
+ "autonomy",
55
+ "api",
56
+ "settings",
57
+ "steer",
58
+ "invalidate",
59
+ "health",
60
+ "graph",
61
+ "onboard",
62
+ "explain",
63
+ "cache",
64
+ "checkpoint",
65
+ "search",
66
+ "orchestrate",
67
+ "schedule",
68
+ "scheduled",
69
+ "anchor",
70
+ "auto-summarize",
71
+ "auto_boomerang",
72
+ "goal",
73
+ "workflow-create",
74
+ "workflow-get",
75
+ "workflow-list",
76
+ "workflow-save",
77
+ "workflow-delete",
33
78
  ] as const;
34
79
 
35
80
  /**
@@ -1,12 +1,12 @@
1
1
  import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
2
- import { appendEvent, readEvents, type TeamEvent } from "../state/event-log.ts";
2
+ import { readCrewAgents, saveCrewAgents } from "../runtime/crew-agent-records.ts";
3
3
  import { checkProcessLiveness, isActiveRunStatus } from "../runtime/process-status.ts";
4
+ import { appendEvent, readEvents, type TeamEvent } from "../state/event-log.ts";
5
+ import { withRunLockSync } from "../state/locks.ts";
4
6
  import { loadRunManifestById, saveRunTasks, updateRunStatus } from "../state/state-store.ts";
5
7
  import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
6
- import { readCrewAgents, saveCrewAgents } from "../runtime/crew-agent-records.ts";
7
- import { withRunLockSync } from "../state/locks.ts";
8
- import { listRuns } from "./run-index.ts";
9
8
  import { logInternalError } from "../utils/internal-error.ts";
9
+ import { listRuns } from "./run-index.ts";
10
10
 
11
11
  export interface AsyncNotifierState {
12
12
  seenFinishedRunIds: Set<string>;
@@ -51,15 +51,35 @@ function markActiveTasksAndAgentsFailed(run: TeamRunManifest, message: string):
51
51
  const tasks = loaded?.tasks ?? [];
52
52
  const failedAt = new Date().toISOString();
53
53
  if (tasks.some(isTaskActive)) {
54
- saveRunTasks(run, tasks.map((task) => isTaskActive(task) ? { ...task, status: "failed", finishedAt: failedAt, error: message } : task));
54
+ saveRunTasks(
55
+ run,
56
+ tasks.map((task) =>
57
+ isTaskActive(task)
58
+ ? {
59
+ ...task,
60
+ status: "failed",
61
+ finishedAt: failedAt,
62
+ error: message,
63
+ }
64
+ : task,
65
+ ),
66
+ );
55
67
  }
56
68
  const agents = readCrewAgents(run);
57
69
  if (agents.some((agent) => agent.status === "running" || agent.status === "queued" || agent.status === "waiting")) {
58
- saveCrewAgents(run, agents.map((agent) =>
59
- agent.status === "running" || agent.status === "queued" || agent.status === "waiting"
60
- ? { ...agent, status: "failed", completedAt: failedAt, error: message }
61
- : agent,
62
- ));
70
+ saveCrewAgents(
71
+ run,
72
+ agents.map((agent) =>
73
+ agent.status === "running" || agent.status === "queued" || agent.status === "waiting"
74
+ ? {
75
+ ...agent,
76
+ status: "failed",
77
+ completedAt: failedAt,
78
+ error: message,
79
+ }
80
+ : agent,
81
+ ),
82
+ );
63
83
  }
64
84
  }
65
85
 
@@ -77,16 +97,26 @@ export function markDeadAsyncRunIfNeeded(run: TeamRunManifest, now = Date.now(),
77
97
  if (!fresh || !isActiveRunStatus(fresh.manifest.status)) return undefined;
78
98
  const failed = updateRunStatus(fresh.manifest, "failed", message);
79
99
  markActiveTasksAndAgentsFailed(failed, message);
80
- appendEvent(failed.eventsPath, { type: "async.died", runId: failed.runId, message, data: { pid: asyncPid, detail: liveness.detail } });
100
+ appendEvent(failed.eventsPath, {
101
+ type: "async.died",
102
+ runId: failed.runId,
103
+ message,
104
+ data: { pid: asyncPid, detail: liveness.detail },
105
+ });
81
106
  return failed;
82
107
  });
83
108
  }
84
109
 
85
110
  const LIST_RUNS_DEBOUNCE_MS = 30_000;
86
111
 
87
- export function startAsyncRunNotifier(ctx: ExtensionContext, state: AsyncNotifierState, intervalMs = 5000, options: AsyncNotifierOptions = {}): void {
112
+ export function startAsyncRunNotifier(
113
+ ctx: ExtensionContext,
114
+ state: AsyncNotifierState,
115
+ intervalMs = 5000,
116
+ options: AsyncNotifierOptions = {},
117
+ ): void {
88
118
  if (state.interval) clearInterval(state.interval);
89
- const generation = options.generation ?? ((state.generation ?? 0) + 1);
119
+ const generation = options.generation ?? (state.generation ?? 0) + 1;
90
120
  state.generation = generation;
91
121
  const startedAtMs = Date.now();
92
122
  const staleBeforeMs = state.lastStoppedAtMs ?? startedAtMs;