pi-crew 0.9.16 → 0.9.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (435) hide show
  1. package/CHANGELOG.md +130 -0
  2. package/README.md +19 -0
  3. package/dist/build-meta.json +21784 -0
  4. package/dist/index.mjs +83169 -0
  5. package/dist/index.mjs.map +7 -0
  6. package/docs/A +358 -0
  7. package/docs/M-A +357 -0
  8. package/docs/REVIEW-FINDINGS-2026-06 +357 -0
  9. package/docs/Y +357 -0
  10. package/docs/a +357 -0
  11. package/docs/aA +358 -0
  12. package/docs/archive/README.md +91 -0
  13. package/docs/migration/atomic-write-v2-migration.md +297 -0
  14. package/docs/patterns/command-agent-skill.md +1 -1
  15. package/docs/perf/performance-review-2026-07.md +287 -0
  16. package/docs/skills/REFERENCE.md +0 -17
  17. package/docs//303/242mmaAAA/303/242 +357 -0
  18. package/index.bundle.ts +25 -0
  19. package/index.ts +95 -4
  20. package/package.json +15 -4
  21. package/skills/iterative-audit/SKILL.md +0 -1
  22. package/skills/widget-rendering/SKILL.md +17 -0
  23. package/src/adapters/claude-adapter.ts +1 -3
  24. package/src/adapters/export-util.ts +16 -16
  25. package/src/adapters/index.ts +5 -5
  26. package/src/agents/agent-config.ts +20 -14
  27. package/src/agents/agent-serializer.ts +1 -1
  28. package/src/agents/discover-agents.ts +83 -39
  29. package/src/benchmark/benchmark-runner.ts +51 -51
  30. package/src/benchmark/feedback-loop.ts +1 -1
  31. package/src/config/config.ts +303 -591
  32. package/src/config/defaults.ts +28 -2
  33. package/src/config/drift-detector.ts +11 -14
  34. package/src/config/markers.ts +201 -203
  35. package/src/config/resilient-parser.ts +14 -6
  36. package/src/config/role-tools.ts +3 -3
  37. package/src/config/suggestions.ts +5 -12
  38. package/src/config/types.ts +9 -25
  39. package/src/errors.ts +151 -157
  40. package/src/extension/action-suggestions.ts +54 -9
  41. package/src/extension/async-notifier.ts +43 -13
  42. package/src/extension/autonomous-policy.ts +77 -37
  43. package/src/extension/command-completions.ts +9 -8
  44. package/src/extension/context-status-injection.ts +14 -12
  45. package/src/extension/crew-autocomplete.ts +8 -16
  46. package/src/extension/crew-cleanup.ts +2 -1
  47. package/src/extension/crew-shortcuts.ts +9 -6
  48. package/src/extension/cross-extension-rpc.ts +136 -42
  49. package/src/extension/help.ts +1 -1
  50. package/src/extension/import-index.ts +10 -5
  51. package/src/extension/knowledge-injection.ts +88 -15
  52. package/src/extension/management.ts +89 -349
  53. package/src/extension/message-renderers.ts +3 -4
  54. package/src/extension/notification-router.ts +22 -5
  55. package/src/extension/notification-sink.ts +6 -3
  56. package/src/extension/pi-api.ts +17 -8
  57. package/src/extension/plan-orchestrate.ts +8 -27
  58. package/src/extension/project-init.ts +21 -6
  59. package/src/extension/register.ts +329 -975
  60. package/src/extension/registration/artifact-cleanup.ts +9 -4
  61. package/src/extension/registration/command-utils.ts +5 -1
  62. package/src/extension/registration/commands.ts +806 -314
  63. package/src/extension/registration/compaction-guard.ts +15 -15
  64. package/src/extension/registration/lifecycle.ts +259 -0
  65. package/src/extension/registration/observability.ts +293 -0
  66. package/src/extension/registration/subagent-helpers.ts +29 -7
  67. package/src/extension/registration/subagent-tools.ts +253 -44
  68. package/src/extension/registration/team-tool.ts +19 -84
  69. package/src/extension/registration/ui.ts +168 -0
  70. package/src/extension/registration/viewers.ts +64 -24
  71. package/src/extension/result-watcher.ts +18 -7
  72. package/src/extension/run-bundle-schema.ts +21 -6
  73. package/src/extension/run-export.ts +15 -6
  74. package/src/extension/run-import.ts +64 -29
  75. package/src/extension/run-index.ts +28 -9
  76. package/src/extension/run-maintenance.ts +32 -12
  77. package/src/extension/session-summary.ts +1 -1
  78. package/src/extension/team-manager-command.ts +64 -7
  79. package/src/extension/team-onboard.ts +149 -150
  80. package/src/extension/team-recommendation.ts +121 -21
  81. package/src/extension/team-tool/anchor.ts +31 -64
  82. package/src/extension/team-tool/api.ts +929 -141
  83. package/src/extension/team-tool/auto-summarize.ts +14 -26
  84. package/src/extension/team-tool/cache-control.ts +1 -5
  85. package/src/extension/team-tool/cancel.ts +138 -38
  86. package/src/extension/team-tool/chain-dispatch.ts +5 -13
  87. package/src/extension/team-tool/chain-executor.ts +29 -51
  88. package/src/extension/team-tool/config-patch.ts +1 -1
  89. package/src/extension/team-tool/context.ts +40 -20
  90. package/src/extension/team-tool/destructive-gate.ts +10 -5
  91. package/src/extension/team-tool/doctor.ts +170 -51
  92. package/src/extension/team-tool/explain.ts +228 -214
  93. package/src/extension/team-tool/failure-patterns.ts +3 -9
  94. package/src/extension/team-tool/goal-wrap.ts +71 -29
  95. package/src/extension/team-tool/goal.ts +185 -35
  96. package/src/extension/team-tool/handle-schedule.ts +34 -15
  97. package/src/extension/team-tool/handle-settings.ts +94 -56
  98. package/src/extension/team-tool/health-monitor.ts +27 -108
  99. package/src/extension/team-tool/inspect.ts +42 -9
  100. package/src/extension/team-tool/intent-policy.ts +4 -1
  101. package/src/extension/team-tool/lifecycle-actions.ts +244 -48
  102. package/src/extension/team-tool/orchestrate.ts +7 -18
  103. package/src/extension/team-tool/parallel-dispatch.ts +51 -29
  104. package/src/extension/team-tool/plan.ts +29 -5
  105. package/src/extension/team-tool/respond.ts +49 -16
  106. package/src/extension/team-tool/run-not-found.ts +3 -8
  107. package/src/extension/team-tool/run.ts +80 -317
  108. package/src/extension/team-tool/status.ts +135 -43
  109. package/src/extension/team-tool/workflow-manage.ts +92 -25
  110. package/src/extension/team-tool-types.ts +8 -1
  111. package/src/extension/team-tool.ts +142 -551
  112. package/src/extension/validate-resources.ts +39 -8
  113. package/src/hooks/registry.ts +66 -17
  114. package/src/hooks/types.ts +1 -1
  115. package/src/i18n.ts +25 -11
  116. package/src/observability/correlation.ts +17 -3
  117. package/src/observability/event-bus.ts +51 -56
  118. package/src/observability/event-to-metric.ts +117 -15
  119. package/src/observability/exporters/otlp-exporter.ts +56 -17
  120. package/src/observability/exporters/prometheus-exporter.ts +1 -1
  121. package/src/observability/metric-registry.ts +16 -4
  122. package/src/observability/metric-retention.ts +8 -2
  123. package/src/observability/metric-sink.ts +11 -3
  124. package/src/observability/metrics-primitives.ts +42 -9
  125. package/src/plugins/plugin-define.ts +2 -2
  126. package/src/plugins/plugin-registry.ts +25 -25
  127. package/src/plugins/plugins/index.ts +1 -1
  128. package/src/plugins/plugins/nextjs.ts +16 -16
  129. package/src/plugins/plugins/vite.ts +7 -11
  130. package/src/plugins/plugins/vitest.ts +6 -11
  131. package/src/runtime/adaptive-plan.ts +225 -40
  132. package/src/runtime/agent-control.ts +58 -15
  133. package/src/runtime/agent-memory.ts +15 -9
  134. package/src/runtime/agent-observability.ts +10 -2
  135. package/src/runtime/anchor-manager.ts +27 -25
  136. package/src/runtime/async-marker.ts +7 -1
  137. package/src/runtime/async-runner.ts +39 -24
  138. package/src/runtime/auto-summarize.ts +7 -13
  139. package/src/runtime/background-runner.ts +189 -251
  140. package/src/runtime/batch-barrier.ts +18 -16
  141. package/src/runtime/cancellation-token.ts +16 -6
  142. package/src/runtime/cancellation.ts +46 -8
  143. package/src/runtime/capability-inventory.ts +6 -4
  144. package/src/runtime/chain-parser.ts +44 -11
  145. package/src/runtime/chain-runner.ts +63 -69
  146. package/src/runtime/checkpoint.ts +12 -56
  147. package/src/runtime/child-pi.ts +344 -79
  148. package/src/runtime/coalesce-tasks.ts +268 -0
  149. package/src/runtime/code-summary.ts +71 -26
  150. package/src/runtime/compact-stages/index.ts +15 -5
  151. package/src/runtime/compact-stages/tail-capture-stage.ts +7 -2
  152. package/src/runtime/compact-stages/truncation-stage.ts +4 -1
  153. package/src/runtime/compaction-summary.ts +17 -10
  154. package/src/runtime/completion-guard.ts +33 -16
  155. package/src/runtime/crash-classification.ts +28 -7
  156. package/src/runtime/crash-recovery.ts +177 -37
  157. package/src/runtime/crew-agent-records.ts +145 -47
  158. package/src/runtime/crew-hooks.ts +9 -24
  159. package/src/runtime/cross-extension-rpc.ts +25 -23
  160. package/src/runtime/custom-tools/irc-tool.ts +43 -15
  161. package/src/runtime/custom-tools/submit-result-tool.ts +16 -5
  162. package/src/runtime/delivery-coordinator.ts +34 -7
  163. package/src/runtime/delta-conflict.ts +9 -21
  164. package/src/runtime/deterministic-ast.ts +1 -1
  165. package/src/runtime/diagnostic-export.ts +53 -20
  166. package/src/runtime/direct-run.ts +12 -2
  167. package/src/runtime/dwf-state-store.ts +1 -1
  168. package/src/runtime/dynamic-workflow-context.ts +187 -59
  169. package/src/runtime/dynamic-workflow-runner.ts +42 -20
  170. package/src/runtime/effectiveness.ts +16 -8
  171. package/src/runtime/errors/crew-errors.ts +7 -11
  172. package/src/runtime/event-stream-bridge.ts +9 -3
  173. package/src/runtime/foreground-control.ts +54 -14
  174. package/src/runtime/foreground-watchdog.ts +9 -6
  175. package/src/runtime/goal-achievement.ts +27 -10
  176. package/src/runtime/goal-evaluator.ts +54 -19
  177. package/src/runtime/goal-loop-runner.ts +280 -99
  178. package/src/runtime/goal-state-store.ts +27 -17
  179. package/src/runtime/green-contract.ts +11 -2
  180. package/src/runtime/group-join.ts +64 -31
  181. package/src/runtime/handoff-manager.ts +37 -42
  182. package/src/runtime/heartbeat-gradient.ts +10 -2
  183. package/src/runtime/heartbeat-watcher.ts +32 -6
  184. package/src/runtime/hidden-handoff.ts +13 -31
  185. package/src/runtime/important-line-classifier.ts +12 -2
  186. package/src/runtime/iteration-hooks.ts +25 -15
  187. package/src/runtime/live-agent-control.ts +55 -7
  188. package/src/runtime/live-agent-manager.ts +130 -27
  189. package/src/runtime/live-control-realtime.ts +23 -3
  190. package/src/runtime/live-irc.ts +4 -1
  191. package/src/runtime/live-session-health.ts +12 -4
  192. package/src/runtime/live-session-runtime.ts +379 -117
  193. package/src/runtime/manifest-cache.ts +28 -12
  194. package/src/runtime/mcp-proxy.ts +10 -18
  195. package/src/runtime/metric-parser.ts +1 -5
  196. package/src/runtime/model-fallback.ts +55 -18
  197. package/src/runtime/model-resolver.ts +2 -6
  198. package/src/runtime/model-scope.ts +19 -3
  199. package/src/runtime/notebook-helpers.ts +60 -62
  200. package/src/runtime/orphan-worker-registry.ts +37 -26
  201. package/src/runtime/output-validator.ts +18 -3
  202. package/src/runtime/overflow-recovery.ts +5 -4
  203. package/src/runtime/parallel-research.ts +29 -5
  204. package/src/runtime/parallel-utils.ts +9 -11
  205. package/src/runtime/path-overlap.ts +150 -0
  206. package/src/runtime/peer-dep.ts +12 -17
  207. package/src/runtime/per-write-validator.ts +1 -3
  208. package/src/runtime/phase-tracker.ts +342 -330
  209. package/src/runtime/pi-args.ts +26 -8
  210. package/src/runtime/pi-json-output.ts +1 -1
  211. package/src/runtime/pi-spawn.ts +30 -19
  212. package/src/runtime/pipeline-runner.ts +56 -55
  213. package/src/runtime/plan-templates.ts +5 -6
  214. package/src/runtime/policy-engine.ts +43 -7
  215. package/src/runtime/post-checks.ts +12 -4
  216. package/src/runtime/post-exit-stdio-guard.ts +2 -2
  217. package/src/runtime/process-lifecycle.ts +20 -10
  218. package/src/runtime/process-status.ts +16 -5
  219. package/src/runtime/progress-event-coalescer.ts +2 -1
  220. package/src/runtime/progress-tracker.ts +103 -103
  221. package/src/runtime/prose-compressor.ts +9 -11
  222. package/src/runtime/recovery-recipes.ts +118 -24
  223. package/src/runtime/replace.ts +25 -10
  224. package/src/runtime/resilient-edit.ts +10 -25
  225. package/src/runtime/result-extractor.ts +2 -6
  226. package/src/runtime/retry-executor.ts +20 -4
  227. package/src/runtime/retry-runner.ts +27 -51
  228. package/src/runtime/role-permission.ts +6 -1
  229. package/src/runtime/run-coalesced-task-group.ts +256 -0
  230. package/src/runtime/run-drift.ts +14 -15
  231. package/src/runtime/run-tracker.ts +6 -28
  232. package/src/runtime/runtime-policy.ts +1 -6
  233. package/src/runtime/runtime-resolver.ts +80 -15
  234. package/src/runtime/scheduler.ts +47 -18
  235. package/src/runtime/semaphore.ts +5 -7
  236. package/src/runtime/sensitive-paths.ts +2 -1
  237. package/src/runtime/session-usage.ts +1 -1
  238. package/src/runtime/settings-store.ts +16 -12
  239. package/src/runtime/sidechain-output.ts +6 -2
  240. package/src/runtime/single-agent-compose.ts +1 -4
  241. package/src/runtime/skill-effectiveness.ts +29 -97
  242. package/src/runtime/skill-instructions.ts +40 -83
  243. package/src/runtime/stale-reconciler.ts +73 -197
  244. package/src/runtime/stream-preview.ts +1 -1
  245. package/src/runtime/streaming-output.ts +1 -1
  246. package/src/runtime/subagent-manager.ts +44 -169
  247. package/src/runtime/subprocess-tool-registry.ts +4 -1
  248. package/src/runtime/supervisor-contact.ts +10 -5
  249. package/src/runtime/task-display.ts +19 -5
  250. package/src/runtime/task-graph-scheduler.ts +95 -21
  251. package/src/runtime/task-graph.ts +5 -11
  252. package/src/runtime/task-health.ts +54 -47
  253. package/src/runtime/task-id.ts +12 -19
  254. package/src/runtime/task-output-context.ts +265 -81
  255. package/src/runtime/task-packet.ts +12 -20
  256. package/src/runtime/task-quality.ts +6 -14
  257. package/src/runtime/task-runner/context-retrieval.ts +4 -13
  258. package/src/runtime/task-runner/live-executor.ts +114 -36
  259. package/src/runtime/task-runner/output-splitter.ts +152 -0
  260. package/src/runtime/task-runner/progress.ts +50 -12
  261. package/src/runtime/task-runner/prompt-builder.ts +31 -7
  262. package/src/runtime/task-runner/prompt-pipeline.ts +31 -7
  263. package/src/runtime/task-runner/result-utils.ts +3 -1
  264. package/src/runtime/task-runner/retrieval-orchestrator.ts +310 -0
  265. package/src/runtime/task-runner/run-projection.ts +27 -8
  266. package/src/runtime/task-runner/state-helpers.ts +50 -14
  267. package/src/runtime/task-runner/tail-read.ts +2 -6
  268. package/src/runtime/task-runner.ts +180 -326
  269. package/src/runtime/team-runner-artifacts.ts +13 -0
  270. package/src/runtime/team-runner.ts +456 -974
  271. package/src/runtime/tool-output-pruner.ts +6 -9
  272. package/src/runtime/tool-progress.ts +11 -21
  273. package/src/runtime/verification-gates.ts +33 -24
  274. package/src/runtime/verification-integrity.ts +2 -7
  275. package/src/runtime/verification-worktree.ts +62 -12
  276. package/src/runtime/worker-heartbeat.ts +5 -1
  277. package/src/runtime/worker-startup.ts +29 -5
  278. package/src/runtime/workflow-state.ts +17 -9
  279. package/src/runtime/workspace-lock.ts +30 -35
  280. package/src/runtime/workspace-tree.ts +20 -32
  281. package/src/runtime/yield-handler.ts +43 -9
  282. package/src/runtime/zombie-scanner.ts +5 -4
  283. package/src/schema/config-schema.ts +266 -172
  284. package/src/schema/team-tool-schema.ts +29 -74
  285. package/src/schema/validation-types.ts +25 -17
  286. package/src/skills/discover-skills.ts +35 -10
  287. package/src/skills/skill-templates.ts +109 -27
  288. package/src/skills/validate.ts +26 -8
  289. package/src/state/active-run-registry.ts +87 -28
  290. package/src/state/artifact-store.ts +9 -5
  291. package/src/state/atomic-write-v2.ts +85 -63
  292. package/src/state/atomic-write.ts +106 -27
  293. package/src/state/blob-store.ts +47 -20
  294. package/src/state/contracts.ts +20 -5
  295. package/src/state/crew-init.ts +5 -22
  296. package/src/state/decision-ledger.ts +19 -73
  297. package/src/state/event-log-rotation.ts +41 -15
  298. package/src/state/event-log.ts +168 -53
  299. package/src/state/event-reconstructor.ts +11 -1
  300. package/src/state/gitignore-manager.ts +2 -8
  301. package/src/state/health-store.ts +57 -57
  302. package/src/state/hook-instinct-bridge.ts +1 -1
  303. package/src/state/hook-integrations.ts +1 -1
  304. package/src/state/instinct-store.ts +17 -5
  305. package/src/state/jsonl-writer.ts +1 -1
  306. package/src/state/locks.ts +23 -9
  307. package/src/state/mailbox.ts +151 -28
  308. package/src/state/observation-store.ts +20 -14
  309. package/src/state/run-cache.ts +142 -135
  310. package/src/state/run-graph.ts +6 -15
  311. package/src/state/run-metrics.ts +5 -18
  312. package/src/state/schedule.ts +15 -9
  313. package/src/state/state-store.ts +137 -47
  314. package/src/state/task-claims.ts +12 -2
  315. package/src/state/tiered-eval.ts +52 -43
  316. package/src/state/types-eval.ts +2 -2
  317. package/src/state/types.ts +24 -20
  318. package/src/state/usage.ts +20 -4
  319. package/src/state/worker-atomic-writer.ts +6 -3
  320. package/src/subagents/index.ts +2 -2
  321. package/src/teams/discover-teams.ts +21 -6
  322. package/src/tools/safe-bash-extension.ts +5 -6
  323. package/src/tools/safe-bash.ts +10 -11
  324. package/src/types/new-api-types.ts +6 -10
  325. package/src/ui/agent-management-overlay.ts +52 -40
  326. package/src/ui/card-colors.ts +13 -4
  327. package/src/ui/crew-footer.ts +8 -7
  328. package/src/ui/crew-select-list.ts +1 -1
  329. package/src/ui/dashboard-panes/agents-pane.ts +41 -25
  330. package/src/ui/dashboard-panes/cancellation-pane.ts +1 -1
  331. package/src/ui/dashboard-panes/capability-pane.ts +32 -15
  332. package/src/ui/dashboard-panes/health-pane.ts +2 -1
  333. package/src/ui/dashboard-panes/metrics-pane.ts +4 -1
  334. package/src/ui/dashboard-panes/progress-pane.ts +12 -9
  335. package/src/ui/heartbeat-aggregator.ts +15 -4
  336. package/src/ui/keybinding-map.ts +40 -7
  337. package/src/ui/live-conversation-overlay.ts +36 -20
  338. package/src/ui/live-duration.ts +1 -4
  339. package/src/ui/live-run-sidebar.ts +88 -25
  340. package/src/ui/loaders.ts +2 -8
  341. package/src/ui/mascot.ts +20 -36
  342. package/src/ui/overlays/agent-picker-overlay.ts +11 -3
  343. package/src/ui/overlays/confirm-overlay.ts +4 -2
  344. package/src/ui/overlays/help-overlay.ts +25 -14
  345. package/src/ui/overlays/mailbox-compose-overlay.ts +48 -11
  346. package/src/ui/overlays/mailbox-compose-preview.ts +20 -5
  347. package/src/ui/overlays/mailbox-detail-overlay.ts +27 -6
  348. package/src/ui/pi-ui-compat.ts +7 -7
  349. package/src/ui/powerbar-publisher.ts +120 -42
  350. package/src/ui/render-diff.ts +10 -3
  351. package/src/ui/render-scheduler.ts +12 -4
  352. package/src/ui/run-action-dispatcher.ts +81 -18
  353. package/src/ui/run-dashboard.ts +172 -76
  354. package/src/ui/run-event-bus.ts +59 -37
  355. package/src/ui/run-snapshot-cache.ts +276 -86
  356. package/src/ui/settings-overlay.ts +361 -74
  357. package/src/ui/status-colors.ts +12 -1
  358. package/src/ui/syntax-highlight.ts +1 -1
  359. package/src/ui/terminal-status.ts +1 -3
  360. package/src/ui/theme-adapter.ts +16 -14
  361. package/src/ui/theme-discovery.ts +13 -2
  362. package/src/ui/tool-progress-formatter.ts +7 -7
  363. package/src/ui/tool-render.ts +128 -56
  364. package/src/ui/tool-renderers/brief-mode.ts +45 -27
  365. package/src/ui/tool-renderers/index.ts +109 -43
  366. package/src/ui/transcript-cache.ts +32 -6
  367. package/src/ui/transcript-entries.ts +25 -23
  368. package/src/ui/transcript-viewer.ts +78 -29
  369. package/src/ui/widget/index.ts +99 -40
  370. package/src/ui/widget/widget-formatters.ts +13 -6
  371. package/src/ui/widget/widget-model.ts +19 -8
  372. package/src/ui/widget/widget-renderer.ts +23 -13
  373. package/src/ui/widget/widget-types.ts +1 -1
  374. package/src/utils/bm25-search.ts +199 -199
  375. package/src/utils/conflict-detect.ts +22 -21
  376. package/src/utils/env-filter.ts +14 -7
  377. package/src/utils/file-coalescer.ts +5 -1
  378. package/src/utils/fingerprint.ts +3 -6
  379. package/src/utils/frontmatter.ts +3 -1
  380. package/src/utils/fs-watch.ts +2 -6
  381. package/src/utils/gh-protocol.ts +119 -44
  382. package/src/utils/git.ts +13 -15
  383. package/src/utils/guards.ts +2 -5
  384. package/src/utils/ids.ts +9 -2
  385. package/src/utils/incremental-reader.ts +14 -3
  386. package/src/utils/internal-error.ts +2 -1
  387. package/src/utils/names.ts +12 -3
  388. package/src/utils/paths.ts +49 -5
  389. package/src/utils/project-detector.ts +2 -2
  390. package/src/utils/redaction.ts +29 -19
  391. package/src/utils/resolve-shell.ts +9 -7
  392. package/src/utils/run-watcher-registry.ts +19 -31
  393. package/src/utils/safe-paths.ts +46 -29
  394. package/src/utils/scan-cache.ts +9 -2
  395. package/src/utils/session-utils.ts +2 -4
  396. package/src/utils/sleep.ts +12 -5
  397. package/src/utils/sse-parser.ts +5 -17
  398. package/src/utils/visual.ts +52 -32
  399. package/src/workflows/discover-workflows.ts +41 -109
  400. package/src/workflows/intermediate-store.ts +5 -21
  401. package/src/workflows/preflight-validator.ts +6 -33
  402. package/src/workflows/topology-analyzer.ts +5 -21
  403. package/src/workflows/workflow-config.ts +7 -6
  404. package/src/worktree/branch-freshness.ts +66 -8
  405. package/src/worktree/cleanup.ts +130 -20
  406. package/src/worktree/worktree-manager.ts +212 -69
  407. package/skills/artifact-analysis-loop/SKILL.md +0 -303
  408. package/skills/detection-pipeline-design/SKILL.md +0 -286
  409. package/skills/hunting-investigation-loop/SKILL.md +0 -402
  410. package/skills/incident-playbook-construction/SKILL.md +0 -384
  411. package/skills/security-review/SKILL.md +0 -561
  412. package/skills/threat-hypothesis-framework/SKILL.md +0 -176
  413. package/skills/ui-render-performance/SKILL.md +0 -58
  414. /package/docs/{followup-review-round3-2026-05-12.md → archive/followup-review-round3-2026-05-12.md} +0 -0
  415. /package/docs/{followup-review-round4-2026-05-13.md → archive/followup-review-round4-2026-05-13.md} +0 -0
  416. /package/docs/{pi-crew-bugs.md → archive/pi-crew-bugs.md} +0 -0
  417. /package/docs/{pi-crew-test-final.md → archive/pi-crew-test-final.md} +0 -0
  418. /package/docs/{pi-crew-test-results.md → archive/pi-crew-test-results.md} +0 -0
  419. /package/docs/{pi-crew-test-round2.md → archive/pi-crew-test-round2.md} +0 -0
  420. /package/docs/{pi-crew-test-round4.md → archive/pi-crew-test-round4.md} +0 -0
  421. /package/docs/{pi-crew-test-round5.md → archive/pi-crew-test-round5.md} +0 -0
  422. /package/docs/{pi-crew-test-round6.md → archive/pi-crew-test-round6.md} +0 -0
  423. /package/docs/{pi-crew-v0.5.10-audit-fix-plan.md → archive/pi-crew-v0.5.10-audit-fix-plan.md} +0 -0
  424. /package/docs/{pi-crew-v0.5.11-audit-fix-plan.md → archive/pi-crew-v0.5.11-audit-fix-plan.md} +0 -0
  425. /package/docs/{pi-crew-v0.5.12-audit-fix-plan.md → archive/pi-crew-v0.5.12-audit-fix-plan.md} +0 -0
  426. /package/docs/{pi-crew-v0.5.13-audit-fix-plan.md → archive/pi-crew-v0.5.13-audit-fix-plan.md} +0 -0
  427. /package/docs/{pi-crew-v0.5.14-audit-fix-plan.md → archive/pi-crew-v0.5.14-audit-fix-plan.md} +0 -0
  428. /package/docs/{pi-crew-v0.5.16-audit-fix-plan.md → archive/pi-crew-v0.5.16-audit-fix-plan.md} +0 -0
  429. /package/docs/{pi-crew-v0.5.17-audit-fix-plan.md → archive/pi-crew-v0.5.17-audit-fix-plan.md} +0 -0
  430. /package/docs/{pi-crew-v0.5.5-audit-fix-plan.md → archive/pi-crew-v0.5.5-audit-fix-plan.md} +0 -0
  431. /package/docs/{pi-crew-v0.5.9-audit-fix-plan.md → archive/pi-crew-v0.5.9-audit-fix-plan.md} +0 -0
  432. /package/docs/{pi-mono-opportunities.md → archive/pi-mono-opportunities.md} +0 -0
  433. /package/docs/{pi-mono-review.md → archive/pi-mono-review.md} +0 -0
  434. /package/docs/{pi-subagent4-comparison.md → archive/pi-subagent4-comparison.md} +0 -0
  435. /package/docs/{pi-subagents3-deep-analysis.md → archive/pi-subagents3-deep-analysis.md} +0 -0
