pi-crew 0.9.16 → 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 +81 -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 +145 -47
  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 +44 -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
@@ -1,77 +1,78 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
- import { projectCrewRoot } from "../utils/paths.ts";
4
- import { allTeams, discoverTeams } from "../teams/discover-teams.ts";
5
3
  import type { TeamRunManifest } from "../state/types.ts";
4
+ import { allTeams, discoverTeams } from "../teams/discover-teams.ts";
5
+ import { projectCrewRoot } from "../utils/paths.ts";
6
6
 
7
7
  export interface OnboardingOptions {
8
- team?: string;
9
- limit?: number;
10
- cwd?: string;
8
+ team?: string;
9
+ limit?: number;
10
+ cwd?: string;
11
11
  }
12
12
 
13
13
  interface RunSummary {
14
- runId: string;
15
- status: string;
16
- goal: string;
17
- team: string;
18
- createdAt: string;
19
- completedAt?: string;
20
- taskCount: number;
14
+ runId: string;
15
+ status: string;
16
+ goal: string;
17
+ team: string;
18
+ createdAt: string;
19
+ completedAt?: string;
20
+ taskCount: number;
21
21
  }
22
22
 
23
23
  /**
24
24
  * Load run summaries from the state directory.
25
25
  */
26
26
  function loadRunSummaries(cwd: string, options: OnboardingOptions = {}): RunSummary[] {
27
- const crewRoot = projectCrewRoot(cwd);
28
- const runsRoot = path.join(crewRoot, "state", "runs");
29
-
30
- if (!fs.existsSync(runsRoot)) return [];
31
-
32
- const limit = options.limit ?? 5;
33
- const teamFilter = options.team;
34
-
35
- const entries = fs.readdirSync(runsRoot)
36
- .filter((e) => {
37
- try {
38
- return fs.statSync(path.join(runsRoot, e)).isDirectory();
39
- } catch {
40
- return false;
41
- }
42
- })
43
- .sort()
44
- .reverse()
45
- .slice(0, 100);
46
-
47
- const summaries: RunSummary[] = [];
48
-
49
- for (const runId of entries) {
50
- if (summaries.length >= limit) break;
51
-
52
- const manifestPath = path.join(runsRoot, runId, "manifest.json");
53
- if (!fs.existsSync(manifestPath)) continue;
54
-
55
- try {
56
- const raw = JSON.parse(fs.readFileSync(manifestPath, "utf-8")) as TeamRunManifest & { completedAt?: string };
57
-
58
- if (teamFilter && raw.team !== teamFilter) continue;
59
-
60
- summaries.push({
61
- runId,
62
- status: raw.status,
63
- goal: raw.goal ?? "",
64
- team: raw.team,
65
- createdAt: raw.createdAt,
66
- completedAt: raw.completedAt ?? raw.updatedAt,
67
- taskCount: 0, // tasks stored separately, not in manifest
68
- });
69
- } catch {
70
- continue;
71
- }
72
- }
73
-
74
- return summaries;
27
+ const crewRoot = projectCrewRoot(cwd);
28
+ const runsRoot = path.join(crewRoot, "state", "runs");
29
+
30
+ if (!fs.existsSync(runsRoot)) return [];
31
+
32
+ const limit = options.limit ?? 5;
33
+ const teamFilter = options.team;
34
+
35
+ const entries = fs
36
+ .readdirSync(runsRoot)
37
+ .filter((e) => {
38
+ try {
39
+ return fs.statSync(path.join(runsRoot, e)).isDirectory();
40
+ } catch {
41
+ return false;
42
+ }
43
+ })
44
+ .sort()
45
+ .reverse()
46
+ .slice(0, 100);
47
+
48
+ const summaries: RunSummary[] = [];
49
+
50
+ for (const runId of entries) {
51
+ if (summaries.length >= limit) break;
52
+
53
+ const manifestPath = path.join(runsRoot, runId, "manifest.json");
54
+ if (!fs.existsSync(manifestPath)) continue;
55
+
56
+ try {
57
+ const raw = JSON.parse(fs.readFileSync(manifestPath, "utf-8")) as TeamRunManifest & { completedAt?: string };
58
+
59
+ if (teamFilter && raw.team !== teamFilter) continue;
60
+
61
+ summaries.push({
62
+ runId,
63
+ status: raw.status,
64
+ goal: raw.goal ?? "",
65
+ team: raw.team,
66
+ createdAt: raw.createdAt,
67
+ completedAt: raw.completedAt ?? raw.updatedAt,
68
+ taskCount: 0, // tasks stored separately, not in manifest
69
+ });
70
+ } catch {
71
+ continue;
72
+ }
73
+ }
74
+
75
+ return summaries;
75
76
  }
