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
@@ -22,25 +22,25 @@
22
22
  * `setResult()` reaches the main context.
23
23
  */
24
24
 
25
- import { runChildPi } from "./child-pi.ts";
26
- import { parsePiJsonOutput } from "./pi-json-output.ts";
27
- import { extractStructuredResult } from "./result-extractor.ts";
28
- import { mapConcurrent } from "./parallel-utils.ts";
29
- import { Semaphore } from "./semaphore.ts";
30
- import { executeWithRetry } from "./retry-executor.ts";
25
+ import { randomBytes } from "node:crypto";
26
+ import type { TSchema } from "@sinclair/typebox";
27
+ import type { AgentConfig } from "../agents/agent-config.ts";
31
28
  import { allAgents, discoverAgents } from "../agents/discover-agents.ts";
32
29
  import { writeArtifact } from "../state/artifact-store.ts";
33
30
  import { appendEvent } from "../state/event-log.ts";
34
31
  import { appendMailboxMessage, readMailbox } from "../state/mailbox.ts";
35
- import { renderPlanTemplate } from "./plan-templates.ts";
36
- import { prepareAgentWorktree, cleanupAgentWorktree } from "../worktree/worktree-manager.ts";
37
- import { logInternalError } from "../utils/internal-error.ts";
38
- import { randomBytes } from "node:crypto";
39
- import type { TSchema } from "@sinclair/typebox";
40
- import type { AgentConfig } from "../agents/agent-config.ts";
41
- import type { TeamConfig } from "../teams/team-config.ts";
42
32
  import type { TeamRunManifest } from "../state/types.ts";
33
+ import type { TeamConfig } from "../teams/team-config.ts";
34
+ import { logInternalError } from "../utils/internal-error.ts";
35
+ import { cleanupAgentWorktree, prepareAgentWorktree } from "../worktree/worktree-manager.ts";
36
+ import { runChildPi } from "./child-pi.ts";
43
37
  import type { DwfCheckpointState } from "./dwf-state-store.ts";
38
+ import { mapConcurrent } from "./parallel-utils.ts";
39
+ import { parsePiJsonOutput } from "./pi-json-output.ts";
40
+ import { renderPlanTemplate } from "./plan-templates.ts";
41
+ import { extractStructuredResult } from "./result-extractor.ts";
42
+ import { executeWithRetry } from "./retry-executor.ts";
43
+ import { Semaphore } from "./semaphore.ts";
44
44
 