@@ -15,14 +15,14 @@
15
15
  // `__test__parseAdaptivePlan` and `__test__repairAdaptivePlan` are re-exported
16
16
  // from team-runner.ts so existing test imports keep working.
17
17
  import * as fs from "node:fs";
18
- import { appendEvent } from "../state/event-log.ts";
19
18
  import { writeArtifact } from "../state/artifact-store.ts";
19
+ import { appendEvent } from "../state/event-log.ts";
20
20
  import { saveRunManifest } from "../state/state-store.ts";
21
+ import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
21
22
  import type { TeamConfig } from "../teams/team-config.ts";
22
23
  import type { WorkflowConfig, WorkflowStep } from "../workflows/workflow-config.ts";
23
- import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
24
+ import { getPlanTemplate, listPlanTemplates, renderPlanTemplate } from "./plan-templates.ts";
24
25
  import { refreshTaskGraphQueues } from "./task-graph-scheduler.ts";
25
- import { getPlanTemplate, renderPlanTemplate, listPlanTemplates } from "./plan-templates.ts";
26
26
 
27
27
  export interface AdaptivePlanTask {
28
28
  role: string;
@@ -42,7 +42,13 @@ export interface AdaptivePlan {
42
42
  const MAX_ADAPTIVE_TASKS = 12;
43
43
 
44
44
  export function slug(value: string): string {
45
- return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 32) || "task";
45
+ return (
46
+ value
47
+ .toLowerCase()
48
+ .replace(/[^a-z0-9]+/g, "-")
49
+ .replace(/^-+|-+$/g, "")
50
+ .slice(0, 32) || "task"
51
+ );
46
52
  }
47
53
 
48
54
  /** Strip surrounding markdown code fences if present. */
@@ -81,11 +87,13 @@ export function parseAdaptivePlan(text: string, allowedRoles: string[]): Adaptiv
81
87
  try {
82
88
  const varsJson = text.slice(templateRefMatch[0].length).trim();
83
89
  if (varsJson) variables = JSON.parse(varsJson);
84
- } catch { /* use empty variables */ }
90
+ } catch {
91
+ /* use empty variables */
92
+ }
85
93
  const rendered = renderPlanTemplate(templateRefMatch[1], variables);