76
77
 
77
78
  /**
@@ -79,100 +80,100 @@ function loadRunSummaries(cwd: string, options: OnboardingOptions = {}): RunSumm
79
80
  * (e.g. legacy test runs) — returns "?" instead of "NaNm".
80
81
  */
81
82
  export function formatDuration(createdAt: string, completedAt?: string): string {
82
- const start = new Date(createdAt).getTime();
83
- const end = completedAt ? new Date(completedAt).getTime() : Date.now();
84
- if (!Number.isFinite(start) || !Number.isFinite(end) || end < start) return "?";
85
- const minutes = Math.round((end - start) / 1000 / 60);
86
- if (minutes < 1) return "<1m";
87
- if (minutes >= 60) return `${Math.round(minutes / 60)}h`;
88
- return `${minutes}m`;
83
+ const start = new Date(createdAt).getTime();
84
+ const end = completedAt ? new Date(completedAt).getTime() : Date.now();
85
+ if (!Number.isFinite(start) || !Number.isFinite(end) || end < start) return "?";
86
+ const minutes = Math.round((end - start) / 1000 / 60);
87
+ if (minutes < 1) return "<1m";
88
+ if (minutes >= 60) return `${Math.round(minutes / 60)}h`;
89
+ return `${minutes}m`;
89
90
  }
90
91
 
91
92
  /**
92
93
  * Build markdown onboarding guide for a team.
93
94
  */