45
45
  export interface AgentCallOpts {
46
46
  prompt: string;
@@ -120,11 +120,31 @@ export interface WorkflowCtx {
120
120
  ...stages: Array<(previous: TResult, original: TItem, index: number) => Promise<TResult> | TResult>
121
121
  ): Promise<(TResult | null)[]>;
122
122
  /** Run a reviewer agent over an artifact; parse {outcome, feedback}. §3.2. */
123
- review(taskId: string, reviewerRole?: string, opts?: { content?: string; artifactPath?: string; disableTools?: boolean }): Promise<{ outcome: "accept" | "reject" | "changes_requested"; feedback: string }>;
123
+ review(
124
+ taskId: string,
125
+ reviewerRole?: string,
126
+ opts?: {
127
+ content?: string;
128
+ artifactPath?: string;
129
+ disableTools?: boolean;
130
+ },
131
+ ): Promise<{
132
+ outcome: "accept" | "reject" | "changes_requested";
133
+ feedback: string;
134
+ }>;
124
135
  /** Re-run a task with feedback (wraps executeWithRetry). */
125
136
  retry(taskId: string, opts?: { feedback?: string }): Promise<AgentResult>;
126
137
  /** Send a mailbox message to another agent/leader. */
127
- mail(to: string, body: string, opts?: { kind?: string; taskId?: string; replyTo?: string; replyDeadline?: number }): string;
138
+ mail(
139
+ to: string,
140
+ body: string,
141
+ opts?: {
142
+ kind?: string;
143
+ taskId?: string;
144
+ replyTo?: string;
145
+ replyDeadline?: number;
146
+ },
147
+ ): string;
128
148
  /** Block until N mailbox replies arrive or deadline. ~10 LOC net-new (report 05 §G.4). */
129
149
  gatherReplies(messageIds: string[], deadlineMs: number): Promise<unknown[]>;
130
150
  /** Render a built-in plan template (full-implementation / standard-review). */
@@ -235,7 +255,10 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
235
255
  // The events log is the durable source of truth for phase boundaries.
236
256
  // round-18 P2-3: hydrate phaseState from a resumed checkpoint (backward compatible when unset).
237
257
  let phaseState: { currentPhase: string | undefined; phases: string[] } = opts.resumedState
238
- ? { currentPhase: opts.resumedState.currentPhase, phases: [...opts.resumedState.phases] }
258
+ ? {
259
+ currentPhase: opts.resumedState.currentPhase,
260
+ phases: [...opts.resumedState.phases],
261
+ }
239
262
  : { currentPhase: undefined, phases: [] };
240
263
  let phaseCapWarned = false;
241
264
  // round-14 P1-2/P1-3/P1-5: closure-scoped runtime state shared by budget/log/args.
@@ -271,7 +294,12 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
271
294
  // round-14 P1-2: budget check BEFORE spawning. When the per-workflow token
272
295
  // budget is exhausted, reject the call without consuming a child worker.
273
296
  if (budget.total !== null && budget.remaining() <= 0) {
274
- return { ok: false, text: "", error: "workflow token budget exhausted", durationMs: 0 };
297
+ return {
298
+ ok: false,
299
+ text: "",
300
+ error: "workflow token budget exhausted",
301
+ durationMs: 0,
302
+ };
275
303
  }
276
304
  const agentConfig = resolveAgentForRole(call.role, {
277
305
  explicitAgent: call.agent,
@@ -301,7 +329,10 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
301
329
  systemPrompt: composeSchemaSystemPrompt(base, call.schema),
302
330
  };
303
331
  } else if (call.systemPrompt !== undefined) {
304
- effectiveAgent = { ...effectiveAgent, systemPrompt: call.systemPrompt };
332
+ effectiveAgent = {
333
+ ...effectiveAgent,
334
+ systemPrompt: call.systemPrompt,
335
+ };
305
336
  }
306
337
  const task = composeAgentTask(call);
307
338
 
@@ -311,10 +342,7 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
311
342
  // when worktree creation is unavailable (no git repo, dirty leader).
312
343
  let agentCwd = manifest.cwd;
313
344
  if (call.worktree === true) {
314
- const wt = prepareAgentWorktree(
315
- manifest,
316
- `dwf-agent-${Date.now()}-${randomBytes(4).toString("hex")}`,
317
- );
345
+ const wt = prepareAgentWorktree(manifest, `dwf-agent-${Date.now()}-${randomBytes(4).toString("hex")}`);
318
346
  if (wt?.worktreePath) {
319
347
  agentCwd = wt.cwd;
320
348
  worktreePath = wt.worktreePath;
@@ -339,7 +367,12 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
339
367
  role: call.role ?? call.agent,
340
368
  });
341
369
  if (childResult.exitCode !== 0 || childResult.error) {
342
- return { ok: false, text: "", error: childResult.error ?? `exit ${childResult.exitCode}`, durationMs: Date.now() - started };
370
+ return {
371
+ ok: false,
372
+ text: "",
373
+ error: childResult.error ?? `exit ${childResult.exitCode}`,
374
+ durationMs: Date.now() - started,
375
+ };
343
376
  }
344
377
  const parsed = parsePiJsonOutput(childResult.stdout);
345
378
  // round-14 P1-2: accumulate this run's token usage into the workflow budget.
@@ -386,7 +419,12 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
386
419
  };
387
420
  } catch (error) {
388
421
  logInternalError("dynamic-workflow-context.agent", error, `runId=${manifest.runId}`);
389
- return { ok: false, text: "", error: error instanceof Error ? error.message : String(error), durationMs: Date.now() - started };
422
+ return {
423
+ ok: false,
424
+ text: "",
425
+ error: error instanceof Error ? error.message : String(error),
426
+ durationMs: Date.now() - started,
427
+ };
390
428
  } finally {
391
429
  // round-17 P2-4: clean up the worktree after the agent completes (success
392
430
  // OR failure). Captures the diff as an artifact before removal. Best-effort
@@ -452,7 +490,18 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
452
490
  return value as TResult;
453
491
  });
454
492
  },