86
94
  if (rendered) {
87
95
  // Convert RenderedPlan → AdaptivePlan
88
- const phases: AdaptivePlanPhase[] = rendered.phases.map(phase => ({
96
+ const phases: AdaptivePlanPhase[] = rendered.phases.map((phase) => ({
89
97
  name: phase.name,
90
98
  tasks: [{ role: phase.role, task: phase.task }],
91
99
  }));
@@ -97,9 +105,22 @@ export function parseAdaptivePlan(text: string, allowedRoles: string[]): Adaptiv
97
105
  const raw = extractAdaptivePlanJson(text);
98
106
  if (!raw) return undefined;
99
107
  let parsed: unknown;
100
- try { parsed = JSON.parse(raw); } catch { return undefined; }
108
+ try {
109
+ parsed = JSON.parse(raw);
110
+ } catch {
111
+ return undefined;
112
+ }
101
113
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return undefined;
102
- const phasesRaw = Array.isArray((parsed as { phases?: unknown }).phases) ? (parsed as { phases: unknown[] }).phases : Array.isArray((parsed as { tasks?: unknown }).tasks) ? [{ name: "adaptive", tasks: (parsed as { tasks: unknown[] }).tasks }] : undefined;
114
+ const phasesRaw = Array.isArray((parsed as { phases?: unknown }).phases)
115
+ ? (parsed as { phases: unknown[] }).phases
116
+ : Array.isArray((parsed as { tasks?: unknown }).tasks)
117
+ ? [
118
+ {
119
+ name: "adaptive",
120
+ tasks: (parsed as { tasks: unknown[] }).tasks,
121
+ },
122
+ ]
123
+ : undefined;
103
124
  if (!phasesRaw) return undefined;
104
125
  const allowed = new Set(allowedRoles);
105
126
  const phases: AdaptivePlanPhase[] = [];
@@ -111,14 +132,25 @@ export function parseAdaptivePlan(text: string, allowedRoles: string[]): Adaptiv
111
132
  const tasks: AdaptivePlanTask[] = [];
112
133
  for (const taskRaw of phaseObj.tasks) {
113
134
  if (!taskRaw || typeof taskRaw !== "object" || Array.isArray(taskRaw)) return undefined;
114
- const taskObj = taskRaw as { role?: unknown; title?: unknown; task?: unknown };
135
+ const taskObj = taskRaw as {
136
+ role?: unknown;
137
+ title?: unknown;
138
+ task?: unknown;
139
+ };
115
140
  if (typeof taskObj.role !== "string" || !allowed.has(taskObj.role)) return undefined;
116
141
  if (typeof taskObj.task !== "string" || !taskObj.task.trim()) return undefined;
117
142
  if (total >= MAX_ADAPTIVE_TASKS) return undefined;
118
- tasks.push({ role: taskObj.role, title: typeof taskObj.title === "string" ? taskObj.title : undefined, task: taskObj.task.trim() });
143
+ tasks.push({
144
+ role: taskObj.role,
145
+ title: typeof taskObj.title === "string" ? taskObj.title : undefined,
146
+ task: taskObj.task.trim(),
147
+ });
119
148
  total++;
120
149
  }
121
- phases.push({ name: typeof phaseObj.name === "string" && phaseObj.name.trim() ? phaseObj.name.trim() : `phase-${phaseIndex + 1}`, tasks });
150
+ phases.push({
151
+ name: typeof phaseObj.name === "string" && phaseObj.name.trim() ? phaseObj.name.trim() : `phase-${phaseIndex + 1}`,
152
+ tasks,
153
+ });
122
154
  }
123
155
  return phases.length ? { phases } : undefined;
124
156
  }
@@ -154,7 +186,11 @@ function closeUnbalancedJson(raw: string): CloseUnbalancedJsonResult {
154
186
  }
155
187
  while (stack.length) result += stack.pop();
156
188
  if (inString) {
157
- return { text: result, status: "unstable", warning: "JSON string was truncated — values may be incorrect" };
189
+ return {
190
+ text: result,
191
+ status: "unstable",
192
+ warning: "JSON string was truncated — values may be incorrect",
193
+ };
158
194
  }
159
195
  return { text: result, status: "repaired" };
160
196
  }
@@ -240,7 +276,16 @@ export function repairAdaptivePlan(text: string, allowedRoles: string[]): { plan
240
276
  salvageUsed = parsed !== undefined;
241
277
  }
242
278
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return { repaired: false, reason: "invalid-json" };
243
- const phasesRaw = Array.isArray((parsed as { phases?: unknown }).phases) ? (parsed as { phases: unknown[] }).phases : Array.isArray((parsed as { tasks?: unknown }).tasks) ? [{ name: "adaptive", tasks: (parsed as { tasks: unknown[] }).tasks }] : undefined;
279
+ const phasesRaw = Array.isArray((parsed as { phases?: unknown }).phases)
280
+ ? (parsed as { phases: unknown[] }).phases
281
+ : Array.isArray((parsed as { tasks?: unknown }).tasks)
282
+ ? [
283
+ {
284
+ name: "adaptive",
285
+ tasks: (parsed as { tasks: unknown[] }).tasks,
286
+ },
287
+ ]
288
+ : undefined;
244
289
  if (!phasesRaw) return { repaired: false, reason: "missing-phases" };
245
290
  const allowed = new Set(allowedRoles);
246
291
  const phases: AdaptivePlanPhase[] = [];
@@ -260,20 +305,38 @@ export function repairAdaptivePlan(text: string, allowedRoles: string[]): { plan
260
305
  repaired = true;
261
306
  continue;
262
307
  }
263
- const taskObj = taskRaw as { role?: unknown; title?: unknown; task?: unknown };
308
+ const taskObj = taskRaw as {
309
+ role?: unknown;
310
+ title?: unknown;
311
+ task?: unknown;
312
+ };
264
313
  const role = typeof taskObj.role === "string" ? adaptiveRoleAlias(taskObj.role, allowed) : undefined;
265
314
  const taskText = typeof taskObj.task === "string" ? taskObj.task.trim() : "";
266
315
  if (!role || !taskText) {
267
316
  repaired = true;
268
317
  continue;
269
318
  }
270
- tasks.push({ role, title: typeof taskObj.title === "string" ? taskObj.title : undefined, task: taskText });
319
+ tasks.push({
320
+ role,
321
+ title: typeof taskObj.title === "string" ? taskObj.title : undefined,
322
+ task: taskText,
323
+ });
271
324
  total++;
272
325
  }