94
95
  export function buildTeamOnboarding(team: string, cwd: string, options: OnboardingOptions = {}): string {
95
- const runs = loadRunSummaries(cwd, { ...options, team });
96
-
97
- const lines: string[] = [];
98
-
99
- // Header
100
- lines.push(`# Team: ${team}`);
101
- lines.push("");
102
- lines.push(`> Multi-agent ${team} team for pi-crew.`);
103
- lines.push("");
104
-
105
- // Overview stats
106
- const completed = runs.filter((r) => r.status === "completed");
107
- const failed = runs.filter((r) => r.status === "failed" || r.status === "cancelled");
108
-
109
- let avgDuration = 0;
110
- if (completed.length > 0) {
111
- const totalMs = completed.reduce((sum, r) => {
112
- const start = new Date(r.createdAt).getTime();
113
- const end = r.completedAt ? new Date(r.completedAt).getTime() : Date.now();
114
- return sum + (end - start);
115
- }, 0);
116
- avgDuration = totalMs / completed.length / 1000 / 60;
117
- }
118
-
119
- lines.push("## Overview");
120
- lines.push("");
121
- lines.push(`| Metric | Value |`);
122
- lines.push(`|--------|-------|`);
123
- lines.push(`| Total runs | ${runs.length} |`);
124
- lines.push(`| Completed | ${completed.length} |`);
125
- lines.push(`| Failed/Cancelled | ${failed.length} |`);
126
- if (avgDuration > 0) {
127
- lines.push(`| Avg duration | ${avgDuration.toFixed(1)} min |`);
128
- }
129
- lines.push("");
130
-
131
- // Past runs table
132
- if (runs.length > 0) {
133
- lines.push("## Past Runs");
134
- lines.push("");
135
- lines.push("| Run | Goal | Duration | Status |");
136
- lines.push("|-----|------|----------|--------|");
137
-
138
- for (const run of runs) {
139
- const duration = formatDuration(run.createdAt, run.completedAt);
140
- const goalPreview = run.goal ? run.goal.slice(0, 40) : "N/A";
141
- const goalSuffix = run.goal && run.goal.length > 40 ? "..." : "";
142
- const status = run.status ?? "unknown";
143
- const statusIcon = status === "completed" ? "✅" : status === "failed" ? "❌" : status === "cancelled" ? "⏹️" : "⚠️";
144
- lines.push(`| \`${run.runId.slice(-8)}\` | ${goalPreview}${goalSuffix} | ${duration} | ${statusIcon} ${status} |`);
145
- }
146
- lines.push("");
147
- }
148
-
149
- // How to run
150
- lines.push("## How to Run");
151
- lines.push("");
152
- lines.push("```bash");
153
- lines.push(`team action='run' team='${team}' goal="<your goal>"`);
154
- lines.push("```");
155
- lines.push("");
156
- lines.push("See `team action='help'` for more options.");
157
- lines.push("");
158
-
159
- // Teams
160
- lines.push("## Available Teams");
161
- lines.push("");
162
- try {
163
- const discovery = discoverTeams(cwd);
164
- const teams = allTeams(discovery);
165
- for (const t of teams) {
166
- lines.push(`- \`${t.name}\` — ${t.description ?? "No description"}`);
167
- }
168
- } catch {
169
- lines.push("- *(team discovery unavailable)*");
170
- }
171
- lines.push("");
172
-
173
- // Footer
174
- lines.push("---");
175
- lines.push("*Generated by pi-crew. For up-to-date info, check recent run history.*");
176
-
177
- return lines.join("\n");
96
+ const runs = loadRunSummaries(cwd, { ...options, team });
97
+
98
+ const lines: string[] = [];
99
+
100
+ // Header
101
+ lines.push(`# Team: ${team}`);
102
+ lines.push("");
103
+ lines.push(`> Multi-agent ${team} team for pi-crew.`);
104
+ lines.push("");
105
+
106
+ // Overview stats
107
+ const completed = runs.filter((r) => r.status === "completed");
108
+ const failed = runs.filter((r) => r.status === "failed" || r.status === "cancelled");
109
+
110
+ let avgDuration = 0;
111
+ if (completed.length > 0) {
112
+ const totalMs = completed.reduce((sum, r) => {
113
+ const start = new Date(r.createdAt).getTime();
114
+ const end = r.completedAt ? new Date(r.completedAt).getTime() : Date.now();
115
+ return sum + (end - start);
116
+ }, 0);
117
+ avgDuration = totalMs / completed.length / 1000 / 60;
118
+ }
119
+
120
+ lines.push("## Overview");
121
+ lines.push("");
122
+ lines.push(`| Metric | Value |`);
123
+ lines.push(`|--------|-------|`);
124
+ lines.push(`| Total runs | ${runs.length} |`);
125
+ lines.push(`| Completed | ${completed.length} |`);
126
+ lines.push(`| Failed/Cancelled | ${failed.length} |`);
127
+ if (avgDuration > 0) {
128
+ lines.push(`| Avg duration | ${avgDuration.toFixed(1)} min |`);
129
+ }
130
+ lines.push("");
131
+
132
+ // Past runs table
133
+ if (runs.length > 0) {
134
+ lines.push("## Past Runs");
135
+ lines.push("");
136
+ lines.push("| Run | Goal | Duration | Status |");
137
+ lines.push("|-----|------|----------|--------|");
138
+
139
+ for (const run of runs) {
140
+ const duration = formatDuration(run.createdAt, run.completedAt);
141
+ const goalPreview = run.goal ? run.goal.slice(0, 40) : "N/A";
142
+ const goalSuffix = run.goal && run.goal.length > 40 ? "..." : "";
143
+ const status = run.status ?? "unknown";
144
+ const statusIcon = status === "completed" ? "✅" : status === "failed" ? "❌" : status === "cancelled" ? "⏹️" : "⚠️";
145
+ lines.push(`| \`${run.runId.slice(-8)}\` | ${goalPreview}${goalSuffix} | ${duration} | ${statusIcon} ${status} |`);
146
+ }
147
+ lines.push("");
148
+ }
149
+
150
+ // How to run
151
+ lines.push("## How to Run");
152
+ lines.push("");
153
+ lines.push("```bash");
154
+ lines.push(`team action='run' team='${team}' goal="<your goal>"`);
155
+ lines.push("```");
156
+ lines.push("");
157
+ lines.push("See `team action='help'` for more options.");
158
+ lines.push("");
159
+
160
+ // Teams
161
+ lines.push("## Available Teams");
162
+ lines.push("");
163
+ try {
164
+ const discovery = discoverTeams(cwd);
165
+ const teams = allTeams(discovery);
166
+ for (const t of teams) {
167
+ lines.push(`- \`${t.name}\` — ${t.description ?? "No description"}`);
168
+ }
169
+ } catch {
170
+ lines.push("- *(team discovery unavailable)*");
171
+ }
172
+ lines.push("");
173
+
174
+ // Footer
175
+ lines.push("---");
176
+ lines.push("*Generated by pi-crew. For up-to-date info, check recent run history.*");
177
+
178
+ return lines.join("\n");
178
179
  }