455
- async review(taskId: string, reviewerRole = "reviewer", reviewOpts?: { content?: string; artifactPath?: string; disableTools?: boolean }): Promise<{ outcome: "accept" | "reject" | "changes_requested"; feedback: string }> {
493
+ async review(
494
+ taskId: string,
495
+ reviewerRole = "reviewer",
496
+ reviewOpts?: {
497
+ content?: string;
498
+ artifactPath?: string;
499
+ disableTools?: boolean;
500
+ },
501
+ ): Promise<{
502
+ outcome: "accept" | "reject" | "changes_requested";
503
+ feedback: string;
504
+ }> {
456
505
  // review() is a VERDICT step: it must produce a parseable JSON {outcome, feedback}, not a
457
506
  // free-form markdown review. The resolved reviewer agent (e.g. ~/.pi/agent/agents/reviewer.md)
458
507
  // has tools (read/grep/bash) + a markdown-output system prompt. Without disableTools, the
@@ -470,13 +519,15 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
470
519
  prompt: `You are reviewing the work for task '${taskId}'.${workContext}\n\nEvaluate the work and respond with ONLY a single JSON object, no prose, no markdown:\n{"outcome":"accept|reject|changes_requested","feedback":"<one-paragraph explanation>"}\n\n- "accept": work is complete and correct.\n- "reject": work is fundamentally wrong.\n- "changes_requested": work needs revision (explain what in feedback).`,
471
520
  maxTurns: 3,
472
521
  disableTools,
473
- systemPrompt: "You are a JSON verdict judge. You output ONLY a single JSON object with keys \"outcome\" (one of accept/reject/changes_requested) and \"feedback\" (a concise explanation). Never output prose, markdown, or code fences. Begin your response with { and end with }.",
522
+ systemPrompt:
523
+ 'You are a JSON verdict judge. You output ONLY a single JSON object with keys "outcome" (one of accept/reject/changes_requested) and "feedback" (a concise explanation). Never output prose, markdown, or code fences. Begin your response with { and end with }.',
474
524
  });
475
525
  const extracted = res.structured as { outcome?: string; feedback?: string } | undefined;
476
526
  if (extracted && typeof extracted.outcome === "string" && typeof extracted.feedback === "string") {
477
- const outcome = (extracted.outcome === "accept" || extracted.outcome === "reject" || extracted.outcome === "changes_requested")
478
- ? extracted.outcome
479
- : "changes_requested";
527
+ const outcome =
528
+ extracted.outcome === "accept" || extracted.outcome === "reject" || extracted.outcome === "changes_requested"
529
+ ? extracted.outcome
530
+ : "changes_requested";
480
531
  return { outcome, feedback: extracted.feedback };
481
532
  }
482
533
  // Fallback (round-11 runtime): many models (e.g. MiniMax-M3) ignore JSON-output
@@ -491,13 +542,15 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
491
542
  prompt: `Convert the following code review into a verdict JSON. Read the review and decide the outcome.\n\nREVIEW:\n"""\n${res.text.slice(0, 4000)}\n"""\n\nRespond with ONLY a JSON object:\n{"outcome":"accept|reject|changes_requested","feedback":"<concise summary>"}\n- accept: review found no real issues.\n- reject: review found critical/fundamental problems.\n- changes_requested: review found issues that need fixing.`,
492
543
  maxTurns: 1,
493
544
  disableTools: true,
494
- systemPrompt: "You output ONLY a single JSON object with keys outcome and feedback. Begin with { and end with }. Never output prose.",
545
+ systemPrompt:
546
+ "You output ONLY a single JSON object with keys outcome and feedback. Begin with { and end with }. Never output prose.",
495
547
  });
496
548
  const judged = judge.structured as { outcome?: string; feedback?: string } | undefined;
497
549
  if (judged && typeof judged.outcome === "string" && typeof judged.feedback === "string") {
498
- const outcome = (judged.outcome === "accept" || judged.outcome === "reject" || judged.outcome === "changes_requested")
499
- ? judged.outcome
500
- : "changes_requested";
550
+ const outcome =
551
+ judged.outcome === "accept" || judged.outcome === "reject" || judged.outcome === "changes_requested"
552
+ ? judged.outcome
553
+ : "changes_requested";
501
554
  return { outcome, feedback: judged.feedback };
502
555
  }
503
556
  }
@@ -510,20 +563,41 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
510
563
  // always the hardcoded 'changes_requested' default (e.g. correct code was
511
564
  // misclassified as needing changes).
512
565
  if (res.text.trim()) {
513
- return { outcome: classifyReviewOutcome(res.text), feedback: res.text };
566
+ return {
567
+ outcome: classifyReviewOutcome(res.text),
568
+ feedback: res.text,
569
+ };
514
570
  }