273
- if (tasks.length) phases.push({ name: typeof phaseObj.name === "string" && phaseObj.name.trim() ? phaseObj.name.trim() : `phase-${phaseIndex + 1}`, tasks });
326
+ if (tasks.length)
327
+ phases.push({
328
+ name: typeof phaseObj.name === "string" && phaseObj.name.trim() ? phaseObj.name.trim() : `phase-${phaseIndex + 1}`,
329
+ tasks,
330
+ });
274
331
  if (total >= MAX_ADAPTIVE_TASKS) break;
275
332
  }
276
- return phases.length ? { plan: { phases }, repaired: true, reason: repaired ? "repaired" : "normalized" } : { repaired: false, reason: "empty-plan" };
333
+ return phases.length
334
+ ? {
335
+ plan: { phases },
336
+ repaired: true,
337
+ reason: repaired ? "repaired" : "normalized",
338
+ }
339
+ : { repaired: false, reason: "empty-plan" };
277
340
  }
278
341
 
279
342
  function reconstructAdaptiveWorkflow(workflow: WorkflowConfig, tasks: TeamTaskState[]): WorkflowConfig {
@@ -281,7 +344,13 @@ function reconstructAdaptiveWorkflow(workflow: WorkflowConfig, tasks: TeamTaskSt
281
344
  const steps: WorkflowStep[] = [];
282
345
  for (const task of tasks) {
283
346
  if (!task.stepId?.startsWith("adaptive-") || !task.adaptive?.task || existing.has(task.stepId)) continue;
284
- steps.push({ id: task.stepId, role: task.role, dependsOn: task.graph?.dependencies ?? task.dependsOn, parallelGroup: `adaptive-${slug(task.adaptive.phase)}`, task: task.adaptive.task });
347
+ steps.push({
348
+ id: task.stepId,
349
+ role: task.role,
350
+ dependsOn: task.graph?.dependencies ?? task.dependsOn,
351
+ parallelGroup: `adaptive-${slug(task.adaptive.phase)}`,
352
+ task: task.adaptive.task,
353
+ });
285
354
  }
286
355
  return steps.length ? { ...workflow, steps: [...workflow.steps, ...steps] } : workflow;
287
356
  }
@@ -301,34 +370,110 @@ export interface InjectAdaptivePlanResult {
301
370
  }
302
371
 
303
372
  export function injectAdaptivePlanIfReady(input: InjectAdaptivePlanInput): InjectAdaptivePlanResult {
304
- if (input.workflow.name !== "implementation") return { tasks: input.tasks, workflow: input.workflow, injected: false, missingPlan: false };
305
- if (input.tasks.some((task) => task.stepId?.startsWith("adaptive-"))) return { tasks: input.tasks, workflow: reconstructAdaptiveWorkflow(input.workflow, input.tasks), injected: false, missingPlan: false };
306
- const completedAssess = input.tasks.find((task) => task.stepId === "assess" && (task.status === "completed" || task.status === "needs_attention"));
307
- if (!completedAssess) return { tasks: input.tasks, workflow: input.workflow, injected: false, missingPlan: false };
373
+ if (input.workflow.name !== "implementation")
374
+ return {
375
+ tasks: input.tasks,
376
+ workflow: input.workflow,
377
+ injected: false,
378
+ missingPlan: false,
379
+ };
380
+ if (input.tasks.some((task) => task.stepId?.startsWith("adaptive-")))
381
+ return {
382
+ tasks: input.tasks,
383
+ workflow: reconstructAdaptiveWorkflow(input.workflow, input.tasks),
384
+ injected: false,
385
+ missingPlan: false,
386
+ };
387
+ const completedAssess = input.tasks.find(
388
+ (task) => task.stepId === "assess" && (task.status === "completed" || task.status === "needs_attention"),
389
+ );
390
+ if (!completedAssess)
391
+ return {
392
+ tasks: input.tasks,
393
+ workflow: input.workflow,
394
+ injected: false,
395
+ missingPlan: false,
396
+ };
308
397
  if (!completedAssess.resultArtifact?.path) {
309
- appendEvent(input.manifest.eventsPath, { type: "adaptive.plan_missing", runId: input.manifest.runId, taskId: completedAssess.id, message: "Adaptive planner result artifact is missing." });
310
- return { tasks: input.tasks, workflow: input.workflow, injected: false, missingPlan: true };
398
+ appendEvent(input.manifest.eventsPath, {
399
+ type: "adaptive.plan_missing",
400
+ runId: input.manifest.runId,
401
+ taskId: completedAssess.id,
402
+ message: "Adaptive planner result artifact is missing.",
403
+ });
404
+ return {
405
+ tasks: input.tasks,
406
+ workflow: input.workflow,
407
+ injected: false,
408
+ missingPlan: true,
409
+ };
311
410
  }
312
411
  const assessTask = completedAssess;
313
412
  const resultPath = completedAssess.resultArtifact.path;
314
413
  let text = "";
315
- try { text = fs.readFileSync(resultPath, "utf-8"); } catch {
316
- appendEvent(input.manifest.eventsPath, { type: "adaptive.plan_missing", runId: input.manifest.runId, taskId: assessTask.id, message: "Adaptive planner result artifact could not be read." });
317
- return { tasks: input.tasks, workflow: input.workflow, injected: false, missingPlan: true };
414
+ try {
415
+ text = fs.readFileSync(resultPath, "utf-8");
416
+ } catch {
417
+ appendEvent(input.manifest.eventsPath, {
418
+ type: "adaptive.plan_missing",
419
+ runId: input.manifest.runId,
420
+ taskId: assessTask.id,
421
+ message: "Adaptive planner result artifact could not be read.",
422
+ });
423
+ return {
424
+ tasks: input.tasks,
425
+ workflow: input.workflow,
426
+ injected: false,
427
+ missingPlan: true,
428
+ };
318
429
  }
319
430
  const allowedRoles = input.team.roles.map((role) => role.name);
320
431
  let plan = parseAdaptivePlan(text, allowedRoles);
321
432
  if (!plan) {
322
- const repair = process.env.PI_CREW_ADAPTIVE_REPAIR === "0" || process.env.PI_TEAMS_ADAPTIVE_REPAIR === "0" ? { repaired: false, reason: "disabled" } : repairAdaptivePlan(text, allowedRoles);
433
+ const repair =
434
+ process.env.PI_CREW_ADAPTIVE_REPAIR === "0" || process.env.PI_TEAMS_ADAPTIVE_REPAIR === "0"
435
+ ? { repaired: false, reason: "disabled" }
436
+ : repairAdaptivePlan(text, allowedRoles);
323
437
  if (repair.plan) {
324
438
  plan = repair.plan;
325
- const repairArtifact = writeArtifact(input.manifest.artifactsRoot, { kind: "metadata", relativePath: "metadata/adaptive-repair.json", producer: assessTask.id, content: `${JSON.stringify({ reason: repair.reason, phases: repair.plan.phases.map((phase) => ({ name: phase.name, count: phase.tasks.length, roles: phase.tasks.map((task) => task.role) })) }, null, 2)}\n` });
326
- saveRunManifest({ ...input.manifest, updatedAt: new Date().toISOString(), artifacts: [...input.manifest.artifacts, repairArtifact] });
327
- appendEvent(input.manifest.eventsPath, { type: "adaptive.plan_repaired", runId: input.manifest.runId, taskId: assessTask.id, message: "Adaptive planner output was repaired before dynamic subagents were spawned.", data: { reason: repair.reason } });
439
+ const repairArtifact = writeArtifact(input.manifest.artifactsRoot, {
440
+ kind: "metadata",
441
+ relativePath: "metadata/adaptive-repair.json",
442
+ producer: assessTask.id,
443
+ content: `${JSON.stringify({ reason: repair.reason, phases: repair.plan.phases.map((phase) => ({ name: phase.name, count: phase.tasks.length, roles: phase.tasks.map((task) => task.role) })) }, null, 2)}\n`,
444
+ });
445
+ saveRunManifest({
446
+ ...input.manifest,
447
+ updatedAt: new Date().toISOString(),
448
+ artifacts: [...input.manifest.artifacts, repairArtifact],
449
+ });
450
+ appendEvent(input.manifest.eventsPath, {
451
+ type: "adaptive.plan_repaired",
452
+ runId: input.manifest.runId,
453
+ taskId: assessTask.id,
454
+ message: "Adaptive planner output was repaired before dynamic subagents were spawned.",
455
+ data: { reason: repair.reason },
456
+ });
328
457
  } else {
329
- appendEvent(input.manifest.eventsPath, { type: "adaptive.plan_repair_failed", runId: input.manifest.runId, taskId: assessTask.id, message: "Adaptive planner output could not be repaired.", data: { reason: repair.reason } });
330
- appendEvent(input.manifest.eventsPath, { type: "adaptive.plan_missing", runId: input.manifest.runId, taskId: assessTask.id, message: "Adaptive planner did not produce a valid plan; no dynamic subagents were spawned." });
331
- return { tasks: input.tasks, workflow: input.workflow, injected: false, missingPlan: true };
458
+ appendEvent(input.manifest.eventsPath, {
459
+ type: "adaptive.plan_repair_failed",
460
+ runId: input.manifest.runId,
461
+ taskId: assessTask.id,
462
+ message: "Adaptive planner output could not be repaired.",
463
+ data: { reason: repair.reason },
464
+ });
465
+ appendEvent(input.manifest.eventsPath, {
466
+ type: "adaptive.plan_missing",
467
+ runId: input.manifest.runId,
468
+ taskId: assessTask.id,
469
+ message: "Adaptive planner did not produce a valid plan; no dynamic subagents were spawned.",
470
+ });
471
+ return {
472
+ tasks: input.tasks,
473
+ workflow: input.workflow,
474
+ injected: false,
475
+ missingPlan: true,
476
+ };
332
477
  }
333
478
  }
334
479
  const steps: WorkflowStep[] = [];
@@ -341,7 +486,13 @@ export function injectAdaptivePlanIfReady(input: InjectAdaptivePlanInput): Injec
341
486
  counter++;
342
487
  const stepId = `adaptive-${phaseIndex + 1}-${taskIndex + 1}-${slug(planned.role)}`;
343
488
  const taskId = `adaptive-${String(counter).padStart(2, "0")}-${slug(planned.role)}`;
344
- steps.push({ id: stepId, role: planned.role, dependsOn: previousStepIds, parallelGroup: `adaptive-${slug(phase.name)}`, task: planned.task });
489
+ steps.push({
490
+ id: stepId,
491
+ role: planned.role,
492
+ dependsOn: previousStepIds,
493
+ parallelGroup: `adaptive-${slug(phase.name)}`,
494
+ task: planned.task,
495
+ });
345
496
  tasks.push({
346
497
  id: taskId,
347
498
  runId: input.manifest.runId,
@@ -353,21 +504,55 @@ export function injectAdaptivePlanIfReady(input: InjectAdaptivePlanInput): Injec
353
504
  dependsOn: previousStepIds,
354
505
  cwd: input.manifest.cwd,
355
506
  adaptive: { phase: phase.name, task: planned.task },
356
- graph: { taskId, dependencies: previousStepIds, children: [], queue: "blocked" },
507
+ graph: {
508
+ taskId,
509
+ dependencies: previousStepIds,
510
+ children: [],
511
+ queue: "blocked",
512
+ },
357
513
  });
358
514
  currentStepIds.push(stepId);
359
515
  }
360
516
  previousStepIds = currentStepIds;
361
517
  }
362
- const dependencyTaskIdByStep = new Map<string, string>([["assess", assessTask.id], ...tasks.map((task) => [task.stepId ?? task.id, task.id] as const)]);
518
+ const dependencyTaskIdByStep = new Map<string, string>([
519
+ ["assess", assessTask.id],
520
+ ...tasks.map((task) => [task.stepId ?? task.id, task.id] as const),
521
+ ]);
363
522
  const withGraph = tasks.map((task) => ({
364
523
  ...task,
365
524
  dependsOn: task.dependsOn.map((dep) => dependencyTaskIdByStep.get(dep) ?? dep),
366
- graph: task.graph ? { ...task.graph, dependencies: task.dependsOn.map((dep) => dependencyTaskIdByStep.get(dep) ?? dep), queue: "blocked" as const } : task.graph,
525
+ graph: task.graph
526
+ ? {
527
+ ...task.graph,
528
+ dependencies: task.dependsOn.map((dep) => dependencyTaskIdByStep.get(dep) ?? dep),
529
+ queue: "blocked" as const,
530
+ }
531
+ : task.graph,
367
532
  }));
368
533
  const allTasks = refreshTaskGraphQueues([...input.tasks, ...withGraph]);
369
- appendEvent(input.manifest.eventsPath, { type: "adaptive.plan_injected", runId: input.manifest.runId, taskId: assessTask.id, message: `Injected ${withGraph.length} adaptive subagent task(s) across ${plan.phases.length} phase(s).`, data: { phases: plan.phases.map((phase) => ({ name: phase.name, count: phase.tasks.length, roles: phase.tasks.map((task) => task.role) })) } });
370
- return { tasks: allTasks, workflow: { ...input.workflow, steps: [...input.workflow.steps, ...steps] }, injected: true, missingPlan: false };
534
+ appendEvent(input.manifest.eventsPath, {
535
+ type: "adaptive.plan_injected",
536
+ runId: input.manifest.runId,
537
+ taskId: assessTask.id,
538
+ message: `Injected ${withGraph.length} adaptive subagent task(s) across ${plan.phases.length} phase(s).`,
539
+ data: {
540
+ phases: plan.phases.map((phase) => ({
541
+ name: phase.name,
542
+ count: phase.tasks.length,
543
+ roles: phase.tasks.map((task) => task.role),
544
+ })),
545
+ },
546
+ });
547
+ return {
548
+ tasks: allTasks,
549
+ workflow: {
550
+ ...input.workflow,
551
+ steps: [...input.workflow.steps, ...steps],
552
+ },
553
+ injected: true,
554
+ missingPlan: false,
555
+ };
371
556
  }
