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
@@ -39,13 +39,7 @@ export interface BatchSnapshot {
39
39
  notified: boolean;
40
40
  }
41
41
 
42
- const TERMINAL_STATUSES = new Set([
43
- "completed",
44
- "failed",
45
- "cancelled",
46
- "error",
47
- "stopped",
48
- ]);
42
+ const TERMINAL_STATUSES = new Set(["completed", "failed", "cancelled", "error", "stopped"]);
49
43
 
50
44
  export function isTerminalStatus(status: string): boolean {
51
45
  return TERMINAL_STATUSES.has(status);
@@ -65,7 +59,11 @@ export class BatchBarrier {
65
59
  register(batchId: string, agentId: string, meta?: { description?: string; type?: string }): void {
66
60
  let batch = this.batches.get(batchId);
67
61
  if (!batch) {
68
- batch = { members: new Map(), terminal: new Map(), notified: false };
62
+ batch = {
63
+ members: new Map(),
64
+ terminal: new Map(),
65
+ notified: false,
66
+ };
69
67
  this.batches.set(batchId, batch);
70
68
  }
71
69
  if (!batch.members.has(agentId)) {
@@ -87,7 +85,11 @@ export class BatchBarrier {
87
85
  markTerminal(batchId: string, member: BatchMember): BatchSnapshot {
88
86
  let batch = this.batches.get(batchId);
89
87
  if (!batch) {
90
- batch = { members: new Map(), terminal: new Map(), notified: false };
88
+ batch = {
89
+ members: new Map(),
90
+ terminal: new Map(),
91
+ notified: false,
92
+ };
91
93
  this.batches.set(batchId, batch);
92
94
  }
93
95
  // Ensure the member is known (auto-register for the defensive case).
@@ -97,11 +99,13 @@ export class BatchBarrier {
97
99
  if (isTerminalStatus(member.status)) {
98
100
  batch.terminal.set(member.id, { ...member });
99
101
  const existing = batch.members.get(member.id);
100
- if (existing) batch.members.set(member.id, { ...existing, status: member.status });
102
+ if (existing)
103
+ batch.members.set(member.id, {
104
+ ...existing,
105
+ status: member.status,
106
+ });
101
107
  }
102
- const allDone =
103
- batch.members.size > 0 &&
104
- [...batch.members.keys()].every((id) => batch.terminal.has(id));
108
+ const allDone = batch.members.size > 0 && [...batch.members.keys()].every((id) => batch.terminal.has(id));
105
109
  return {
106
110
  batchId,
107
111
  members: [...batch.members.values()],
@@ -130,9 +134,7 @@ export class BatchBarrier {
130
134
  batchId,
131
135
  members: [...batch.members.values()],
132
136
  terminal: [...batch.terminal.values()],
133
- allDone:
134
- batch.members.size > 0 &&
135
- [...batch.members.keys()].every((id) => batch.terminal.has(id)),
137
+ allDone: batch.members.size > 0 && [...batch.members.keys()].every((id) => batch.terminal.has(id)),
136
138
  notified: batch.notified,
137
139
  };
138
140
  }
@@ -1,4 +1,4 @@
1
- import { CrewCancellationError, type CancellationReason, cancellationReasonFromUnknown } from "./cancellation.ts";
1
+ import { type CancellationReason, CrewCancellationError, cancellationReasonFromUnknown } from "./cancellation.ts";
2
2
 
3
3
  export interface CancellationTokenState {
4
4
  aborted: boolean;
@@ -28,11 +28,21 @@ export class CancellationToken {
28
28
  else if (options.signal) options.signal.addEventListener("abort", () => this.abort(options.signal?.reason), { once: true });
29
29
  }
30
30
 
31
- get signal(): AbortSignal { return this.#controller.signal; }
32
- get aborted(): boolean { return this.#controller.signal.aborted; }
33
- get reason(): CancellationReason | undefined { return this.#reason; }
34
- get lastHeartbeatAt(): string | undefined { return this.#lastHeartbeatAt; }
35
- get lastHeartbeatStage(): string | undefined { return this.#lastHeartbeatStage; }
31
+ get signal(): AbortSignal {
32
+ return this.#controller.signal;
33
+ }
34
+ get aborted(): boolean {
35
+ return this.#controller.signal.aborted;
36
+ }
37
+ get reason(): CancellationReason | undefined {
38
+ return this.#reason;
39
+ }
40
+ get lastHeartbeatAt(): string | undefined {
41
+ return this.#lastHeartbeatAt;
42
+ }
43
+ get lastHeartbeatStage(): string | undefined {
44
+ return this.#lastHeartbeatStage;
45
+ }
36
46
 
37
47
  heartbeat(stage?: string): CancellationTokenState {
38
48
  this.throwIfCancelled();
@@ -1,6 +1,13 @@
1
1
  import type { OperationTerminalEvidence } from "../state/types.ts";
2
2
 
3
- export type CancellationReasonCode = "caller_cancelled" | "leader_interrupted" | "provider_timeout" | "worker_timeout" | "tool_timeout" | "shutdown" | "unknown";
3
+ export type CancellationReasonCode =
4
+ | "caller_cancelled"
5
+ | "leader_interrupted"
6
+ | "provider_timeout"
7
+ | "worker_timeout"
8
+ | "tool_timeout"
9
+ | "shutdown"
10
+ | "unknown";
4
11
 
5
12
  export interface CancellationReason {
6
13
  code: CancellationReasonCode;
@@ -13,10 +20,24 @@ export function buildSyntheticTerminalEvidence(
13
20
  reason: CancellationReason,
14
21
  startedAt?: string,
15
22
  ): OperationTerminalEvidence {
16
- return { operation, status: "cancelled", startedAt, finishedAt: new Date().toISOString(), reason };
23
+ return {
24
+ operation,
25
+ status: "cancelled",
26
+ startedAt,
27
+ finishedAt: new Date().toISOString(),
28
+ reason,
29
+ };
17
30
  }
18
31
 
19
- const KNOWN_CODES: ReadonlySet<string> = new Set(["caller_cancelled", "leader_interrupted", "provider_timeout", "worker_timeout", "tool_timeout", "shutdown", "unknown"]);
32
+ const KNOWN_CODES: ReadonlySet<string> = new Set([
33
+ "caller_cancelled",
34
+ "leader_interrupted",
35
+ "provider_timeout",
36
+ "worker_timeout",
37
+ "tool_timeout",
38
+ "shutdown",
39
+ "unknown",
40
+ ]);
20
41
 
21
42
  export class CrewCancellationError extends Error {
22
43
  readonly reason: CancellationReason;
@@ -30,18 +51,35 @@ export class CrewCancellationError extends Error {
30
51
 
31
52
  function reasonFromString(value: string): CancellationReason {
32
53
  const trimmed = value.trim();
33
- if (KNOWN_CODES.has(trimmed)) return { code: trimmed as CancellationReasonCode, message: `Cancelled: ${trimmed}` };
34
- return { code: "caller_cancelled", message: trimmed || "Cancelled by caller." };
54
+ if (KNOWN_CODES.has(trimmed))
55
+ return {
56
+ code: trimmed as CancellationReasonCode,
57
+ message: `Cancelled: ${trimmed}`,
58
+ };
59
+ return {
60
+ code: "caller_cancelled",
61
+ message: trimmed || "Cancelled by caller.",
62
+ };
35
63
  }
36
64
 
37
65
  export function cancellationReasonFromUnknown(value: unknown): CancellationReason {
38
66
  if (value instanceof CrewCancellationError) return value.reason;
39
- if (value instanceof Error) return { code: "caller_cancelled", message: value.message || "Cancelled by caller.", cause: value };
67
+ if (value instanceof Error)
68
+ return {
69
+ code: "caller_cancelled",
70
+ message: value.message || "Cancelled by caller.",
71
+ cause: value,
72
+ };
40
73
  if (typeof value === "string") return reasonFromString(value);
41
74
  if (value && typeof value === "object" && !Array.isArray(value)) {
42
- const record = value as { code?: unknown; reason?: unknown; message?: unknown; cause?: unknown };
75
+ const record = value as {
76
+ code?: unknown;
77
+ reason?: unknown;
78
+ message?: unknown;
79
+ cause?: unknown;
80
+ };
43
81
  const rawCode = typeof record.code === "string" ? record.code : typeof record.reason === "string" ? record.reason : undefined;
44
- const code = rawCode && KNOWN_CODES.has(rawCode) ? rawCode as CancellationReasonCode : "caller_cancelled";
82
+ const code = rawCode && KNOWN_CODES.has(rawCode) ? (rawCode as CancellationReasonCode) : "caller_cancelled";
45
83
  const message = typeof record.message === "string" && record.message.trim() ? record.message.trim() : `Cancelled: ${code}`;
46
84
  return { code, message, cause: record.cause ?? value };
47
85
  }
@@ -1,10 +1,10 @@
1
1
  import type { AgentConfig, ResourceSource } from "../agents/agent-config.ts";
2
2
  import { discoverAgents } from "../agents/discover-agents.ts";
3
- import { discoverTeams } from "../teams/discover-teams.ts";
4
- import { discoverWorkflows } from "../workflows/discover-workflows.ts";
3
+ import type { PiTeamsConfig } from "../config/config.ts";
5
4
  import { discoverSkills, getLastDiscoveryDiagnostics } from "../skills/discover-skills.ts";
6
5
  import type { SkillValidationError } from "../skills/validate.ts";
7
- import type { PiTeamsConfig } from "../config/config.ts";
6
+ import { discoverTeams } from "../teams/discover-teams.ts";
7
+ import { discoverWorkflows } from "../workflows/discover-workflows.ts";
8
8
 
9
9
  export type CapabilityKind = "team" | "workflow" | "agent" | "skill" | "tool" | "runtime";
10
10
  export type CapabilitySource = "builtin" | "project" | "user" | "package" | "git";
@@ -105,7 +105,9 @@ export function buildCapabilityInventory(cwd: string, config?: PiTeamsConfig): C
105
105
  ];
106
106
 
107
107
  // Mark shadowed resources: project/user items with same kind:name as a builtin
108
- const builtinNames = new Set(items.filter((item) => item.source === "builtin" || item.source === "package").map((item) => `${item.kind}:${item.name}`));
108
+ const builtinNames = new Set(
109
+ items.filter((item) => item.source === "builtin" || item.source === "package").map((item) => `${item.kind}:${item.name}`),
110
+ );
109
111
  for (const item of items) {
110
112
  if (item.source !== "builtin" && item.source !== "package" && builtinNames.has(`${item.kind}:${item.name}`)) {
111
113
  item.state = "shadowed";
@@ -48,19 +48,39 @@ function tokenize(input: string): Token[] {
48
48
 
49
49
  while (i < input.length) {
50
50
  // Skip whitespace
51
- if (/\s/.test(input[i]!)) { i++; continue; }
51
+ if (/\s/.test(input[i]!)) {
52
+ i++;
53
+ continue;
54
+ }
52
55
 
53
56
  // Arrow ->
54
57
  if (input[i] === "-" && input[i + 1] === ">") {
55
58
  tokens.push({ type: "ARROW", value: "->" });
56
- i += 2; continue;
59
+ i += 2;
60
+ continue;
57
61
  }
58
62
 
59
63
  // Punctuation
60
- if (input[i] === "(") { tokens.push({ type: "LPAREN", value: "(" }); i++; continue; }
61
- if (input[i] === ")") { tokens.push({ type: "RPAREN", value: ")" }); i++; continue; }
62
- if (input[i] === ",") { tokens.push({ type: "COMMA", value: "," }); i++; continue; }
63
- if (input[i] === ":") { tokens.push({ type: "COLON", value: ":" }); i++; continue; }
64
+ if (input[i] === "(") {
65
+ tokens.push({ type: "LPAREN", value: "(" });
66
+ i++;
67
+ continue;
68
+ }
69
+ if (input[i] === ")") {
70
+ tokens.push({ type: "RPAREN", value: ")" });
71
+ i++;
72
+ continue;
73
+ }
74
+ if (input[i] === ",") {
75
+ tokens.push({ type: "COMMA", value: "," });
76
+ i++;
77
+ continue;
78
+ }
79
+ if (input[i] === ":") {
80
+ tokens.push({ type: "COLON", value: ":" });
81
+ i++;
82
+ continue;
83
+ }
64
84
 
65
85
  // Quoted argument
66
86
  if (input[i] === '"' || input[i] === "'") {
@@ -68,8 +88,12 @@ function tokenize(input: string): Token[] {
68
88
  let str = "";
69
89
  i++; // skip opening quote
70
90
  while (i < input.length && input[i] !== quote) {
71
- if (input[i] === "\\" && i + 1 < input.length) { i++; str += input[i]; }
72
- else { str += input[i]!; }
91
+ if (input[i] === "\\" && i + 1 < input.length) {
92
+ i++;
93
+ str += input[i];
94
+ } else {
95
+ str += input[i]!;
96
+ }
73
97
  i++;
74
98
  }
75
99
  if (i >= input.length) throw new Error("Unclosed quoted string in chain DSL");
@@ -82,7 +106,10 @@ function tokenize(input: string): Token[] {
82
106
  if (input[i] === "-" && input[i + 1] === "-") {
83
107
  let flag = "";
84
108
  i += 2;
85
- while (i < input.length && /[a-zA-Z0-9_-]/.test(input[i]!)) { flag += input[i]; i++; }
109
+ while (i < input.length && /[a-zA-Z0-9_-]/.test(input[i]!)) {
110
+ flag += input[i];
111
+ i++;
112
+ }
86
113
  tokens.push({ type: "FLAG", value: flag });
87
114
  continue;
88
115
  }
@@ -90,7 +117,10 @@ function tokenize(input: string): Token[] {
90
117
  // Number
91
118
  if (/[0-9]/.test(input[i]!)) {
92
119
  let num = "";
93
- while (i < input.length && /[0-9]/.test(input[i]!)) { num += input[i]; i++; }
120
+ while (i < input.length && /[0-9]/.test(input[i]!)) {
121
+ num += input[i];
122
+ i++;
123
+ }
94
124
  tokens.push({ type: "NUMBER", value: num });
95
125
  continue;
96
126
  }
@@ -98,7 +128,10 @@ function tokenize(input: string): Token[] {
98
128
  // Name
99
129
  if (/[a-zA-Z_]/.test(input[i]!)) {
100
130
  let name = "";
101
- while (i < input.length && /[a-zA-Z0-9_.-]/.test(input[i]!)) { name += input[i]; i++; }
131
+ while (i < input.length && /[a-zA-Z0-9_.-]/.test(input[i]!)) {
132
+ name += input[i];
133
+ i++;
134
+ }
102
135
  tokens.push({ type: "NAME", value: name });
103
136
  continue;
104
137
  }
@@ -1,18 +1,18 @@
1
1
  /**
2
2
  * ChainRunner - Execute sequential chains with `->` syntax support.
3
- *
3
+ *
4
4
  * Based on pi-boomerang's parseChain pattern:
5
5
  * - Parses "teamA -> teamB -> teamC" syntax
6
6
  * - Supports per-step overrides for model, skill, thinking
7
7
  * - Accumulates handoffs between steps
8
8
  * - Executes steps sequentially with context passing
9
- *
9
+ *
10
10
  * @see docs/pi-boomerang-integration-plan.md
11
11
  */
12
12
 
13
- import type { HandoffSummary, HandoffManager, TaskPacket, TaskResult } from "./handoff-manager.ts";
14
- import { parseChainDSL } from "./chain-parser.ts";
15
13
  import type { ChainStep as DSLChainStep } from "./chain-parser.ts";
14
+ import { parseChainDSL } from "./chain-parser.ts";
15
+ import type { HandoffManager, HandoffSummary, TaskPacket, TaskResult } from "./handoff-manager.ts";
16
16
 
17
17
  /**
18
18
  * Single step in a chain.
@@ -109,32 +109,29 @@ export class ChainRunner {
109
109
  private taskRunner: ChainTaskRunner;
110
110
  private handoffManager: HandoffManager;
111
111
 
112
- constructor(
113
- taskRunner: ChainTaskRunner,
114
- handoffManager: HandoffManager,
115
- ) {
112
+ constructor(taskRunner: ChainTaskRunner, handoffManager: HandoffManager) {
116
113
  this.taskRunner = taskRunner;
117
114
  this.handoffManager = handoffManager;
118
115
  }
119
116
 
120
117
  /**
121
118
  * Parse chain syntax: step1 -> step2 -> step3
122
- *
119
+ *
123
120
  * Supports multiple syntaxes:
124
121
  * - Team reference: @teamName
125
122
  * - Workflow reference: workflow:name
126
123
  * - Template reference: template:name
127
124
  * - Inline goal: "goal description"
128
- *
125
+ *
129
126
  * @example
130
127
  * parseChain("@research -> @implement -> @review")
131
128
  * parseChain('"Research AI trends" -> "Analyze findings"')
132
129
  * parseChain("@step1 --model claude-opus-3 -> @step2")
133
- *
130
+ *
134
131
  * Also supports DSL syntax from chain-parser for advanced constructs:
135
132
  * parseChain("step1 -> parallel(step2, step3) -> step4")
136
133
  * parseChain("step1:3 -> step2 --with-context -> step3")
137
- *
134
+ *
138
135
  * @param chainString - The chain string to parse
139
136
  * @returns Parsed chain specification
140
137
  */
@@ -150,7 +147,7 @@ export class ChainRunner {
150
147
  }
151
148
  }
152
149
 
153
- const stepStrings = chainString.split("->").map(s => s.trim());
150
+ const stepStrings = chainString.split("->").map((s) => s.trim());
154
151
 
155
152
  const steps: ChainStep[] = stepStrings.map((step, index) => {
156
153
  return this.parseStep(step, index);
@@ -174,17 +171,13 @@ export class ChainRunner {
174
171
  /**
175
172
  * Execute chain sequentially.
176
173
  * Each step receives handoff from previous step.
177
- *
174
+ *
178
175
  * @param spec - Parsed chain specification
179
176
  * @param initialContext - Initial context for the chain
180
177
  * @param eventsPath - Optional event log path for events
181
178
  * @returns Final chain result
182
179
  */
183
- async runChain(
184
- spec: ChainSpec,
185
- initialContext: Record<string, unknown> = {},
186
- eventsPath?: string
187
- ): Promise<ChainResult> {
180
+ async runChain(spec: ChainSpec, initialContext: Record<string, unknown> = {}, eventsPath?: string): Promise<ChainResult> {
188
181
  const stepResults: ChainStepResult[] = [];
189
182
  let accumulatedContext = { ...initialContext };
190
183
  const startTime = Date.now();
@@ -200,10 +193,7 @@ export class ChainRunner {
200
193
  const effectiveConfig = this.getEffectiveConfig(step, spec);
201
194
 
202
195
  // Enrich context with previous handoffs
203
- const stepContext = this.enrichContextFromHandoffs(
204
- accumulatedContext,
205
- stepResults
206
- );
196
+ const stepContext = this.enrichContextFromHandoffs(accumulatedContext, stepResults);
207
197
 
208
198
  // Execute step
209
199
  const result = await this.executeStep(effectiveConfig, stepContext);
@@ -214,10 +204,7 @@ export class ChainRunner {
214
204
  }
215
205
 
216
206
  // Generate handoff for next step
217
- const handoff = await this.handoffManager.generateSummary(
218
- this.createMinimalPacket(step, i),
219
- result
220
- );
207
+ const handoff = await this.handoffManager.generateSummary(this.createMinimalPacket(step, i), result);
221
208
 
222
209
  stepResults.push({
223
210
  step: i + 1,
@@ -228,7 +215,9 @@ export class ChainRunner {
228
215
  duration: Date.now() - stepStart,
229
216
  });
230
217
 
231
- if (handoff !== null) { allHandoffs.push(handoff); }
218
+ if (handoff !== null) {
219
+ allHandoffs.push(handoff);
220
+ }
232
221
 
233
222
  // Update accumulated context on success
234
223
  if (result.outcome === "success") {
@@ -246,7 +235,7 @@ export class ChainRunner {
246
235
 
247
236
  // Emit progress event if eventsPath provided
248
237
  if (eventsPath) {
249
- // LAZY: defer dynamic import of ../state/event-log.ts to its call site.
238
+ // LAZY: defer dynamic import of ../state/event-log.ts to its call site.
250
239
  const { appendEventAsync } = await import("../state/event-log.ts");
251
240
  await appendEventAsync(eventsPath, {
252
241
  type: "chain.step_completed",
@@ -260,7 +249,6 @@ export class ChainRunner {
260
249
  },
261
250
  });
262
251
  }
263
-
264
252
  } catch (error) {
265
253
  const errorMessage = error instanceof Error ? error.message : String(error);
266
254
 
@@ -282,7 +270,7 @@ export class ChainRunner {
282
270
  return {
283
271
  steps: stepResults,
284
272
  totalDuration: Date.now() - startTime,
285
- success: stepResults.every(s => s.outcome !== "failure"),
273
+ success: stepResults.every((s) => s.outcome !== "failure"),
286
274
  totalTokens: totalTokens > 0 ? totalTokens : undefined,
287
275
  totalHandoffs: allHandoffs,
288
276
  };
@@ -306,9 +294,7 @@ export class ChainRunner {
306
294
  const inlineMatch = step.match(/"([^"]{1,10000})"/);
307
295
 
308
296
  const nameParts = step.split(/\s+/);
309
- const name = (nameParts[0] && nameParts[0].length > 0 && nameParts[0].length <= 100)
310
- ? nameParts[0]
311
- : `step-${index}`;
297
+ const name = nameParts[0] && nameParts[0].length > 0 && nameParts[0].length <= 100 ? nameParts[0] : `step-${index}`;
312
298
 
313
299
  const parsed: ChainStep = {
314
300
  name,
@@ -366,9 +352,7 @@ export class ChainRunner {
366
352
  * DSL features: parallel(...), :loopCount, --with-context flag
367
353
  */
368
354
  private hasDSLConstructs(chainString: string): boolean {
369
- return /\bparallel\s*\(/.test(chainString) ||
370
- /\w+:\d+\b/.test(chainString) ||
371
- /--with-context/.test(chainString);
355
+ return /\bparallel\s*\(/.test(chainString) || /\w+:\d+\b/.test(chainString) || /--with-context/.test(chainString);
372
356
  }
373
357
 
374
358
  /**
@@ -381,13 +365,22 @@ export class ChainRunner {
381
365
  return {
382
366
  name: dslStep.name,
383
367
  context: {
384
- parallel: dslStep.parallel.map(p => ({ name: p.name, loopCount: p.loopCount, withContext: p.withContext, args: p.args })),
368
+ parallel: dslStep.parallel.map((p) => ({
369
+ name: p.name,
370
+ loopCount: p.loopCount,
371
+ withContext: p.withContext,
372
+ args: p.args,
373
+ })),
385
374
  },
386
375
  loopCount: dslStep.loopCount,
387
376
  };
388
377
  }
389
378
  const step: ChainStep = { name: dslStep.name };
390
- if (dslStep.loopCount) step.context = { ...step.context, loopCount: dslStep.loopCount };
379
+ if (dslStep.loopCount)
380
+ step.context = {
381
+ ...step.context,
382
+ loopCount: dslStep.loopCount,
383
+ };
391
384
  if (dslStep.withContext) step.context = { ...step.context, withContext: true };
392
385
  if (dslStep.args && dslStep.args.length > 0) step.context = { ...step.context, args: dslStep.args };
393
386
  return step;
@@ -399,14 +392,20 @@ export class ChainRunner {
399
392
  const globalThinking = this.extractGlobalFlag(chainString, "global-thinking") as "fast" | "standard" | "deep" | undefined;
400
393
  const continueOnError = this.extractGlobalFlag(chainString, "continue-on-error") === "true";
401
394
 
402
- return { steps, globalModel, globalSkill, globalThinking, continueOnError };
395
+ return {
396
+ steps,
397
+ globalModel,
398
+ globalSkill,
399
+ globalThinking,
400
+ continueOnError,
401
+ };
403
402
  }
404
403
 
405
404
  /**
406
405
  * Sanitize identifier to prevent injection.
407
406
  */
408
407
  private sanitizeIdentifier(value: string): string {
409
- return value.replace(/[^a-zA-Z0-9_]/g, '_').substring(0, 100);
408
+ return value.replace(/[^a-zA-Z0-9_]/g, "_").substring(0, 100);
410
409
  }
411
410
 
412
411
  /**
@@ -414,7 +413,7 @@ export class ChainRunner {
414
413
  */
415
414
  private sanitizeInlineGoal(value: string): string {
416
415
  // Remove control characters and limit length
417
- return value.replace(/[\x00-\x1F\x7F]/g, '').substring(0, 10000);
416
+ return value.replace(/[\x00-\x1F\x7F]/g, "").substring(0, 10000);
418
417
  }
419
418
 
420
419
  /**
@@ -444,7 +443,7 @@ export class ChainRunner {
444
443
  */
445
444
  private extractFlag(input: string, flag: string): string | undefined {
446
445
  // Escape regex special characters in flag name to prevent injection
447
- const escapedFlag = flag.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
446
+ const escapedFlag = flag.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
448
447
  const match = input.match(new RegExp(`--${escapedFlag}\\s+(\\S+)`));
449
448
  return match?.[1];
450
449
  }
@@ -456,13 +455,13 @@ export class ChainRunner {
456
455
  */
457
456
  private extractGlobalFlag(input: string, flag: string): string | undefined {
458
457
  // Escape regex special characters in flag name to prevent injection
459
- const escapedFlag = flag.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
460
- const patternEq = '--' + escapedFlag + '=\\s*(\\S+)';
461
- const match = input.match(new RegExp(patternEq, 'i'));
458
+ const escapedFlag = flag.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
459
+ const patternEq = "--" + escapedFlag + "=\\s*(\\S+)";
460
+ const match = input.match(new RegExp(patternEq, "i"));
462
461
  if (match) return match[1];
463
462
 
464
- const patternNoEq = '--' + escapedFlag + '\\s+(\\S+)';
465
- const matchNoEq = input.match(new RegExp(patternNoEq, 'i'));
463
+ const patternNoEq = "--" + escapedFlag + "\\s+(\\S+)";
464
+ const matchNoEq = input.match(new RegExp(patternNoEq, "i"));
466
465
  if (matchNoEq) return matchNoEq[1];
467
466
 
468
467
  return undefined;
@@ -484,13 +483,8 @@ export class ChainRunner {
484
483
  * Enrich context with previous handoffs.
485
484
  * Limits history size to prevent memory leaks.
486
485
  */
487
- private enrichContextFromHandoffs(
488
- context: Record<string, unknown>,
489
- previousResults: ChainStepResult[]
490
- ): Record<string, unknown> {
491
- const handoffs = previousResults
492
- .filter(r => r.handoff)
493
- .map(r => r.handoff!);
486
+ private enrichContextFromHandoffs(context: Record<string, unknown>, previousResults: ChainStepResult[]): Record<string, unknown> {
487
+ const handoffs = previousResults.filter((r) => r.handoff).map((r) => r.handoff!);
494
488
 
495
489
  if (handoffs.length === 0) {
496
490
  return context;
@@ -504,24 +498,28 @@ export class ChainRunner {
504
498
  let limitedHandoffs = handoffs;
505
499
  if (handoffs.length > ChainRunner.MAX_CHAIN_HISTORY_SIZE) {
506
500
  const dropped = handoffs.length - ChainRunner.MAX_CHAIN_HISTORY_SIZE;
507
- notes.push(`[chain history limited to last ${ChainRunner.MAX_CHAIN_HISTORY_SIZE} entries; ${dropped} older entr${dropped === 1 ? "y" : "ies"} omitted]`);
501
+ notes.push(
502
+ `[chain history limited to last ${ChainRunner.MAX_CHAIN_HISTORY_SIZE} entries; ${dropped} older entr${dropped === 1 ? "y" : "ies"} omitted]`,
503
+ );
508
504
  limitedHandoffs = handoffs.slice(-ChainRunner.MAX_CHAIN_HISTORY_SIZE);
509
505
  }
510
506
 
511
507
  // Limit per-entry size to prevent memory issues from large artifacts.
512
- const filteredHandoffs = limitedHandoffs.filter(h => {
508
+ const filteredHandoffs = limitedHandoffs.filter((h) => {
513
509
  const size = JSON.stringify(h).length;
514
510
  return size <= ChainRunner.MAX_HANDOFF_ENTRY_SIZE;
515
511
  });
516
512
  const oversizedDropped = limitedHandoffs.length - filteredHandoffs.length;
517
513
  if (oversizedDropped > 0) {
518
- notes.push(`[${oversizedDropped} handoff entr${oversizedDropped === 1 ? "y" : "ies"} omitted (> ${ChainRunner.MAX_HANDOFF_ENTRY_SIZE} bytes each)]`);
514
+ notes.push(
515
+ `[${oversizedDropped} handoff entr${oversizedDropped === 1 ? "y" : "ies"} omitted (> ${ChainRunner.MAX_HANDOFF_ENTRY_SIZE} bytes each)]`,
516
+ );
519
517
  }
520
518
 
521
519
  // Track array-cap drops so capped lists do not vanish silently. Each field
522
520
  // over its cap records the full count so a reader knows data was elided.
523
521
  const arrayCapNotes: string[] = [];
524
- const mapped = filteredHandoffs.map(h => {
522
+ const mapped = filteredHandoffs.map((h) => {
525
523
  const over: string[] = [];
526
524
  if (h.filesCreated && h.filesCreated.length > 50) over.push(`filesCreated=${h.filesCreated.length}`);
527
525
  if (h.filesModified && h.filesModified.length > 50) over.push(`filesModified=${h.filesModified.length}`);
@@ -550,10 +548,7 @@ export class ChainRunner {
550
548
  /**
551
549
  * Execute a single step.
552
550
  */
553
- private async executeStep(
554
- config: ChainStep,
555
- context: Record<string, unknown>
556
- ): Promise<TaskResult> {
551
+ private async executeStep(config: ChainStep, context: Record<string, unknown>): Promise<TaskResult> {
557
552
  // Pass step config (team/workflow/model) into the packet context so the
558
553
  // concrete ChainTaskRunner can resolve which team/workflow to run. Without
559
554
  // this, a step parsed to a @teamName reference would lose its team because
@@ -592,10 +587,7 @@ export class ChainRunner {
592
587
  /**
593
588
  * Create a ChainRunner with default dependencies.
594
589
  */
595
- export function createChainRunner(
596
- taskRunner: ChainTaskRunner,
597
- handoffManager: HandoffManager
598
- ): ChainRunner {
590
+ export function createChainRunner(taskRunner: ChainTaskRunner, handoffManager: HandoffManager): ChainRunner {
599
591
  return new ChainRunner(taskRunner, handoffManager);
600
592
  }
601
593
 
@@ -604,8 +596,10 @@ export function createChainRunner(
604
596
  */
605
597
  export function parseChainString(chainString: string): ChainSpec {
606
598
  const runner = new ChainRunner(
607
- { runTask: () => Promise.reject(new Error("Not initialized")) } as ChainTaskRunner,
608
- {} as HandoffManager
599
+ {
600
+ runTask: () => Promise.reject(new Error("Not initialized")),
601
+ } as ChainTaskRunner,
602
+ {} as HandoffManager,
609
603
  );
610
604
  return runner.parseChain(chainString);
611
605
  }