@@ -1,7 +1,7 @@
1
- import { detectTeamIntent } from "./autonomous-policy.ts";
2
1
  import type { AgentConfig } from "../agents/agent-config.ts";
3
- import type { TeamConfig } from "../teams/team-config.ts";
4
2
  import type { PiTeamsAutonomousConfig } from "../config/config.ts";
3
+ import type { TeamConfig } from "../teams/team-config.ts";
4
+ import { detectTeamIntent } from "./autonomous-policy.ts";
5
5
 
6
6
  export type DecompositionStrategy = "numbered" | "bulleted" | "conjunction" | "atomic";
7
7
 
@@ -18,16 +18,61 @@ export interface TeamRecommendation {
18
18
  async: boolean;
19
19
  workspaceMode: "single" | "worktree";
20
20
  confidence: "low" | "medium" | "high";
21
- decomposition: { strategy: DecompositionStrategy; subtasks: RecommendedSubtask[]; fanout: number };
21
+ decomposition: {
22
+ strategy: DecompositionStrategy;
23
+ subtasks: RecommendedSubtask[];
24
+ fanout: number;
25
+ };
22
26
  reasons: string[];
23
27
  }
24
28
 
25
29
  const REVIEW_TERMS = ["review", "audit", "security", "vulnerability", "diff", "pr", "pull request"];
26
- const RESEARCH_TERMS = ["research", "investigate", "compare", "analyze", "document", "docs", "explain", "architecture", "đọc sâu", "source", "projects"];
30
+ const RESEARCH_TERMS = [
31
+ "research",
32
+ "investigate",
33
+ "compare",
34
+ "analyze",
35
+ "document",
36
+ "docs",
37
+ "explain",
38
+ "architecture",
39
+ "đọc sâu",
40
+ "source",
41
+ "projects",
42
+ ];
27
43
  const PARALLEL_RESEARCH_RE = /(?:đọc sâu|deep read|deep research|source audit|multiple projects|các project|pi-\*|source\/|@source)/i;
28
44
  const FAST_FIX_TERMS = ["quick fix", "fast-fix", "small bug", "typo", "one-line", "minor", "lint"];
29
- const IMPLEMENTATION_TERMS = ["implement", "refactor", "migrate", "feature", "tests", "test", "integration", "upgrade", "build", "create", "add", "fix", "update", "sửa", "thêm", "cập nhật", "kiểm thử"];
30
- const RISKY_TERMS = ["migration", "refactor", "large", "multiple", "parallel", "concurrent", "risky", "critical", "nhiều file", "nhiều task"];
45
+ const IMPLEMENTATION_TERMS = [
46
+ "implement",
47
+ "refactor",
48
+ "migrate",
49
+ "feature",
50
+ "tests",
51
+ "test",
52
+ "integration",
53
+ "upgrade",
54
+ "build",
55
+ "create",
56
+ "add",
57
+ "fix",
58
+ "update",
59
+ "sửa",
60
+ "thêm",
61
+ "cập nhật",
62
+ "kiểm thử",
63
+ ];
64
+ const RISKY_TERMS = [
65
+ "migration",
66
+ "refactor",
67
+ "large",
68
+ "multiple",
69
+ "parallel",
70
+ "concurrent",
71
+ "risky",
72
+ "critical",
73
+ "nhiều file",
74
+ "nhiều task",
75
+ ];
31
76
  const NUMBERED_LINE_RE = /^\s*\d+[.)]\s+(.+)$/;
32
77
  const BULLETED_LINE_RE = /^\s*[-*•]\s+(.+)$/;
33
78
  const CONJUNCTION_SPLIT_RE = /\s+(?:and|,\s*and|,)\s+/i;
@@ -58,8 +103,15 @@ function makeSubtask(text: string): RecommendedSubtask {
58
103
  return { subject, description: text.trim(), role: recommendRole(text) };
59
104
  }
60
105
 