515
- return { outcome: "changes_requested", feedback: res.text || "(reviewer produced no parseable verdict)" };
571
+ return {
572
+ outcome: "changes_requested",
573
+ feedback: res.text || "(reviewer produced no parseable verdict)",
574
+ };
516
575
  },
517
576
  async retry(taskId: string, retryOpts?: { feedback?: string }): Promise<AgentResult> {
518
577
  return executeWithRetry(
519
- async () => ctx.agent({
520
- role: "executor",
521
- prompt: `Re-do task '${taskId}'.${retryOpts?.feedback ? ` Feedback: ${retryOpts.feedback}` : ""}`,
522
- }),
523
- { maxAttempts: 3, backoffMs: 0, jitterRatio: 0, exponentialFactor: 1 },
578
+ async () =>
579
+ ctx.agent({
580
+ role: "executor",
581
+ prompt: `Re-do task '${taskId}'.${retryOpts?.feedback ? ` Feedback: ${retryOpts.feedback}` : ""}`,
582
+ }),
583
+ {
584
+ maxAttempts: 3,
585
+ backoffMs: 0,
586
+ jitterRatio: 0,
587
+ exponentialFactor: 1,
588
+ },
524
589
  );
525
590
  },
526
- mail(to: string, body: string, mailOpts?: { kind?: string; taskId?: string; replyTo?: string; replyDeadline?: number }): string {
591
+ mail(
592
+ to: string,
593
+ body: string,
594
+ mailOpts?: {
595
+ kind?: string;
596
+ taskId?: string;
597
+ replyTo?: string;
598
+ replyDeadline?: number;
599
+ },
600
+ ): string {
527
601
  const msg = appendMailboxMessage(manifest, {
528
602
  direction: "outbox",
529
603
  from: "dynamic-workflow",
@@ -577,7 +651,9 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
577
651
  phaseCapWarned = true;
578
652
  logInternalError(
579
653
  "dynamic-workflow-context.phase-cap",
580
- new Error("Phase list cap of 100 reached; further phases still emit events but are not added to the in-memory phases[] list. Use the events log as the durable source of truth."),
654
+ new Error(
655
+ "Phase list cap of 100 reached; further phases still emit events but are not added to the in-memory phases[] list. Use the events log as the durable source of truth.",
656
+ ),
581
657
  `runId=${manifest.runId}`,
582
658
  );
583
659
  }
@@ -638,12 +714,26 @@ export function makeWorkflowCtx(manifest: TeamRunManifest, opts: MakeWorkflowCtx
638
714
 
639
715
  /** Read the final result set by the script (runner-only; not part of the public ctx surface). */
640
716
  export function getWorkflowFinalResult(ctx: WorkflowCtx): { artifactPath: string; meta?: Record<string, unknown> } | undefined {
641
- return (ctx as unknown as { __finalResult?: { artifactPath: string; meta?: Record<string, unknown> } }).__finalResult;
717
+ return (
718
+ ctx as unknown as {
719
+ __finalResult?: {
720
+ artifactPath: string;
721
+ meta?: Record<string, unknown>;
722
+ };
723
+ }
724
+ ).__finalResult;
642
725
  }
643
726
 
644
727
  /** Read the in-memory phase state set by the script (runner-only; not part of the public ctx surface). */
645
728
  export function getWorkflowPhaseState(ctx: WorkflowCtx): { currentPhase: string | undefined; phases: string[] } | undefined {
646
- return (ctx as unknown as { __phaseState?: { currentPhase: string | undefined; phases: string[] } }).__phaseState;
729
+ return (
730
+ ctx as unknown as {
731
+ __phaseState?: {
732
+ currentPhase: string | undefined;
733
+ phases: string[];
734
+ };
735
+ }
736
+ ).__phaseState;
647
737
  }
648
738
 
649
739
  /** Read the in-memory log buffer appended by ctx.log() (runner-only; not part of the public ctx surface).
@@ -753,22 +843,58 @@ export function classifyReviewOutcome(prose: string): "accept" | "reject" | "cha
753
843
  const text = prose.toLowerCase();
754
844
  // Strong negative signals → reject. These indicate fundamental/critical problems.
755
845
  const rejectSignals = [
756
- "\breject\b", "fundamentally", "completely broken", "totally broken",
757
- "critical bug", "critical issue", "critical flaw", "security vulnerability",
758
- "does not work", "doesn't work", "will not work", "fails to",
759
- "unacceptable", "must not be merged", "do not merge", "wrong approach",
760
- "logically incorrect", "incorrectly implements", "returns the opposite",
761
- "subtraction instead of addition", "opposite of its intended",
846
+ "\breject\b",
847
+ "fundamentally",
848
+ "completely broken",
849
+ "totally broken",
850
+ "critical bug",
851
+ "critical issue",
852
+ "critical flaw",
853
+ "security vulnerability",
854
+ "does not work",
855
+ "doesn't work",
856
+ "will not work",
857
+ "fails to",
858
+ "unacceptable",
859
+ "must not be merged",
860
+ "do not merge",
861
+ "wrong approach",
862
+ "logically incorrect",
863
+ "incorrectly implements",
864
+ "returns the opposite",
865
+ "subtraction instead of addition",
866
+ "opposite of its intended",
762
867
  ];
763
868
  // Acceptance signals → accept. These indicate explicit approval with no real issues.
764
869
  const acceptSignals = [
765
- "\baccept\b", "looks good", "well done", "no issues", "no real issues",
766
- "no problems", "no concerns", "nothing to change", "ready to merge",
767
- "lgtm", "ship it", "correctly implements", "correctly returns",
768
- "works as expected", "works correctly", "no bugs", "no defects",
769
- "meets all requirements", "all requirements met", "passes all",
770
- "is correct", "are correct", "no changes needed", "no changes required",
771
- "no further changes", "nothing more to", "complete and correct", "sound implementation",
870
+ "\baccept\b",
871
+ "looks good",
872
+ "well done",
873
+ "no issues",
874
+ "no real issues",
875
+ "no problems",
876
+ "no concerns",
877
+ "nothing to change",
878
+ "ready to merge",
879
+ "lgtm",
880
+ "ship it",
881
+ "correctly implements",
882
+ "correctly returns",
883
+ "works as expected",
884
+ "works correctly",
885
+ "no bugs",
886
+ "no defects",
887
+ "meets all requirements",
888
+ "all requirements met",
889
+ "passes all",
890
+ "is correct",
891
+ "are correct",
892
+ "no changes needed",
893
+ "no changes required",
894
+ "no further changes",
895
+ "nothing more to",
896
+ "complete and correct",
897
+ "sound implementation",
772
898
  ];
773
899
  const hasReject = rejectSignals.some((sig) => new RegExp(sig).test(text));
774
900
  const hasAccept = acceptSignals.some((sig) => new RegExp(sig).test(text));
@@ -808,7 +934,9 @@ export function extractTextFallback(stdout: string): string {
808
934
  try {
809
935
  const obj = JSON.parse(lineTrim);
810
936
  collect(obj);
811
- } catch { /* skip */ }
937
+ } catch {
938
+ /* skip */
939
+ }
812
940
  }
813
941
  // 2. If nothing from JSON, try plain text (longest non-empty line that's not JSON)
814
942
  if (candidates.length === 0) {
@@ -19,16 +19,16 @@
19
19
 
20
20
  import { readFileSync } from "node:fs";
21
21
  import { join } from "node:path";
22
- import { resolveRealContainedPath } from "../utils/safe-paths.ts";
23
- import { appendEvent } from "../state/event-log.ts";
24
22
  import { writeArtifact } from "../state/artifact-store.ts";
23
+ import { appendEvent } from "../state/event-log.ts";
24
+ import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
25
25
  import { logInternalError } from "../utils/internal-error.ts";
26
- import { makeWorkflowCtx, getWorkflowFinalResult, getWorkflowPhaseState } from "./dynamic-workflow-context.ts";
27
- import { DwfStore } from "./dwf-state-store.ts";
28
- import { assertDeterministicScript, isDeterminismCheckEnabled } from "./deterministic-ast.ts";
29
- import { projectCrewRoot, userPiRoot, packageRoot } from "../utils/paths.ts";
26
+ import { packageRoot, projectCrewRoot, userPiRoot } from "../utils/paths.ts";
27
+ import { resolveRealContainedPath } from "../utils/safe-paths.ts";
30
28
  import type { DynamicWorkflowConfig } from "../workflows/workflow-config.ts";
31
- import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
29
+ import { assertDeterministicScript, isDeterminismCheckEnabled } from "./deterministic-ast.ts";
30
+ import { DwfStore } from "./dwf-state-store.ts";
31
+ import { getWorkflowFinalResult, getWorkflowPhaseState, makeWorkflowCtx } from "./dynamic-workflow-context.ts";
32
32
 
33
33
  export interface RunDynamicWorkflowInput {
34
34
  manifest: TeamRunManifest;
@@ -84,11 +84,7 @@ function resolveScriptPath(workflow: DynamicWorkflowConfig, cwd: string): string
84
84
  // Fix round-5 P1: the round-4 P2-5 fix over-corrected to a SINGLE base (crewRoot/workflows).
85
85
  // But discoverWorkflows() reads from THREE dirs (builtin, user, project). Use the same bases
86
86
  // so user/builtin dynamic workflows aren't rejected.
87
- const allowedBases = [
88
- join(projectCrewRoot(cwd), "workflows"),
89
- join(userPiRoot(), "workflows"),
90
- join(packageRoot(), "workflows"),
91
- ];
87
+ const allowedBases = [join(projectCrewRoot(cwd), "workflows"), join(userPiRoot(), "workflows"), join(packageRoot(), "workflows")];
92
88
  for (const base of allowedBases) {
93
89
  try {
94
90
  const real = resolveRealContainedPath(base, workflow.filePath);
@@ -98,7 +94,9 @@ function resolveScriptPath(workflow: DynamicWorkflowConfig, cwd: string): string
98
94
  }
99
95
  }
100
96
  // Not contained in any allowed base — refuse (do NOT fall back to the raw path).
101
- throw new Error(`Dynamic workflow '${workflow.filePath}' is outside the allowed workflows directories (${allowedBases.join(", ")}). Refusing to load.`);
97
+ throw new Error(
98
+ `Dynamic workflow '${workflow.filePath}' is outside the allowed workflows directories (${allowedBases.join(", ")}). Refusing to load.`,
99
+ );
102
100
  }
103
101
 
104
102
  /**
@@ -121,7 +119,7 @@ async function loadWorkflowModule(scriptPath: string): Promise<DynamicWorkflowSc
121
119
  // lazily so this module stays importable in environments without jiti (type-only consumers).
122
120
  // Fix round-4: use createRequire(import.meta.url) so `require` works under the strip-types
123
121
  // loader fallback (Node ≥ 22.6) where bare `require` is not defined in ESM scope.
124
- // LAZY: defer dynamic import of node:module to its call site.
122
+ // LAZY: defer dynamic import of node:module to its call site.
125
123
  const { createRequire } = await import("node:module");
126
124
  const require = createRequire(import.meta.url);
127
125
  // eslint-disable-next-line @typescript-eslint/no-require-imports
@@ -144,7 +142,11 @@ export async function runDynamicWorkflow(input: RunDynamicWorkflowInput): Promis
144
142
  const eventsPath = manifest.eventsPath;
145
143
  const scriptPath = resolveScriptPath(workflow, manifest.cwd);
146
144
 
147
- appendEvent(eventsPath, { type: "dwf.started", runId: manifest.runId, data: { workflow: workflow.name, script: scriptPath } });
145
+ appendEvent(eventsPath, {
146
+ type: "dwf.started",
147
+ runId: manifest.runId,
148
+ data: { workflow: workflow.name, script: scriptPath },
149
+ });
148
150
 
149
151
  // round-18 P2-3: resume/checkpoint. Load any existing checkpoint for this run's stateRoot.
150
152
  // stateRoot is already <crewRoot>/state/runs/<runId>, so the checkpoint lands at
@@ -156,7 +158,11 @@ export async function runDynamicWorkflow(input: RunDynamicWorkflowInput): Promis
156
158
  appendEvent(eventsPath, {
157
159
  type: "dwf.resumed",
158
160
  runId: manifest.runId,
159
- data: { agentCount: resumedState.agentCount, phases: resumedState.phases, currentPhase: resumedState.currentPhase },
161
+ data: {
162
+ agentCount: resumedState.agentCount,
163
+ phases: resumedState.phases,
164
+ currentPhase: resumedState.currentPhase,
165
+ },
160
166
  });
161
167
  }
162
168
 
@@ -194,7 +200,11 @@ export async function runDynamicWorkflow(input: RunDynamicWorkflowInput): Promis
194
200
  let timeoutHandle: NodeJS.Timeout | undefined;
195
201
  const timeoutPromise = new Promise<never>((_, reject) => {
196
202
  timeoutHandle = setTimeout(() => {
197
- reject(new Error(`Dynamic workflow script timed out after ${SCRIPT_TIMEOUT_MS}ms. The script may have spawned a child process that did not exit. Check for spawn/exec calls without proper stdio handling.`));
203
+ reject(
204
+ new Error(
205
+ `Dynamic workflow script timed out after ${SCRIPT_TIMEOUT_MS}ms. The script may have spawned a child process that did not exit. Check for spawn/exec calls without proper stdio handling.`,
206
+ ),
207
+ );
198
208
  }, SCRIPT_TIMEOUT_MS);
199
209
  timeoutHandle.unref?.();
200
210
  });
@@ -205,13 +215,21 @@ export async function runDynamicWorkflow(input: RunDynamicWorkflowInput): Promis
205
215
  }
206
216
  } catch (error) {
207
217
  logInternalError("dynamic-workflow-runner.run", error, `runId=${manifest.runId}, workflow=${workflow.name}`);
208
- appendEvent(eventsPath, { type: "dwf.failed", runId: manifest.runId, data: { error: error instanceof Error ? error.message : String(error) } });
218
+ appendEvent(eventsPath, {
219
+ type: "dwf.failed",
220
+ runId: manifest.runId,
221
+ data: {
222
+ error: error instanceof Error ? error.message : String(error),
223
+ },
224
+ });
209
225
  // Re-throw so background-runner's error handling marks the run failed.
210
226
  throw error;
211
227
  }
212
228
 
213
229
  const final = getWorkflowFinalResult(ctx);
214
- const finalText = final ? readFinalArtifact(final.artifactPath) : `(dynamic workflow '${workflow.name}' completed without calling ctx.setResult())`;
230
+ const finalText = final
231
+ ? readFinalArtifact(final.artifactPath)
232
+ : `(dynamic workflow '${workflow.name}' completed without calling ctx.setResult())`;
215
233
 
216
234
  // round-12 P0-4: fail fast on unawaited Promise returns BEFORE we try to
217
235
  // write a 2 KB blob that contains a Promise reference. structuredClone on
@@ -240,7 +258,11 @@ export async function runDynamicWorkflow(input: RunDynamicWorkflowInput): Promis
240
258
  phaseState.currentPhase = undefined;
241
259
  }
242
260
 
243
- appendEvent(eventsPath, { type: "dwf.completed", runId: manifest.runId, data: { workflow: workflow.name, summaryArtifact: summary.path } });
261
+ appendEvent(eventsPath, {
262
+ type: "dwf.completed",
263
+ runId: manifest.runId,
264
+ data: { workflow: workflow.name, summaryArtifact: summary.path },
265
+ });
244
266
 
245
267
  // round-18 P2-3: the run completed cleanly — delete the checkpoint so a fresh re-run
246
268
  // (same runId) starts from scratch rather than resuming stale state.
@@ -1,6 +1,6 @@
1
- import { permissionForRole } from "./role-permission.ts";
2
1
  import type { CrewRuntimeConfig } from "../config/config.ts";
3
2
  import type { PolicyDecision, TeamRunManifest, TeamTaskState } from "../state/types.ts";
3
+ import { permissionForRole } from "./role-permission.ts";
4
4
 
5
5
  export type EffectivenessGuardMode = "off" | "warn" | "block" | "fail";
6
6
  export type WorkerExecutionState = "enabled" | "disabled/scaffold";
@@ -18,22 +18,30 @@ export interface RunEffectivenessSummary {
18
18
 
19
19
  export function taskHasObservableWorkerActivity(task: TeamTaskState): boolean {
20
20
  return Boolean(
21
- (task.agentProgress?.toolCount ?? 0) > 0
22
- || task.usage
23
- || task.transcriptArtifact
24
- || task.modelAttempts?.some((attempt) => attempt.success)
25
- || task.jsonEvents,
21
+ (task.agentProgress?.toolCount ?? 0) > 0 ||
22
+ task.usage ||
23
+ task.transcriptArtifact ||
24
+ task.modelAttempts?.some((attempt) => attempt.success) ||
25
+ task.jsonEvents,
26
26
  );
27
27
  }
28
28
 
29
- export function resolveEffectivenessGuardMode(runtimeConfig: CrewRuntimeConfig | undefined, manifest?: TeamRunManifest): EffectivenessGuardMode {
29
+ export function resolveEffectivenessGuardMode(
30
+ runtimeConfig: CrewRuntimeConfig | undefined,
31
+ manifest?: TeamRunManifest,
32
+ ): EffectivenessGuardMode {
30
33
  const configured = runtimeConfig?.effectivenessGuard;
31
34
  if (configured === "off" || configured === "warn" || configured === "block" || configured === "fail") return configured;
32
35
  if (manifest?.runtimeResolution?.safety === "explicit_dry_run") return "off";
33
36
  return "warn";
34
37
  }
35
38
 
36
- export function evaluateRunEffectiveness(input: { manifest?: TeamRunManifest; tasks: TeamTaskState[]; executeWorkers: boolean; runtimeConfig?: CrewRuntimeConfig }): RunEffectivenessSummary {
39
+ export function evaluateRunEffectiveness(input: {
40
+ manifest?: TeamRunManifest;
41
+ tasks: TeamTaskState[];
42
+ executeWorkers: boolean;
43
+ runtimeConfig?: CrewRuntimeConfig;
44
+ }): RunEffectivenessSummary {
37
45
  const completedTasks = input.tasks.filter((task) => task.status === "completed");
38
46
  const noObservedWorkTasks = completedTasks.filter((task) => !taskHasObservableWorkerActivity(task));
39
47
  const needsAttentionTasks = input.tasks.filter((task) => task.agentProgress?.activityState === "needs_attention");
@@ -17,7 +17,7 @@ export abstract class CrewError extends Error {
17
17
  abstract readonly code: string;
18
18
 
19
19
  /** Returns the class name. Use `instanceof` for discrimination. */
20
- toString(): string {
20
+ toString(): string {
21
21
  return `[${this.constructor.name}] ${this.message}`;
22
22
  }
23
23
  }
@@ -123,11 +123,11 @@ export class CrewSessionError extends CrewError {
123
123
  * Used by RunTracker and health monitoring for outcome classification.
124
124
  */
125
125
  export type CrewRunOutcome =
126
- | "ok" // Completed successfully
126
+ | "ok" // Completed successfully
127
127
  | "cancelled" // Explicitly cancelled by user or API
128
128
  | "deadletter" // Agent encountered unrecoverable error
129
- | "failed" // Workflow step failed (gate error, etc.)
130
- | "timeout" // Exceeded max duration
129
+ | "failed" // Workflow step failed (gate error, etc.)
130
+ | "timeout" // Exceeded max duration
131
131
  | "aborted"; // Operator interrupt (Esc, SIGINT)
132
132
 
133
133
  /**
@@ -150,9 +150,7 @@ export function classifyError(error: unknown): CrewRunOutcome {
150
150
  * (cancelled, aborted, or timed out) vs a genuine failure.
151
151
  */
152
152
  export function isInterruptError(error: unknown): boolean {
153
- return error instanceof CrewCancelledError
154
- || error instanceof CrewAbortError
155
- || error instanceof CrewTimeoutError;
153
+ return error instanceof CrewCancelledError || error instanceof CrewAbortError || error instanceof CrewTimeoutError;
156
154
  }
157
155
 
158
156
  /**
@@ -160,7 +158,5 @@ export function isInterruptError(error: unknown): boolean {
160
158
  * rather than workflow logic or user action.
161
159
  */
162
160
  export function isAgentError(error: unknown): boolean {
163
- return error instanceof CrewDeadletterError
164
- || error instanceof CrewTurnLimitError
165
- || error instanceof CrewSessionError;
166
- }
161
+ return error instanceof CrewDeadletterError || error instanceof CrewTurnLimitError || error instanceof CrewSessionError;
162
+ }
@@ -1,5 +1,5 @@
1
1
  import { runEventBus } from "../ui/run-event-bus.ts";
2
- import { subprocessToolRegistry, type SubprocessToolEvent } from "./subprocess-tool-registry.ts";
2
+ import { type SubprocessToolEvent, subprocessToolRegistry } from "./subprocess-tool-registry.ts";
3
3
 
4
4
  export interface StreamBridgeEvent {
5
5
  runId: string;
@@ -15,10 +15,16 @@ export interface StreamBridgeEvent {
15
15
 
16
16
  const activeBridges = new Map<string, (event: StreamBridgeEvent) => void>();
17
17
 
18
- export function registerStreamBridge(runId: string): { handler: (event: StreamBridgeEvent) => void; dispose: () => void } {
18
+ export function registerStreamBridge(runId: string): {
19
+ handler: (event: StreamBridgeEvent) => void;
20
+ dispose: () => void;
21
+ } {
19
22
  const existing = activeBridges.get(runId);
20
23
  if (existing) {
21
- return { handler: existing, dispose: () => unregisterStreamBridge(runId) };
24
+ return {
25
+ handler: existing,
26
+ dispose: () => unregisterStreamBridge(runId),
27
+ };
22
28
  }
23
29
 
24
30
  const handler = (event: StreamBridgeEvent) => {