372
557
 
373
558
  // Test compatibility: original team-runner.ts exposed these names. Keep
@@ -1,9 +1,9 @@
1
+ import { randomUUID } from "node:crypto";
1
2
  import type { PiTeamsConfig } from "../config/config.ts";
2
- import type { TeamRunManifest, ControlReservation } from "../state/types.ts";
3
+ import type { ControlReservation, TeamRunManifest } from "../state/types.ts";
3
4
  import { appendTaskAttentionEvent } from "./attention-events.ts";
4
- import type { CrewAgentRecord } from "./crew-agent-runtime.ts";
5
5
  import { upsertCrewAgent } from "./crew-agent-records.ts";
6
- import { randomUUID } from "node:crypto";
6
+ import type { CrewAgentRecord } from "./crew-agent-runtime.ts";
7
7
 
8
8
  export interface CrewControlConfig {
9
9
  enabled: boolean;
@@ -21,7 +21,16 @@ function positiveInt(value: unknown): number | undefined {
21
21
  }
22
22
 
23
23
  export function resolveCrewControlConfig(config: PiTeamsConfig | undefined): CrewControlConfig {
24
- const raw = config as PiTeamsConfig & { control?: { enabled?: unknown; needsAttentionAfterMs?: unknown; consecutiveFailureThreshold?: unknown; longRunningMinutes?: unknown } } | undefined;
24
+ const raw = config as
25
+ | (PiTeamsConfig & {
26
+ control?: {
27
+ enabled?: unknown;
28
+ needsAttentionAfterMs?: unknown;
29
+ consecutiveFailureThreshold?: unknown;
30
+ longRunningMinutes?: unknown;
31
+ };
32
+ })
33
+ | undefined;
25
34
  return {
26
35
  enabled: raw?.control?.enabled === false ? false : true,
27
36
  needsAttentionAfterMs: positiveInt(raw?.control?.needsAttentionAfterMs) ?? DEFAULT_NEEDS_ATTENTION_MS,
@@ -47,7 +56,12 @@ export function formatActivityAge(agent: CrewAgentRecord, now = Date.now()): str
47
56
  return agent.progress?.activityState === "needs_attention" ? `no activity for ${minutes}m` : `active ${minutes}m ago`;
48
57
  }
49
58
 
50
- export function applyAttentionState(manifest: TeamRunManifest, agent: CrewAgentRecord, config: CrewControlConfig, now = Date.now()): CrewAgentRecord {
59
+ export function applyAttentionState(
60
+ manifest: TeamRunManifest,
61
+ agent: CrewAgentRecord,
62
+ config: CrewControlConfig,
63
+ now = Date.now(),
64
+ ): CrewAgentRecord {
51
65
  if (!config.enabled || agent.status !== "running") return agent;
52
66
  const age = activityAgeMs(agent, now);
53
67
  if (age === undefined || age <= config.needsAttentionAfterMs) return agent;
@@ -55,7 +69,11 @@ export function applyAttentionState(manifest: TeamRunManifest, agent: CrewAgentR
55
69
  const updated: CrewAgentRecord = {
56
70
  ...agent,
57
71
  progress: {
58
- ...(agent.progress ?? { recentTools: [], recentOutput: [], toolCount: agent.toolUses ?? 0 }),
72
+ ...(agent.progress ?? {
73
+ recentTools: [],
74
+ recentOutput: [],
75
+ toolCount: agent.toolUses ?? 0,
76
+ }),
59
77
  activityState: "needs_attention",
60
78
  },
61
79
  };
@@ -64,7 +82,14 @@ export function applyAttentionState(manifest: TeamRunManifest, agent: CrewAgentR
64
82
  manifest,
65
83
  taskId: agent.taskId,
66
84
  message: `${agent.agent} needs attention (no observed activity for ${Math.floor(age / 1000)}s).`,
67
- data: { activityState: "needs_attention", reason: "idle", elapsedMs: age, taskId: agent.taskId, agentName: agent.agent, suggestedAction: "Check worker status, wait, steer, or cancel if needed." },
85
+ data: {
86
+ activityState: "needs_attention",
87
+ reason: "idle",
88
+ elapsedMs: age,
89
+ taskId: agent.taskId,
90
+ agentName: agent.agent,
91
+ suggestedAction: "Check worker status, wait, steer, or cancel if needed.",
92
+ },
68
93
  });
69
94
  return updated;
70
95
  }
@@ -92,7 +117,11 @@ function applyLongRunningCheck(
92
117
  const updated: CrewAgentRecord = {
93
118
  ...agent,
94
119
  progress: {
95
- ...(agent.progress ?? { recentTools: [], recentOutput: [], toolCount: agent.toolUses ?? 0 }),
120
+ ...(agent.progress ?? {
121
+ recentTools: [],
122
+ recentOutput: [],
123
+ toolCount: agent.toolUses ?? 0,
124
+ }),
96
125
  activityState: "active_long_running",
97
126
  },
98
127
  };
@@ -101,7 +130,14 @@ function applyLongRunningCheck(
101
130
  manifest,
102
131
  taskId: agent.taskId,
103
132
  message: `${agent.agent} has been running for ${Math.floor(runtimeMs / 60000)}m (threshold: ${config.longRunningMinutes}m).`,
104
- data: { activityState: "active_long_running", reason: "idle", elapsedMs: runtimeMs, taskId: agent.taskId, agentName: agent.agent, suggestedAction: "Check worker progress, steer, or cancel if needed." },
133
+ data: {
134
+ activityState: "active_long_running",
135
+ reason: "idle",
136
+ elapsedMs: runtimeMs,
137
+ taskId: agent.taskId,
138
+ agentName: agent.agent,
139
+ suggestedAction: "Check worker progress, steer, or cancel if needed.",
140
+ },
105
141
  });
106
142
  return updated;
107
143
  }
@@ -122,7 +158,11 @@ function trackConsecutiveToolFailure(
122
158
  const updated: CrewAgentRecord = {
123
159
  ...agent,
124
160
  progress: {
125
- ...(agent.progress ?? { recentTools: [], recentOutput: [], toolCount: agent.toolUses ?? 0 }),
161
+ ...(agent.progress ?? {
162
+ recentTools: [],
163
+ recentOutput: [],
164
+ toolCount: agent.toolUses ?? 0,
165
+ }),
126
166
  consecutiveFailures: newFailures,
127
167
  },
128
168
  };
@@ -133,7 +173,13 @@ function trackConsecutiveToolFailure(
133
173
  manifest,
134
174
  taskId: agent.taskId,
135
175
  message: `${agent.agent} has ${newFailures} consecutive tool failures (threshold: ${config.consecutiveFailureThreshold}). Last: ${toolName}${error ? ` - ${error.slice(0, 100)}` : ""}`,
136
- data: { activityState: "needs_attention", reason: "tool_failures", taskId: agent.taskId, agentName: agent.agent, suggestedAction: "Investigate tool failures, steer, or cancel if needed." },
176
+ data: {
177
+ activityState: "needs_attention",
178
+ reason: "tool_failures",
179
+ taskId: agent.taskId,
180
+ agentName: agent.agent,
181
+ suggestedAction: "Investigate tool failures, steer, or cancel if needed.",
182
+ },
137
183
  });
138
184
  } else {
139
185
  upsertCrewAgent(manifest, updated);
@@ -143,10 +189,7 @@ function trackConsecutiveToolFailure(
143
189
  }
144
190
 
145
191
  /** @internal */
146
- function resetConsecutiveToolFailures(
147
- manifest: TeamRunManifest,
148
- agent: CrewAgentRecord,
149
- ): void {
192
+ function resetConsecutiveToolFailures(manifest: TeamRunManifest, agent: CrewAgentRecord): void {
150
193
  if (!agent.progress?.consecutiveFailures) return;
151
194
  const updated: CrewAgentRecord = {
152
195
  ...agent,
@@ -61,15 +61,21 @@ export function buildMemoryBlock(agentName: string, scope: AgentMemoryScope, cwd
61
61
  `# Agent Memory (${mode})`,
62
62
  `Memory scope: ${scope}`,
63
63
  `Memory directory: ${memoryDir}`,
64
- writable ? "Use this persistent directory to maintain useful long-term notes for this agent." : "You may reference existing memory, but do not create or modify memory files.",
64
+ writable
65
+ ? "Use this persistent directory to maintain useful long-term notes for this agent."
66
+ : "You may reference existing memory, but do not create or modify memory files.",
65
67
  "",
66
68
  existing ? `## Current MEMORY.md\n${existing}` : "No MEMORY.md exists yet.",
67
- writable ? [
68
- "",
69
- "## Memory Instructions",
70
- "- Keep MEMORY.md concise (under 200 lines); store details in separate linked files.",
71
- "- Reject stale memories; update or remove outdated notes.",
72
- "- Use safe relative filenames inside the memory directory only.",
73
- ].join("\n") : "",
74
- ].filter(Boolean).join("\n");
69
+ writable
70
+ ? [
71
+ "",
72
+ "## Memory Instructions",
73
+ "- Keep MEMORY.md concise (under 200 lines); store details in separate linked files.",
74
+ "- Reject stale memories; update or remove outdated notes.",
75
+ "- Use safe relative filenames inside the memory directory only.",
76
+ ].join("\n")
77
+ : "",
78
+ ]
79
+ .filter(Boolean)
80
+ .join("\n");
75
81
  }
@@ -28,7 +28,12 @@ export function readTextTail(filePath: string, maxBytes = 64_000): TextTailResul
28
28
  try {
29
29
  const buffer = Buffer.alloc(bytesToRead);
30
30
  fs.readSync(fd, buffer, 0, bytesToRead, stat.size - bytesToRead);
31
- return { path: filePath, text: buffer.toString("utf-8"), bytes: stat.size, truncated: stat.size > bytesToRead };
31
+ return {
32
+ path: filePath,
33
+ text: buffer.toString("utf-8"),
34
+ bytes: stat.size,
35
+ truncated: stat.size > bytesToRead,
36
+ };
32
37
  } finally {
33
38
  fs.closeSync(fd);
34
39
  }
@@ -85,7 +90,10 @@ function agentLine(manifest: TeamRunManifest, agent: CrewAgentRecord): string {
85
90
  return `- ${statusGlyph(agent.status)} ${agent.taskId} ${agent.role} → ${agent.agent} · ${agent.status} · ${agent.runtime} · ${activityText(agent)}${outputWarning(manifest, agent)}${agent.error ? ` · error=${agent.error}` : ""}`;
86
91
  }
87
92
 
88
- export function buildAgentDashboard(manifest: TeamRunManifest): { text: string; groups: Record<string, CrewAgentRecord[]> } {
93
+ export function buildAgentDashboard(manifest: TeamRunManifest): {
94
+ text: string;
95
+ groups: Record<string, CrewAgentRecord[]>;
96
+ } {
89
97
  const agents = readCrewAgents(manifest);
90
98
  const groups: Record<string, CrewAgentRecord[]> = {
91
99
  running: agents.filter((agent) => agent.status === "running"),