61
- export function decomposeGoal(goal: string): { strategy: DecompositionStrategy; subtasks: RecommendedSubtask[]; fanout: number } {
62
- const lines = goal.split("\n").map((line) => line.trim()).filter(Boolean);
106
+ export function decomposeGoal(goal: string): {
107
+ strategy: DecompositionStrategy;
108
+ subtasks: RecommendedSubtask[];
109
+ fanout: number;
110
+ } {
111
+ const lines = goal
112
+ .split("\n")
113
+ .map((line) => line.trim())
114
+ .filter(Boolean);
63
115
  const fileRefs = goal.match(FILE_REF_RE)?.length ?? 0;
64
116
  const codeSymbols = goal.match(CODE_SYMBOL_RE)?.length ?? 0;
65
117
  const hasParallelKeyword = /\b(?:parallel|concurrently|simultaneously|independently)\b/i.test(goal);
@@ -78,10 +130,17 @@ export function decomposeGoal(goal: string): { strategy: DecompositionStrategy;
78
130
  return { strategy: "bulleted", subtasks, fanout: subtasks.length };
79
131
  }
80
132
  if (lines.length === 1) {
81
- const parts = lines[0].split(CONJUNCTION_SPLIT_RE).map((part) => part.trim()).filter(Boolean);
133
+ const parts = lines[0]
134
+ .split(CONJUNCTION_SPLIT_RE)
135
+ .map((part) => part.trim())
136
+ .filter(Boolean);
82
137
  if (parts.length >= 2) {
83
138
  const subtasks = parts.map((part) => makeSubtask(part));
84
- return { strategy: "conjunction", subtasks, fanout: subtasks.length };
139
+ return {
140
+ strategy: "conjunction",
141
+ subtasks,
142
+ fanout: subtasks.length,
143
+ };
85
144
  }
86
145
  }
87
146
  const subtask = makeSubtask(goal);
@@ -93,7 +152,11 @@ function metadataMatches(goal: string, values: string[] | undefined): string[] {
93
152
  return (values ?? []).filter((value) => lower.includes(value.toLowerCase()));
94
153
  }
95
154
 
96
- export function recommendTeam(goal: string, config: PiTeamsAutonomousConfig = {}, resources?: { teams?: TeamConfig[]; agents?: AgentConfig[] }): TeamRecommendation {
155
+ export function recommendTeam(
156
+ goal: string,
157
+ config: PiTeamsAutonomousConfig = {},
158
+ resources?: { teams?: TeamConfig[]; agents?: AgentConfig[] },
159
+ ): TeamRecommendation {
97
160
  const normalized = goal.toLowerCase();
98
161
  const intents = detectTeamIntent(goal, config);
99
162
  const decomposition = decomposeGoal(goal);
@@ -106,7 +169,10 @@ export function recommendTeam(goal: string, config: PiTeamsAutonomousConfig = {}
106
169
  if (intents.length > 0) reasons.push(`Matched explicit intent keyword(s): ${intents.join(", ")}.`);
107
170
 
108
171
  const metadataTeamMatches = (resources?.teams ?? [])
109
- .map((candidate) => ({ team: candidate, matches: [...metadataMatches(goal, candidate.routing?.triggers), ...metadataMatches(goal, candidate.routing?.useWhen)] }))
172
+ .map((candidate) => ({
173
+ team: candidate,
174
+ matches: [...metadataMatches(goal, candidate.routing?.triggers), ...metadataMatches(goal, candidate.routing?.useWhen)],
175
+ }))
110
176
  .filter((candidate) => candidate.matches.length > 0)
111
177
  .sort((a, b) => b.matches.length - a.matches.length);
112
178
 
@@ -120,13 +186,22 @@ export function recommendTeam(goal: string, config: PiTeamsAutonomousConfig = {}
120
186
  team = metadataTeamMatches[0].team.name as TeamRecommendation["team"];
121
187
  workflow = (metadataTeamMatches[0].team.defaultWorkflow ?? metadataTeamMatches[0].team.name) as TeamRecommendation["workflow"];
122
188
  confidence = "high";
123
- reasons.push(`Matched team routing metadata for '${metadataTeamMatches[0].team.name}': ${metadataTeamMatches[0].matches.join(", ")}.`);
189
+ reasons.push(
190
+ `Matched team routing metadata for '${metadataTeamMatches[0].team.name}': ${metadataTeamMatches[0].matches.join(", ")}.`,
191
+ );
124
192
  } else if (intents.includes("review") || reviewMatches.length >= 2 || normalized.includes("security review")) {
125
193
  team = "review";
126
194
  workflow = "review";
127
195
  confidence = "high";
128
196
  reasons.push(`Review/audit terms detected: ${reviewMatches.join(", ") || "explicit review intent"}.`);
129
- } else if (PARALLEL_RESEARCH_RE.test(goal) || (researchMatches.length >= 2 && (normalized.includes("multiple") || normalized.includes("source") || normalized.includes("project") || normalized.includes("pi-")))) {
197
+ } else if (
198
+ PARALLEL_RESEARCH_RE.test(goal) ||
199
+ (researchMatches.length >= 2 &&
200
+ (normalized.includes("multiple") ||
201
+ normalized.includes("source") ||
202
+ normalized.includes("project") ||
203
+ normalized.includes("pi-")))
204
+ ) {
130
205
  team = "parallel-research";
131
206
  workflow = "parallel-research";
132
207
  confidence = "high";
@@ -145,7 +220,9 @@ export function recommendTeam(goal: string, config: PiTeamsAutonomousConfig = {}
145
220
  team = "implementation";
146
221
  workflow = "implementation";
147
222
  confidence = "high";
148
- reasons.push(`Actionable multi-item task list detected (${decomposition.fanout} bullet${decomposition.fanout === 1 ? "" : "s"}); use coordinated implementation planning.`);
223
+ reasons.push(
224
+ `Actionable multi-item task list detected (${decomposition.fanout} bullet${decomposition.fanout === 1 ? "" : "s"}); use coordinated implementation planning.`,
225
+ );
149
226
  } else if (intents.includes("implementation") || implementationMatches.length > 0) {
150
227
  team = "implementation";
151
228
  workflow = "implementation";
@@ -157,14 +234,26 @@ export function recommendTeam(goal: string, config: PiTeamsAutonomousConfig = {}
157
234
  reasons.push("No strong team-specific intent detected; start with planning/default discovery.");
158
235
  }
159
236
 
160
-
161
- if (decomposition.strategy !== "atomic") reasons.push(`Goal decomposes into ${decomposition.subtasks.length} subtasks using ${decomposition.strategy} parsing.`);
162
- const async = config.preferAsyncForLongTasks === true && (wordCount(goal) > 24 || riskyMatches.length > 0 || implementationMatches.length >= 2 || decomposition.fanout >= 3);
163
- const workspaceMode = config.allowWorktreeSuggestion === false ? "single" : (riskyMatches.length > 0 && team === "implementation" ? "worktree" : "single");
237
+ if (decomposition.strategy !== "atomic")
238
+ reasons.push(`Goal decomposes into ${decomposition.subtasks.length} subtasks using ${decomposition.strategy} parsing.`);
239
+ const async =
240
+ config.preferAsyncForLongTasks === true &&
241
+ (wordCount(goal) > 24 || riskyMatches.length > 0 || implementationMatches.length >= 2 || decomposition.fanout >= 3);
242
+ const workspaceMode =
243
+ config.allowWorktreeSuggestion === false ? "single" : riskyMatches.length > 0 && team === "implementation" ? "worktree" : "single";
164
244
  if (async) reasons.push("Task appears long/risky and config prefers async for long tasks.");
165
245
  if (workspaceMode === "worktree") reasons.push(`Risk/isolation terms detected: ${riskyMatches.join(", ")}.`);
166
246
 
167
- return { team, workflow, action, async, workspaceMode, confidence, decomposition, reasons };
247
+ return {
248
+ team,
249
+ workflow,
250
+ action,
251
+ async,
252
+ workspaceMode,
253
+ confidence,
254
+ decomposition,
255
+ reasons,
256
+ };
168
257
  }
169
258
 
170
259
  export function formatRecommendation(goal: string, recommendation: TeamRecommendation): string {
@@ -183,6 +272,17 @@ export function formatRecommendation(goal: string, recommendation: TeamRecommend
183
272
  "Reasons:",
184
273
  ...recommendation.reasons.map((reason) => `- ${reason}`),
185
274
  "Suggested tool call:",
186
- JSON.stringify({ action: recommendation.action, team: recommendation.team, workflow: recommendation.workflow, goal, async: recommendation.async, workspaceMode: recommendation.workspaceMode }, null, 2),
275
+ JSON.stringify(
276
+ {
277
+ action: recommendation.action,
278
+ team: recommendation.team,
279
+ workflow: recommendation.workflow,
280
+ goal,
281
+ async: recommendation.async,
282
+ workspaceMode: recommendation.workspaceMode,
283
+ },
284
+ null,
285
+ 2,
286
+ ),
187
287
  ].join("\n");
188
288
  }