pi-crew 0.9.15 → 0.9.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (432) hide show
  1. package/CHANGELOG.md +145 -0
  2. package/README.md +19 -0
  3. package/dist/build-meta.json +21790 -0
  4. package/dist/index.mjs +83070 -0
  5. package/dist/index.mjs.map +7 -0
  6. package/docs/A +358 -0
  7. package/docs/M-A +357 -0
  8. package/docs/REVIEW-FINDINGS-2026-06 +357 -0
  9. package/docs/Y +357 -0
  10. package/docs/a +357 -0
  11. package/docs/aA +358 -0
  12. package/docs/archive/README.md +91 -0
  13. package/docs/patterns/command-agent-skill.md +1 -1
  14. package/docs/skills/REFERENCE.md +0 -17
  15. package/docs//303/242mmaAAA/303/242 +357 -0
  16. package/index.bundle.ts +25 -0
  17. package/index.ts +95 -4
  18. package/package.json +15 -4
  19. package/skills/iterative-audit/SKILL.md +0 -1
  20. package/skills/widget-rendering/SKILL.md +17 -0
  21. package/src/adapters/claude-adapter.ts +1 -3
  22. package/src/adapters/export-util.ts +16 -16
  23. package/src/adapters/index.ts +5 -5
  24. package/src/agents/agent-config.ts +20 -14
  25. package/src/agents/agent-serializer.ts +1 -1
  26. package/src/agents/discover-agents.ts +83 -39
  27. package/src/benchmark/benchmark-runner.ts +51 -51
  28. package/src/benchmark/feedback-loop.ts +1 -1
  29. package/src/config/config.ts +166 -590
  30. package/src/config/defaults.ts +28 -2
  31. package/src/config/drift-detector.ts +11 -14
  32. package/src/config/markers.ts +201 -203
  33. package/src/config/resilient-parser.ts +14 -6
  34. package/src/config/role-tools.ts +3 -3
  35. package/src/config/suggestions.ts +5 -12
  36. package/src/config/types.ts +9 -25
  37. package/src/errors.ts +151 -157
  38. package/src/extension/action-suggestions.ts +54 -9
  39. package/src/extension/async-notifier.ts +43 -13
  40. package/src/extension/autonomous-policy.ts +77 -37
  41. package/src/extension/command-completions.ts +9 -8
  42. package/src/extension/context-status-injection.ts +14 -12
  43. package/src/extension/crew-autocomplete.ts +8 -16
  44. package/src/extension/crew-cleanup.ts +2 -1
  45. package/src/extension/crew-shortcuts.ts +9 -6
  46. package/src/extension/cross-extension-rpc.ts +136 -42
  47. package/src/extension/help.ts +1 -1
  48. package/src/extension/import-index.ts +10 -5
  49. package/src/extension/knowledge-injection.ts +88 -15
  50. package/src/extension/management.ts +89 -349
  51. package/src/extension/message-renderers.ts +3 -4
  52. package/src/extension/notification-router.ts +22 -5
  53. package/src/extension/notification-sink.ts +6 -3
  54. package/src/extension/pi-api.ts +17 -8
  55. package/src/extension/plan-orchestrate.ts +8 -27
  56. package/src/extension/project-init.ts +21 -6
  57. package/src/extension/register.ts +329 -975
  58. package/src/extension/registration/artifact-cleanup.ts +9 -4
  59. package/src/extension/registration/command-utils.ts +5 -1
  60. package/src/extension/registration/commands.ts +806 -314
  61. package/src/extension/registration/compaction-guard.ts +15 -15
  62. package/src/extension/registration/lifecycle.ts +259 -0
  63. package/src/extension/registration/observability.ts +293 -0
  64. package/src/extension/registration/subagent-helpers.ts +29 -7
  65. package/src/extension/registration/subagent-tools.ts +253 -44
  66. package/src/extension/registration/team-tool.ts +19 -84
  67. package/src/extension/registration/ui.ts +168 -0
  68. package/src/extension/registration/viewers.ts +64 -24
  69. package/src/extension/result-watcher.ts +18 -7
  70. package/src/extension/run-bundle-schema.ts +21 -6
  71. package/src/extension/run-export.ts +15 -6
  72. package/src/extension/run-import.ts +64 -29
  73. package/src/extension/run-index.ts +28 -9
  74. package/src/extension/run-maintenance.ts +32 -12
  75. package/src/extension/session-summary.ts +1 -1
  76. package/src/extension/team-manager-command.ts +64 -7
  77. package/src/extension/team-onboard.ts +151 -150
  78. package/src/extension/team-recommendation.ts +121 -21
  79. package/src/extension/team-tool/anchor.ts +31 -64
  80. package/src/extension/team-tool/api.ts +929 -141
  81. package/src/extension/team-tool/auto-summarize.ts +14 -26
  82. package/src/extension/team-tool/cache-control.ts +1 -5
  83. package/src/extension/team-tool/cancel.ts +138 -38
  84. package/src/extension/team-tool/chain-dispatch.ts +5 -13
  85. package/src/extension/team-tool/chain-executor.ts +29 -51
  86. package/src/extension/team-tool/config-patch.ts +1 -1
  87. package/src/extension/team-tool/context.ts +40 -20
  88. package/src/extension/team-tool/destructive-gate.ts +10 -5
  89. package/src/extension/team-tool/doctor.ts +170 -51
  90. package/src/extension/team-tool/explain.ts +228 -214
  91. package/src/extension/team-tool/failure-patterns.ts +3 -9
  92. package/src/extension/team-tool/goal-wrap.ts +71 -29
  93. package/src/extension/team-tool/goal.ts +185 -35
  94. package/src/extension/team-tool/handle-schedule.ts +34 -15
  95. package/src/extension/team-tool/handle-settings.ts +94 -56
  96. package/src/extension/team-tool/health-monitor.ts +27 -108
  97. package/src/extension/team-tool/inspect.ts +42 -9
  98. package/src/extension/team-tool/intent-policy.ts +4 -1
  99. package/src/extension/team-tool/lifecycle-actions.ts +244 -48
  100. package/src/extension/team-tool/orchestrate.ts +7 -18
  101. package/src/extension/team-tool/parallel-dispatch.ts +51 -29
  102. package/src/extension/team-tool/plan.ts +29 -5
  103. package/src/extension/team-tool/respond.ts +49 -16
  104. package/src/extension/team-tool/run-not-found.ts +3 -8
  105. package/src/extension/team-tool/run.ts +80 -317
  106. package/src/extension/team-tool/status.ts +135 -43
  107. package/src/extension/team-tool/workflow-manage.ts +92 -25
  108. package/src/extension/team-tool-types.ts +8 -1
  109. package/src/extension/team-tool.ts +142 -551
  110. package/src/extension/validate-resources.ts +39 -8
  111. package/src/hooks/registry.ts +66 -17
  112. package/src/hooks/types.ts +1 -1
  113. package/src/i18n.ts +25 -11
  114. package/src/observability/correlation.ts +17 -3
  115. package/src/observability/event-bus.ts +51 -56
  116. package/src/observability/event-to-metric.ts +117 -15
  117. package/src/observability/exporters/otlp-exporter.ts +56 -17
  118. package/src/observability/exporters/prometheus-exporter.ts +1 -1
  119. package/src/observability/metric-registry.ts +16 -4
  120. package/src/observability/metric-retention.ts +8 -2
  121. package/src/observability/metric-sink.ts +11 -3
  122. package/src/observability/metrics-primitives.ts +42 -9
  123. package/src/plugins/plugin-define.ts +2 -2
  124. package/src/plugins/plugin-registry.ts +25 -25
  125. package/src/plugins/plugins/index.ts +1 -1
  126. package/src/plugins/plugins/nextjs.ts +16 -16
  127. package/src/plugins/plugins/vite.ts +7 -11
  128. package/src/plugins/plugins/vitest.ts +6 -11
  129. package/src/runtime/adaptive-plan.ts +225 -40
  130. package/src/runtime/agent-control.ts +58 -15
  131. package/src/runtime/agent-memory.ts +15 -9
  132. package/src/runtime/agent-observability.ts +10 -2
  133. package/src/runtime/anchor-manager.ts +27 -25
  134. package/src/runtime/async-marker.ts +7 -1
  135. package/src/runtime/async-runner.ts +27 -23
  136. package/src/runtime/auto-summarize.ts +7 -13
  137. package/src/runtime/background-runner.ts +189 -251
  138. package/src/runtime/batch-barrier.ts +18 -16
  139. package/src/runtime/cancellation-token.ts +16 -6
  140. package/src/runtime/cancellation.ts +46 -8
  141. package/src/runtime/capability-inventory.ts +6 -4
  142. package/src/runtime/chain-parser.ts +44 -11
  143. package/src/runtime/chain-runner.ts +63 -69
  144. package/src/runtime/checkpoint.ts +12 -56
  145. package/src/runtime/child-pi.ts +343 -78
  146. package/src/runtime/coalesce-tasks.ts +268 -0
  147. package/src/runtime/code-summary.ts +71 -26
  148. package/src/runtime/compact-stages/index.ts +15 -5
  149. package/src/runtime/compact-stages/tail-capture-stage.ts +7 -2
  150. package/src/runtime/compact-stages/truncation-stage.ts +4 -1
  151. package/src/runtime/compaction-summary.ts +17 -10
  152. package/src/runtime/completion-guard.ts +33 -16
  153. package/src/runtime/crash-classification.ts +28 -7
  154. package/src/runtime/crash-recovery.ts +177 -37
  155. package/src/runtime/crew-agent-records.ts +193 -40
  156. package/src/runtime/crew-hooks.ts +9 -24
  157. package/src/runtime/cross-extension-rpc.ts +25 -23
  158. package/src/runtime/custom-tools/irc-tool.ts +43 -15
  159. package/src/runtime/custom-tools/submit-result-tool.ts +16 -5
  160. package/src/runtime/delivery-coordinator.ts +34 -7
  161. package/src/runtime/delta-conflict.ts +9 -21
  162. package/src/runtime/deterministic-ast.ts +1 -1
  163. package/src/runtime/diagnostic-export.ts +53 -20
  164. package/src/runtime/direct-run.ts +12 -2
  165. package/src/runtime/dwf-state-store.ts +1 -1
  166. package/src/runtime/dynamic-workflow-context.ts +186 -58
  167. package/src/runtime/dynamic-workflow-runner.ts +42 -20
  168. package/src/runtime/effectiveness.ts +16 -8
  169. package/src/runtime/errors/crew-errors.ts +7 -11
  170. package/src/runtime/event-stream-bridge.ts +9 -3
  171. package/src/runtime/foreground-control.ts +54 -14
  172. package/src/runtime/foreground-watchdog.ts +9 -6
  173. package/src/runtime/goal-achievement.ts +27 -10
  174. package/src/runtime/goal-evaluator.ts +54 -19
  175. package/src/runtime/goal-loop-runner.ts +280 -99
  176. package/src/runtime/goal-state-store.ts +27 -17
  177. package/src/runtime/green-contract.ts +11 -2
  178. package/src/runtime/group-join.ts +64 -31
  179. package/src/runtime/handoff-manager.ts +37 -42
  180. package/src/runtime/heartbeat-gradient.ts +10 -2
  181. package/src/runtime/heartbeat-watcher.ts +32 -6
  182. package/src/runtime/hidden-handoff.ts +12 -30
  183. package/src/runtime/important-line-classifier.ts +12 -2
  184. package/src/runtime/iteration-hooks.ts +25 -15
  185. package/src/runtime/live-agent-control.ts +55 -7
  186. package/src/runtime/live-agent-manager.ts +130 -27
  187. package/src/runtime/live-control-realtime.ts +23 -3
  188. package/src/runtime/live-irc.ts +4 -1
  189. package/src/runtime/live-session-health.ts +12 -4
  190. package/src/runtime/live-session-runtime.ts +379 -117
  191. package/src/runtime/manifest-cache.ts +28 -12
  192. package/src/runtime/mcp-proxy.ts +8 -16
  193. package/src/runtime/metric-parser.ts +1 -5
  194. package/src/runtime/model-fallback.ts +55 -18
  195. package/src/runtime/model-resolver.ts +2 -6
  196. package/src/runtime/model-scope.ts +19 -3
  197. package/src/runtime/notebook-helpers.ts +60 -62
  198. package/src/runtime/orphan-worker-registry.ts +37 -26
  199. package/src/runtime/output-validator.ts +18 -3
  200. package/src/runtime/overflow-recovery.ts +5 -4
  201. package/src/runtime/parallel-research.ts +29 -5
  202. package/src/runtime/parallel-utils.ts +9 -11
  203. package/src/runtime/path-overlap.ts +150 -0
  204. package/src/runtime/peer-dep.ts +12 -17
  205. package/src/runtime/per-write-validator.ts +1 -3
  206. package/src/runtime/phase-tracker.ts +342 -330
  207. package/src/runtime/pi-args.ts +26 -8
  208. package/src/runtime/pi-json-output.ts +1 -1
  209. package/src/runtime/pi-spawn.ts +30 -19
  210. package/src/runtime/pipeline-runner.ts +56 -55
  211. package/src/runtime/plan-templates.ts +5 -6
  212. package/src/runtime/policy-engine.ts +43 -7
  213. package/src/runtime/post-checks.ts +12 -4
  214. package/src/runtime/post-exit-stdio-guard.ts +2 -2
  215. package/src/runtime/process-lifecycle.ts +20 -10
  216. package/src/runtime/process-status.ts +16 -5
  217. package/src/runtime/progress-event-coalescer.ts +2 -1
  218. package/src/runtime/progress-tracker.ts +103 -103
  219. package/src/runtime/prose-compressor.ts +9 -11
  220. package/src/runtime/recovery-recipes.ts +118 -24
  221. package/src/runtime/replace.ts +25 -10
  222. package/src/runtime/resilient-edit.ts +10 -25
  223. package/src/runtime/result-extractor.ts +1 -2
  224. package/src/runtime/retry-executor.ts +20 -4
  225. package/src/runtime/retry-runner.ts +26 -50
  226. package/src/runtime/role-permission.ts +6 -1
  227. package/src/runtime/run-coalesced-task-group.ts +256 -0
  228. package/src/runtime/run-drift.ts +14 -15
  229. package/src/runtime/run-tracker.ts +6 -28
  230. package/src/runtime/runtime-policy.ts +1 -6
  231. package/src/runtime/runtime-resolver.ts +80 -15
  232. package/src/runtime/scheduler.ts +47 -18
  233. package/src/runtime/semaphore.ts +5 -7
  234. package/src/runtime/sensitive-paths.ts +2 -1
  235. package/src/runtime/session-usage.ts +1 -1
  236. package/src/runtime/settings-store.ts +16 -12
  237. package/src/runtime/sidechain-output.ts +6 -2
  238. package/src/runtime/single-agent-compose.ts +1 -4
  239. package/src/runtime/skill-effectiveness.ts +29 -97
  240. package/src/runtime/skill-instructions.ts +40 -83
  241. package/src/runtime/stale-reconciler.ts +73 -197
  242. package/src/runtime/stream-preview.ts +1 -1
  243. package/src/runtime/streaming-output.ts +1 -1
  244. package/src/runtime/subagent-manager.ts +86 -169
  245. package/src/runtime/subprocess-tool-registry.ts +4 -1
  246. package/src/runtime/supervisor-contact.ts +10 -5
  247. package/src/runtime/task-display.ts +19 -5
  248. package/src/runtime/task-graph-scheduler.ts +95 -21
  249. package/src/runtime/task-graph.ts +5 -11
  250. package/src/runtime/task-health.ts +54 -47
  251. package/src/runtime/task-id.ts +11 -18
  252. package/src/runtime/task-output-context.ts +265 -81
  253. package/src/runtime/task-packet.ts +12 -20
  254. package/src/runtime/task-quality.ts +6 -14
  255. package/src/runtime/task-runner/context-retrieval.ts +4 -13
  256. package/src/runtime/task-runner/live-executor.ts +114 -36
  257. package/src/runtime/task-runner/output-splitter.ts +152 -0
  258. package/src/runtime/task-runner/progress.ts +50 -12
  259. package/src/runtime/task-runner/prompt-builder.ts +31 -7
  260. package/src/runtime/task-runner/prompt-pipeline.ts +31 -7
  261. package/src/runtime/task-runner/result-utils.ts +3 -1
  262. package/src/runtime/task-runner/retrieval-orchestrator.ts +310 -0
  263. package/src/runtime/task-runner/run-projection.ts +27 -8
  264. package/src/runtime/task-runner/state-helpers.ts +29 -8
  265. package/src/runtime/task-runner/tail-read.ts +2 -6
  266. package/src/runtime/task-runner.ts +180 -326
  267. package/src/runtime/team-runner-artifacts.ts +13 -0
  268. package/src/runtime/team-runner.ts +456 -974
  269. package/src/runtime/tool-output-pruner.ts +6 -9
  270. package/src/runtime/tool-progress.ts +11 -21
  271. package/src/runtime/verification-gates.ts +33 -24
  272. package/src/runtime/verification-integrity.ts +1 -4
  273. package/src/runtime/verification-worktree.ts +62 -12
  274. package/src/runtime/worker-heartbeat.ts +5 -1
  275. package/src/runtime/worker-startup.ts +29 -5
  276. package/src/runtime/workflow-state.ts +17 -9
  277. package/src/runtime/workspace-lock.ts +30 -35
  278. package/src/runtime/workspace-tree.ts +20 -32
  279. package/src/runtime/yield-handler.ts +43 -9
  280. package/src/runtime/zombie-scanner.ts +5 -4
  281. package/src/schema/config-schema.ts +266 -172
  282. package/src/schema/team-tool-schema.ts +29 -74
  283. package/src/schema/validation-types.ts +25 -17
  284. package/src/skills/discover-skills.ts +35 -10
  285. package/src/skills/skill-templates.ts +109 -27
  286. package/src/skills/validate.ts +26 -8
  287. package/src/state/active-run-registry.ts +87 -28
  288. package/src/state/artifact-store.ts +9 -5
  289. package/src/state/atomic-write-v2.ts +85 -63
  290. package/src/state/atomic-write.ts +105 -26
  291. package/src/state/blob-store.ts +47 -20
  292. package/src/state/contracts.ts +20 -5
  293. package/src/state/crew-init.ts +5 -22
  294. package/src/state/decision-ledger.ts +19 -73
  295. package/src/state/event-log-rotation.ts +41 -15
  296. package/src/state/event-log.ts +168 -53
  297. package/src/state/event-reconstructor.ts +11 -1
  298. package/src/state/gitignore-manager.ts +2 -8
  299. package/src/state/health-store.ts +57 -57
  300. package/src/state/hook-instinct-bridge.ts +1 -1
  301. package/src/state/hook-integrations.ts +1 -1
  302. package/src/state/instinct-store.ts +17 -5
  303. package/src/state/jsonl-writer.ts +1 -1
  304. package/src/state/locks.ts +23 -9
  305. package/src/state/mailbox.ts +151 -28
  306. package/src/state/observation-store.ts +20 -14
  307. package/src/state/run-cache.ts +142 -135
  308. package/src/state/run-graph.ts +6 -15
  309. package/src/state/run-metrics.ts +5 -18
  310. package/src/state/schedule.ts +15 -9
  311. package/src/state/state-store.ts +129 -45
  312. package/src/state/task-claims.ts +12 -2
  313. package/src/state/tiered-eval.ts +52 -43
  314. package/src/state/types-eval.ts +2 -2
  315. package/src/state/types.ts +24 -20
  316. package/src/state/usage.ts +20 -4
  317. package/src/state/worker-atomic-writer.ts +6 -3
  318. package/src/subagents/index.ts +2 -2
  319. package/src/teams/discover-teams.ts +21 -6
  320. package/src/tools/safe-bash-extension.ts +5 -6
  321. package/src/tools/safe-bash.ts +10 -11
  322. package/src/types/new-api-types.ts +6 -10
  323. package/src/ui/agent-management-overlay.ts +52 -40
  324. package/src/ui/card-colors.ts +13 -4
  325. package/src/ui/crew-footer.ts +8 -7
  326. package/src/ui/crew-select-list.ts +1 -1
  327. package/src/ui/dashboard-panes/agents-pane.ts +41 -25
  328. package/src/ui/dashboard-panes/cancellation-pane.ts +1 -1
  329. package/src/ui/dashboard-panes/capability-pane.ts +32 -15
  330. package/src/ui/dashboard-panes/health-pane.ts +2 -1
  331. package/src/ui/dashboard-panes/metrics-pane.ts +4 -1
  332. package/src/ui/dashboard-panes/progress-pane.ts +12 -9
  333. package/src/ui/heartbeat-aggregator.ts +15 -4
  334. package/src/ui/keybinding-map.ts +40 -7
  335. package/src/ui/live-conversation-overlay.ts +36 -20
  336. package/src/ui/live-duration.ts +1 -4
  337. package/src/ui/live-run-sidebar.ts +88 -25
  338. package/src/ui/loaders.ts +2 -8
  339. package/src/ui/mascot.ts +20 -36
  340. package/src/ui/overlays/agent-picker-overlay.ts +11 -3
  341. package/src/ui/overlays/confirm-overlay.ts +4 -2
  342. package/src/ui/overlays/help-overlay.ts +25 -14
  343. package/src/ui/overlays/mailbox-compose-overlay.ts +48 -11
  344. package/src/ui/overlays/mailbox-compose-preview.ts +20 -5
  345. package/src/ui/overlays/mailbox-detail-overlay.ts +27 -6
  346. package/src/ui/pi-ui-compat.ts +7 -7
  347. package/src/ui/powerbar-publisher.ts +120 -42
  348. package/src/ui/render-diff.ts +10 -3
  349. package/src/ui/render-scheduler.ts +12 -4
  350. package/src/ui/run-action-dispatcher.ts +81 -18
  351. package/src/ui/run-dashboard.ts +172 -76
  352. package/src/ui/run-event-bus.ts +59 -37
  353. package/src/ui/run-snapshot-cache.ts +276 -86
  354. package/src/ui/settings-overlay.ts +361 -74
  355. package/src/ui/status-colors.ts +12 -1
  356. package/src/ui/syntax-highlight.ts +1 -1
  357. package/src/ui/theme-adapter.ts +16 -14
  358. package/src/ui/theme-discovery.ts +13 -2
  359. package/src/ui/tool-progress-formatter.ts +7 -7
  360. package/src/ui/tool-render.ts +128 -56
  361. package/src/ui/tool-renderers/brief-mode.ts +45 -27
  362. package/src/ui/tool-renderers/index.ts +109 -43
  363. package/src/ui/transcript-cache.ts +32 -6
  364. package/src/ui/transcript-entries.ts +25 -23
  365. package/src/ui/transcript-viewer.ts +78 -29
  366. package/src/ui/widget/index.ts +99 -40
  367. package/src/ui/widget/widget-formatters.ts +13 -6
  368. package/src/ui/widget/widget-model.ts +19 -8
  369. package/src/ui/widget/widget-renderer.ts +23 -13
  370. package/src/ui/widget/widget-types.ts +1 -1
  371. package/src/utils/bm25-search.ts +199 -199
  372. package/src/utils/conflict-detect.ts +22 -21
  373. package/src/utils/env-filter.ts +14 -7
  374. package/src/utils/file-coalescer.ts +5 -1
  375. package/src/utils/fingerprint.ts +3 -6
  376. package/src/utils/frontmatter.ts +3 -1
  377. package/src/utils/fs-watch.ts +2 -6
  378. package/src/utils/gh-protocol.ts +119 -44
  379. package/src/utils/git.ts +13 -15
  380. package/src/utils/guards.ts +2 -5
  381. package/src/utils/ids.ts +9 -2
  382. package/src/utils/incremental-reader.ts +14 -3
  383. package/src/utils/internal-error.ts +2 -1
  384. package/src/utils/names.ts +12 -3
  385. package/src/utils/paths.ts +49 -5
  386. package/src/utils/project-detector.ts +2 -2
  387. package/src/utils/redaction.ts +29 -19
  388. package/src/utils/resolve-shell.ts +9 -7
  389. package/src/utils/run-watcher-registry.ts +19 -31
  390. package/src/utils/safe-paths.ts +45 -24
  391. package/src/utils/scan-cache.ts +9 -2
  392. package/src/utils/session-utils.ts +2 -4
  393. package/src/utils/sleep.ts +12 -5
  394. package/src/utils/sse-parser.ts +5 -17
  395. package/src/utils/visual.ts +52 -32
  396. package/src/workflows/discover-workflows.ts +41 -109
  397. package/src/workflows/intermediate-store.ts +5 -21
  398. package/src/workflows/preflight-validator.ts +6 -33
  399. package/src/workflows/topology-analyzer.ts +5 -21
  400. package/src/workflows/workflow-config.ts +7 -6
  401. package/src/worktree/branch-freshness.ts +66 -8
  402. package/src/worktree/cleanup.ts +130 -20
  403. package/src/worktree/worktree-manager.ts +212 -69
  404. package/skills/artifact-analysis-loop/SKILL.md +0 -303
  405. package/skills/detection-pipeline-design/SKILL.md +0 -286
  406. package/skills/hunting-investigation-loop/SKILL.md +0 -402
  407. package/skills/incident-playbook-construction/SKILL.md +0 -384
  408. package/skills/security-review/SKILL.md +0 -561
  409. package/skills/threat-hypothesis-framework/SKILL.md +0 -176
  410. package/skills/ui-render-performance/SKILL.md +0 -58
  411. /package/docs/{followup-review-round3-2026-05-12.md → archive/followup-review-round3-2026-05-12.md} +0 -0
  412. /package/docs/{followup-review-round4-2026-05-13.md → archive/followup-review-round4-2026-05-13.md} +0 -0
  413. /package/docs/{pi-crew-bugs.md → archive/pi-crew-bugs.md} +0 -0
  414. /package/docs/{pi-crew-test-final.md → archive/pi-crew-test-final.md} +0 -0
  415. /package/docs/{pi-crew-test-results.md → archive/pi-crew-test-results.md} +0 -0
  416. /package/docs/{pi-crew-test-round2.md → archive/pi-crew-test-round2.md} +0 -0
  417. /package/docs/{pi-crew-test-round4.md → archive/pi-crew-test-round4.md} +0 -0
  418. /package/docs/{pi-crew-test-round5.md → archive/pi-crew-test-round5.md} +0 -0
  419. /package/docs/{pi-crew-test-round6.md → archive/pi-crew-test-round6.md} +0 -0
  420. /package/docs/{pi-crew-v0.5.10-audit-fix-plan.md → archive/pi-crew-v0.5.10-audit-fix-plan.md} +0 -0
  421. /package/docs/{pi-crew-v0.5.11-audit-fix-plan.md → archive/pi-crew-v0.5.11-audit-fix-plan.md} +0 -0
  422. /package/docs/{pi-crew-v0.5.12-audit-fix-plan.md → archive/pi-crew-v0.5.12-audit-fix-plan.md} +0 -0
  423. /package/docs/{pi-crew-v0.5.13-audit-fix-plan.md → archive/pi-crew-v0.5.13-audit-fix-plan.md} +0 -0
  424. /package/docs/{pi-crew-v0.5.14-audit-fix-plan.md → archive/pi-crew-v0.5.14-audit-fix-plan.md} +0 -0
  425. /package/docs/{pi-crew-v0.5.16-audit-fix-plan.md → archive/pi-crew-v0.5.16-audit-fix-plan.md} +0 -0
  426. /package/docs/{pi-crew-v0.5.17-audit-fix-plan.md → archive/pi-crew-v0.5.17-audit-fix-plan.md} +0 -0
  427. /package/docs/{pi-crew-v0.5.5-audit-fix-plan.md → archive/pi-crew-v0.5.5-audit-fix-plan.md} +0 -0
  428. /package/docs/{pi-crew-v0.5.9-audit-fix-plan.md → archive/pi-crew-v0.5.9-audit-fix-plan.md} +0 -0
  429. /package/docs/{pi-mono-opportunities.md → archive/pi-mono-opportunities.md} +0 -0
  430. /package/docs/{pi-mono-review.md → archive/pi-mono-review.md} +0 -0
  431. /package/docs/{pi-subagent4-comparison.md → archive/pi-subagent4-comparison.md} +0 -0
  432. /package/docs/{pi-subagents3-deep-analysis.md → archive/pi-subagents3-deep-analysis.md} +0 -0
@@ -1,18 +1,8 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import type { AgentConfig } from "../agents/agent-config.ts";
4
- import {
5
- allAgents,
6
- discoverAgents,
7
- listDynamicAgents,
8
- registerDynamicAgent,
9
- unregisterDynamicAgent,
10
- } from "../agents/discover-agents.ts";
11
- import {
12
- loadConfig,
13
- updateAutonomousConfig,
14
- updateConfig,
15
- } from "../config/config.ts";
4
+ import { allAgents, discoverAgents, listDynamicAgents, registerDynamicAgent, unregisterDynamicAgent } from "../agents/discover-agents.ts";
5
+ import { loadConfig, updateAutonomousConfig, updateConfig } from "../config/config.ts";
16
6
  // Heavy runtime — lazy-loaded to avoid 1.4s import cost at extension registration.
17
7
  // executeTeamRun is only called when a team run actually executes.
18
8
  import type { executeTeamRun as _executeTeamRunFn } from "../runtime/team-runner.ts";
@@ -21,23 +11,11 @@ import { writeArtifact } from "../state/artifact-store.ts";
21
11
  import { appendEvent, appendEventFireAndForget } from "../state/event-log.ts";
22
12
  import { withRunLock } from "../state/locks.ts";
23
13
  import { replayPendingMailboxMessages } from "../state/mailbox.ts";
24
- import {
25
- loadRunManifestById,
26
- saveRunManifest,
27
- saveRunTasks,
28
- updateRunStatus,
29
- } from "../state/state-store.ts";
30
- import type {
31
- ArtifactDescriptor,
32
- TeamRunManifest,
33
- TeamTaskState,
34
- } from "../state/types.ts";
14
+ import { loadRunManifestById, saveRunManifest, saveRunTasks, updateRunStatus } from "../state/state-store.ts";
15
+ import type { ArtifactDescriptor, TeamRunManifest, TeamTaskState } from "../state/types.ts";
35
16
  import { allTeams, discoverTeams } from "../teams/discover-teams.ts";
36
17
  import { assertSafePathId } from "../utils/safe-paths.ts";
37
- import {
38
- allWorkflows,
39
- discoverWorkflows,
40
- } from "../workflows/discover-workflows.ts";
18
+ import { allWorkflows, discoverWorkflows } from "../workflows/discover-workflows.ts";
41
19
  import { piTeamsHelp } from "./help.ts";
42
20
  import { handleCreate, handleDelete, handleUpdate } from "./management.ts";
43
21
  import { initializeProject } from "./project-init.ts";
@@ -45,16 +23,11 @@ import { listRuns } from "./run-index.ts";
45
23
  import { formatRecommendation, recommendTeam } from "./team-recommendation.ts";
46
24
  import { handleSettings } from "./team-tool/handle-settings.ts";
47
25
  import type { PiTeamsToolResult } from "./tool-result.ts";
48
- import {
49
- formatValidationReport,
50
- validateResources,
51
- } from "./validate-resources.ts";
26
+ import { formatValidationReport, validateResources } from "./validate-resources.ts";
52
27
 
53
28
  type ExecuteTeamRunFn = typeof _executeTeamRunFn;
54
29
  let _cachedExecuteTeamRun: ExecuteTeamRunFn | undefined;
55
- async function executeTeamRun(
56
- ...args: Parameters<ExecuteTeamRunFn>
57
- ): Promise<Awaited<ReturnType<ExecuteTeamRunFn>>> {
30
+ async function executeTeamRun(...args: Parameters<ExecuteTeamRunFn>): Promise<Awaited<ReturnType<ExecuteTeamRunFn>>> {
58
31
  if (_cachedExecuteTeamRun === undefined) {
59
32
  // LAZY: heavy runtime — defer 1.4s import cost until team run actually executes.
60
33
  const mod = await import("../runtime/team-runner.ts");
@@ -65,33 +38,17 @@ async function executeTeamRun(
65
38
 
66
39
  import { directTeamAndWorkflowFromRun } from "../runtime/direct-run.ts";
67
40
  import { parsePiJsonOutput } from "../runtime/pi-json-output.ts";
68
- import {
69
- resolveCrewRuntime,
70
- runtimeResolutionState,
71
- } from "../runtime/runtime-resolver.ts";
41
+ import { resolveCrewRuntime, runtimeResolutionState } from "../runtime/runtime-resolver.ts";
72
42
  import { handleApi } from "./team-tool/api.ts";
73
- import {
74
- autonomousPatchFromConfig,
75
- configPatchFromConfig,
76
- effectiveRunConfig,
77
- formatAutonomyStatus,
78
- } from "./team-tool/config-patch.ts";
79
- import {
80
- buildParentContext,
81
- configRecord,
82
- formatScoped,
83
- result,
84
- type TeamContext,
85
- } from "./team-tool/context.ts";
43
+ import { autonomousPatchFromConfig, configPatchFromConfig, effectiveRunConfig, formatAutonomyStatus } from "./team-tool/config-patch.ts";
44
+ import { buildParentContext, configRecord, formatScoped, result, type TeamContext } from "./team-tool/context.ts";
86
45
  // Lazy-loaded: run.ts pulls in spawnBackgroundTeamRun, resolveCrewRuntime, etc.
87
46
  // Static import fails silently in some jiti contexts (child-process), leaving handleRun undefined.
88
47
  import type { handleRun as _handleRunFn } from "./team-tool/run.ts";
89
48
 
90
49
  type HandleRunFn = typeof _handleRunFn;
91
50
  let _cachedHandleRun: HandleRunFn | undefined;
92
- async function handleRun(
93
- ...args: Parameters<HandleRunFn>
94
- ): Promise<Awaited<ReturnType<HandleRunFn>>> {
51
+ async function handleRun(...args: Parameters<HandleRunFn>): Promise<Awaited<ReturnType<HandleRunFn>>> {
95
52
  if (_cachedHandleRun === undefined) {
96
53
  // LAZY: run.ts pulls in spawnBackgroundTeamRun + resolveCrewRuntime; also avoids jiti import race in child-process contexts.
97
54
  const mod = await import("./team-tool/run.ts");
@@ -103,21 +60,13 @@ async function handleRun(
103
60
  import { FileCheckpointStore } from "../runtime/checkpoint.ts";
104
61
  import { waitForRun } from "../runtime/run-tracker.ts";
105
62
  import { normalizeSkillOverride } from "../runtime/skill-instructions.ts";
106
- import {
107
- computeRunCacheKey,
108
- getCachedRun,
109
- getCacheStats,
110
- } from "../state/run-cache.ts";
63
+ import { computeRunCacheKey, getCachedRun, getCacheStats } from "../state/run-cache.ts";
111
64
  import { listRunGraphs, loadRunGraph } from "../state/run-graph.ts";
112
65
  import { searchAgents, searchTeams } from "../utils/bm25-search.ts";
113
66
  import { projectCrewRoot } from "../utils/paths.ts";
67
+ import { formatActionSuggestion } from "./action-suggestions.ts";
114
68
  import { buildTeamOnboarding } from "./team-onboard.ts";
115
- import {
116
- handleAnchorAccumulate,
117
- handleAnchorClear,
118
- handleAnchorSet,
119
- handleAnchorStatus,
120
- } from "./team-tool/anchor.ts";
69
+ import { handleAnchorAccumulate, handleAnchorClear, handleAnchorSet, handleAnchorStatus } from "./team-tool/anchor.ts";
121
70
  import {
122
71
  createAutoSummarizeService,
123
72
  handleAutoSummarizeConfig,
@@ -125,31 +74,14 @@ import {
125
74
  handleAutoSummarizeOn,
126
75
  handleAutoSummarizeStatus,
127
76
  } from "./team-tool/auto-summarize.ts";
128
- import { handleGoal } from "./team-tool/goal.ts";
129
- import {
130
- handleWorkflowCreate,
131
- handleWorkflowGet,
132
- handleWorkflowList,
133
- handleWorkflowSave,
134
- handleWorkflowDelete,
135
- } from "./team-tool/workflow-manage.ts";
136
- import {
137
- type CacheControlDeps,
138
- invalidateSnapshot,
139
- } from "./team-tool/cache-control.ts";
77
+ import { type CacheControlDeps, invalidateSnapshot } from "./team-tool/cache-control.ts";
140
78
  import { handleCancel, handleRetry } from "./team-tool/cancel.ts";
141
79
  import { handleDoctor } from "./team-tool/doctor.ts";
142
80
  import { handleExplain } from "./team-tool/explain.ts";
143
- import {
144
- handleListScheduled,
145
- handleSchedule,
146
- } from "./team-tool/handle-schedule.ts";
81
+ import { handleGoal } from "./team-tool/goal.ts";
82
+ import { handleListScheduled, handleSchedule } from "./team-tool/handle-schedule.ts";
147
83
  import { handleHealthMonitor } from "./team-tool/health-monitor.ts";
148
- import {
149
- handleArtifacts,
150
- handleEvents,
151
- handleSummary,
152
- } from "./team-tool/inspect.ts";
84
+ import { handleArtifacts, handleEvents, handleSummary } from "./team-tool/inspect.ts";
153
85
  import {
154
86
  handleCleanup,
155
87
  handleExport,
@@ -163,9 +95,15 @@ import { handleOrchestrate } from "./team-tool/orchestrate.ts";
163
95
  import { handleParallel } from "./team-tool/parallel-dispatch.ts";
164
96
  import { handlePlan } from "./team-tool/plan.ts";
165
97
  import { handleRespond } from "./team-tool/respond.ts";
166
- import { handleStatus } from "./team-tool/status.ts";
167
98
  import { RUN_NOT_FOUND_HINT } from "./team-tool/run-not-found.ts";
168
- import { formatActionSuggestion } from "./action-suggestions.ts";
99
+ import { handleStatus } from "./team-tool/status.ts";
100
+ import {
101
+ handleWorkflowCreate,
102
+ handleWorkflowDelete,
103
+ handleWorkflowGet,
104
+ handleWorkflowList,
105
+ handleWorkflowSave,
106
+ } from "./team-tool/workflow-manage.ts";
169
107
 
170
108
  export { handleApi } from "./team-tool/api.ts";
171
109
  export { handleRetry } from "./team-tool/cancel.ts";
@@ -192,21 +130,14 @@ export { handleStatus } from "./team-tool/status.ts";
192
130
  export type { TeamToolDetails } from "./team-tool-types.ts";
193
131
  export { handleRun };
194
132
 
195
- export function handleList(
196
- params: TeamToolParamsValue,
197
- ctx: TeamContext,
198
- ): PiTeamsToolResult {
133
+ export function handleList(params: TeamToolParamsValue, ctx: TeamContext): PiTeamsToolResult {
199
134
  const resource = params.resource;
200
135
  const blocks: string[] = [];
201
136
  if (!resource || resource === "team") {
202
137
  const teams = allTeams(discoverTeams(ctx.cwd));
203
138
  blocks.push(
204
139
  "Teams:",
205
- ...(teams.length
206
- ? teams.map((team) =>
207
- formatScoped(team.name, team.source, team.description),
208
- )
209
- : ["- (none)"]),
140
+ ...(teams.length ? teams.map((team) => formatScoped(team.name, team.source, team.description)) : ["- (none)"]),
210
141
  );
211
142
  }
212
143
  if (!resource || resource === "workflow") {
@@ -215,13 +146,7 @@ export function handleList(
215
146
  "",
216
147
  "Workflows:",
217
148
  ...(workflows.length
218
- ? workflows.map((workflow) =>
219
- formatScoped(
220
- workflow.name,
221
- workflow.source,
222
- workflow.description,
223
- ),
224
- )
149
+ ? workflows.map((workflow) => formatScoped(workflow.name, workflow.source, workflow.description))
225
150
  : ["- (none)"]),
226
151
  );
227
152
  }
@@ -230,15 +155,7 @@ export function handleList(
230
155
  blocks.push(
231
156
  "",
232
157
  "Agents:",
233
- ...(agents.length
234
- ? agents.map((agent) =>
235
- formatScoped(
236
- agent.name,
237
- agent.source,
238
- agent.description,
239
- ),
240
- )
241
- : ["- (none)"]),
158
+ ...(agents.length ? agents.map((agent) => formatScoped(agent.name, agent.source, agent.description)) : ["- (none)"]),
242
159
  );
243
160
  }
244
161
  if (!resource) {
@@ -247,30 +164,17 @@ export function handleList(
247
164
  "",
248
165
  "Recent runs:",
249
166
  ...(runs.length
250
- ? runs.map(
251
- (run) =>
252
- `- ${run.runId} [${run.status}] ${run.team}/${run.workflow ?? "none"}: ${run.goal}`,
253
- )
167
+ ? runs.map((run) => `- ${run.runId} [${run.status}] ${run.team}/${run.workflow ?? "none"}: ${run.goal}`)
254
168
  : ["- (none)"]),
255
169
  );
256
170
  }
257
171
  return result(blocks.join("\n"), { action: "list", status: "ok" });
258
172
  }
259
173
 
260
- export function handleGet(
261
- params: TeamToolParamsValue,
262
- ctx: TeamContext,
263
- ): PiTeamsToolResult {
174
+ export function handleGet(params: TeamToolParamsValue, ctx: TeamContext): PiTeamsToolResult {
264
175
  if (params.team) {
265
- const team = allTeams(discoverTeams(ctx.cwd)).find(
266
- (item) => item.name === params.team,
267
- );
268
- if (!team)
269
- return result(
270
- `Team '${params.team}' not found.`,
271
- { action: "get", status: "error" },
272
- true,
273
- );
176
+ const team = allTeams(discoverTeams(ctx.cwd)).find((item) => item.name === params.team);
177
+ if (!team) return result(`Team '${params.team}' not found.`, { action: "get", status: "error" }, true);
274
178
  const lines = [
275
179
  `Team: ${team.name} (${team.source})`,
276
180
  `Path: ${team.filePath}`,
@@ -279,66 +183,40 @@ export function handleGet(
279
183
  `Workspace mode: ${team.workspaceMode ?? "single"}`,
280
184
  "Roles:",
281
185
  ...(team.roles.length
282
- ? team.roles.map(
283
- (role) =>
284
- `- ${role.name} -> ${role.agent}${role.description ? `: ${role.description}` : ""}`,
285
- )
186
+ ? team.roles.map((role) => `- ${role.name} -> ${role.agent}${role.description ? `: ${role.description}` : ""}`)
286
187
  : ["- (none)"]),
287
188
  ];
288
189
  return result(lines.join("\n"), { action: "get", status: "ok" });
289
190
  }
290
191
  if (params.workflow) {
291
- const workflow = allWorkflows(discoverWorkflows(ctx.cwd)).find(
292
- (item) => item.name === params.workflow,
293
- );
294
- if (!workflow)
295
- return result(
296
- `Workflow '${params.workflow}' not found.`,
297
- { action: "get", status: "error" },
298
- true,
299
- );
192
+ const workflow = allWorkflows(discoverWorkflows(ctx.cwd)).find((item) => item.name === params.workflow);
193
+ if (!workflow) return result(`Workflow '${params.workflow}' not found.`, { action: "get", status: "error" }, true);
300
194
  const lines = [
301
195
  `Workflow: ${workflow.name} (${workflow.source})`,
302
196
  `Path: ${workflow.filePath}`,
303
197
  `Description: ${workflow.description}`,
304
198
  "Steps:",
305
199
  ...(workflow.steps.length
306
- ? workflow.steps.map(
307
- (step) =>
308
- `- ${step.id} [${step.role}] dependsOn=${step.dependsOn?.join(",") ?? "none"}`,
309
- )
200
+ ? workflow.steps.map((step) => `- ${step.id} [${step.role}] dependsOn=${step.dependsOn?.join(",") ?? "none"}`)
310
201
  : ["- (none)"]),
311
202
  ];
312
203
  return result(lines.join("\n"), { action: "get", status: "ok" });
313
204
  }
314
205
  if (params.agent) {
315
- const agent = allAgents(discoverAgents(ctx.cwd)).find(
316
- (item) => item.name === params.agent,
317
- );
318
- if (!agent)
319
- return result(
320
- `Agent '${params.agent}' not found.`,
321
- { action: "get", status: "error" },
322
- true,
323
- );
206
+ const agent = allAgents(discoverAgents(ctx.cwd)).find((item) => item.name === params.agent);
207
+ if (!agent) return result(`Agent '${params.agent}' not found.`, { action: "get", status: "error" }, true);
324
208
  const lines = [
325
209
  `Agent: ${agent.name} (${agent.source})`,
326
210
  `Path: ${agent.filePath}`,
327
211
  `Description: ${agent.description}`,
328
212
  agent.model ? `Model: ${agent.model}` : undefined,
329
- agent.skills?.length
330
- ? `Skills: ${agent.skills.join(", ")}`
331
- : undefined,
213
+ agent.skills?.length ? `Skills: ${agent.skills.join(", ")}` : undefined,
332
214
  "",
333
215
  agent.systemPrompt || "(empty system prompt)",
334
216
  ].filter((line): line is string => line !== undefined);
335
217
  return result(lines.join("\n"), { action: "get", status: "ok" });
336
218
  }
337
- return result(
338
- "Specify team, workflow, or agent for get.",
339
- { action: "get", status: "error" },
340
- true,
341
- );
219
+ return result("Specify team, workflow, or agent for get.", { action: "get", status: "error" }, true);
342
220
  }
343
221
 
344
222
  function artifactKey(artifact: ArtifactDescriptor): string {
@@ -353,10 +231,7 @@ function recoverCheckpointedTasks(
353
231
  let nextManifest = manifest;
354
232
  const nextTasks = tasks.map((task) => {
355
233
  if (task.status !== "running" || !task.checkpoint) return task;
356
- if (
357
- task.checkpoint.phase === "artifact-written" &&
358
- task.resultArtifact
359
- ) {
234
+ if (task.checkpoint.phase === "artifact-written" && task.resultArtifact) {
360
235
  recovered.push(task.id);
361
236
  return {
362
237
  ...task,
@@ -368,28 +243,15 @@ function recoverCheckpointedTasks(
368
243
  }
369
244
  if (task.checkpoint.phase === "child-stdout-final") {
370
245
  // transcripts are written with .attempt-${i}.jsonl suffix; find the most recent one
371
- const transcriptsDir = path.join(
372
- manifest.artifactsRoot,
373
- "transcripts",
374
- );
246
+ const transcriptsDir = path.join(manifest.artifactsRoot, "transcripts");
375
247
  let transcriptPath: string | undefined;
376
248
  if (fs.existsSync(transcriptsDir)) {
377
- const files = fs
378
- .readdirSync(transcriptsDir)
379
- .filter(
380
- (f) =>
381
- f.startsWith(`${task.id}.attempt-`) &&
382
- f.endsWith(".jsonl"),
383
- );
249
+ const files = fs.readdirSync(transcriptsDir).filter((f) => f.startsWith(`${task.id}.attempt-`) && f.endsWith(".jsonl"));
384
250
  if (files.length > 0) {
385
251
  // Sort by attempt index descending to get the most recent
386
252
  files.sort((a, b) => {
387
- const idxA = parseInt(
388
- a.match(/\.attempt-(\d+)\./)?.[1] ?? "0",
389
- );
390
- const idxB = parseInt(
391
- b.match(/\.attempt-(\d+)\./)?.[1] ?? "0",
392
- );
253
+ const idxA = parseInt(a.match(/\.attempt-(\d+)\./)?.[1] ?? "0");
254
+ const idxB = parseInt(b.match(/\.attempt-(\d+)\./)?.[1] ?? "0");
393
255
  return idxB - idxA;
394
256
  });
395
257
  transcriptPath = path.join(transcriptsDir, files[0]);
@@ -402,9 +264,7 @@ function recoverCheckpointedTasks(
402
264
  const resultArtifact = writeArtifact(manifest.artifactsRoot, {
403
265
  kind: "result",
404
266
  relativePath: `results/${task.id}.txt`,
405
- content:
406
- parsed.finalText ??
407
- "(recovered from completed child transcript)",
267
+ content: parsed.finalText ?? "(recovered from completed child transcript)",
408
268
  producer: task.id,
409
269
  });
410
270
  const transcriptArtifact = writeArtifact(manifest.artifactsRoot, {
@@ -429,20 +289,12 @@ function recoverCheckpointedTasks(
429
289
  return task;
430
290
  });
431
291
  if (recovered.length) {
432
- const artifacts = new Map(
433
- nextManifest.artifacts.map((artifact) => [
434
- artifactKey(artifact),
435
- artifact,
436
- ]),
437
- );
292
+ const artifacts = new Map(nextManifest.artifacts.map((artifact) => [artifactKey(artifact), artifact]));
438
293
  for (const task of nextTasks) {
439
294
  if (!recovered.includes(task.id)) continue;
440
- for (const artifact of [
441
- task.promptArtifact,
442
- task.resultArtifact,
443
- task.logArtifact,
444
- task.transcriptArtifact,
445
- ].filter(Boolean) as ArtifactDescriptor[])
295
+ for (const artifact of [task.promptArtifact, task.resultArtifact, task.logArtifact, task.transcriptArtifact].filter(
296
+ Boolean,
297
+ ) as ArtifactDescriptor[])
446
298
  artifacts.set(artifactKey(artifact), artifact);
447
299
  }
448
300
  nextManifest = {
@@ -456,70 +308,24 @@ function recoverCheckpointedTasks(
456
308
  return { manifest: nextManifest, tasks: nextTasks, recovered };
457
309
  }
458
310
 
459
- export async function handleResume(
460
- params: TeamToolParamsValue,
461
- ctx: TeamContext,
462
- ): Promise<PiTeamsToolResult> {
463
- if (!params.runId)
464
- return result(
465
- "Resume requires runId.",
466
- { action: "resume", status: "error" },
467
- true,
468
- );
311
+ export async function handleResume(params: TeamToolParamsValue, ctx: TeamContext): Promise<PiTeamsToolResult> {
312
+ if (!params.runId) return result("Resume requires runId.", { action: "resume", status: "error" }, true);
469
313
  const runCwd = locateRunCwd(params.runId, ctx.cwd);
470
- if (!runCwd)
471
- return result(
472
- `Run '${params.runId}' not found.${RUN_NOT_FOUND_HINT}`,
473
- { action: "resume", status: "error" },
474
- true,
475
- );
314
+ if (!runCwd) return result(`Run '${params.runId}' not found.${RUN_NOT_FOUND_HINT}`, { action: "resume", status: "error" }, true);
476
315
  const loaded = loadRunManifestById(runCwd, params.runId); // NOTE: no withRunLock - best-effort only; concurrent writes may cause inconsistency
477
- if (!loaded)
478
- return result(
479
- `Run '${params.runId}' not found.${RUN_NOT_FOUND_HINT}`,
480
- { action: "resume", status: "error" },
481
- true,
482
- );
316
+ if (!loaded) return result(`Run '${params.runId}' not found.${RUN_NOT_FOUND_HINT}`, { action: "resume", status: "error" }, true);
483
317
  if (!loaded.manifest.workflow)
484
- return result(
485
- `Run '${params.runId}' has no workflow to resume.`,
486
- { action: "resume", status: "error" },
487
- true,
488
- );
318
+ return result(`Run '${params.runId}' has no workflow to resume.`, { action: "resume", status: "error" }, true);
489
319
  const agents = allAgents(discoverAgents(ctx.cwd));
490
- const direct = directTeamAndWorkflowFromRun(
491
- loaded.manifest,
492
- loaded.tasks,
493
- agents,
494
- );
495
- const team =
496
- direct?.team ??
497
- allTeams(discoverTeams(ctx.cwd)).find(
498
- (candidate) => candidate.name === loaded.manifest.team,
499
- );
500
- if (!team)
501
- return result(
502
- `Team '${loaded.manifest.team}' not found.`,
503
- { action: "resume", status: "error" },
504
- true,
505
- );
320
+ const direct = directTeamAndWorkflowFromRun(loaded.manifest, loaded.tasks, agents);
321
+ const team = direct?.team ?? allTeams(discoverTeams(ctx.cwd)).find((candidate) => candidate.name === loaded.manifest.team);
322
+ if (!team) return result(`Team '${loaded.manifest.team}' not found.`, { action: "resume", status: "error" }, true);
506
323
  const workflow =
507
- direct?.workflow ??
508
- allWorkflows(discoverWorkflows(ctx.cwd)).find(
509
- (candidate) => candidate.name === loaded.manifest.workflow,
510
- );
511
- if (!workflow)
512
- return result(
513
- `Workflow '${loaded.manifest.workflow}' not found.`,
514
- { action: "resume", status: "error" },
515
- true,
516
- );
324
+ direct?.workflow ?? allWorkflows(discoverWorkflows(ctx.cwd)).find((candidate) => candidate.name === loaded.manifest.workflow);
325
+ if (!workflow) return result(`Workflow '${loaded.manifest.workflow}' not found.`, { action: "resume", status: "error" }, true);
517
326
  return await withRunLock(loaded.manifest, async () => {
518
327
  const loadedConfig = loadConfig(ctx.cwd);
519
- const recovered = recoverCheckpointedTasks(
520
- loaded.manifest,
521
- loaded.tasks,
522
- );
328
+ const recovered = recoverCheckpointedTasks(loaded.manifest, loaded.tasks);
523
329
  const resumeManifest = recovered.manifest;
524
330
  const executedConfig = {
525
331
  ...effectiveRunConfig(loadedConfig.config, params.config),
@@ -527,10 +333,7 @@ export async function handleResume(
527
333
  // Preserve original manifest scaffold mode when resume has no explicit mode override
528
334
  // AND workers are not explicitly disabled. If workers are disabled, let
529
335
  // resolveCrewRuntime detect it and return blocked safety.
530
- if (
531
- !executedConfig.runtime?.mode &&
532
- resumeManifest.runtimeResolution?.safety === "explicit_dry_run"
533
- ) {
336
+ if (!executedConfig.runtime?.mode && resumeManifest.runtimeResolution?.safety === "explicit_dry_run") {
534
337
  const workersDisabled =
535
338
  executedConfig.executeWorkers === false ||
536
339
  process.env.PI_CREW_EXECUTE_WORKERS === "0" ||
@@ -556,16 +359,11 @@ export async function handleResume(
556
359
  data: { runtimeResolution, action: "resume" },
557
360
  });
558
361
  if (runtime.safety === "blocked") {
559
- const runningManifest = updateRunStatus(
560
- runtimeManifest,
561
- "running",
562
- "Checking worker runtime availability before resume.",
563
- );
362
+ const runningManifest = updateRunStatus(runtimeManifest, "running", "Checking worker runtime availability before resume.");
564
363
  const blocked = updateRunStatus(
565
364
  runningManifest,
566
365
  "blocked",
567
- runtime.reason ??
568
- "Child worker execution is disabled; refusing to resume with no-op scaffold subagents.",
366
+ runtime.reason ?? "Child worker execution is disabled; refusing to resume with no-op scaffold subagents.",
569
367
  );
570
368
  appendEvent(blocked.eventsPath, {
571
369
  type: "run.blocked",
@@ -592,10 +390,7 @@ export async function handleResume(
592
390
  );
593
391
  }
594
392
  const resetTasks = recovered.tasks.map((task) =>
595
- task.status === "failed" ||
596
- task.status === "cancelled" ||
597
- task.status === "skipped" ||
598
- task.status === "running"
393
+ task.status === "failed" || task.status === "cancelled" || task.status === "skipped" || task.status === "running"
599
394
  ? {
600
395
  ...task,
601
396
  status: "queued" as const,
@@ -630,15 +425,11 @@ export async function handleResume(
630
425
  message: `Replayed ${replay.messages.length} pending inbox message(s).`,
631
426
  data: {
632
427
  messageIds: replay.messages.map((message) => message.id),
633
- taskIds: replay.messages
634
- .map((message) => message.taskId)
635
- .filter(Boolean),
428
+ taskIds: replay.messages.map((message) => message.taskId).filter(Boolean),
636
429
  },
637
430
  });
638
431
  const executeWorkers = runtime.kind !== "scaffold";
639
- const resumeSkillOverride =
640
- normalizeSkillOverride(params.skill) ??
641
- runtimeManifest.skillOverride;
432
+ const resumeSkillOverride = normalizeSkillOverride(params.skill) ?? runtimeManifest.skillOverride;
642
433
  const executed = await executeTeamRun({
643
434
  manifest: runtimeManifest,
644
435
  tasks: resetTasks,
@@ -677,39 +468,17 @@ export async function handleResume(
677
468
  });
678
469
  }
679
470
 
680
- export function handleSteer(
681
- params: TeamToolParamsValue,
682
- ctx: TeamContext,
683
- ): PiTeamsToolResult {
471
+ export function handleSteer(params: TeamToolParamsValue, ctx: TeamContext): PiTeamsToolResult {
684
472
  const { runId, taskId, message } = params;
685
473
  if (!runId || !taskId || !message) {
686
- return result(
687
- "steer requires runId, taskId, and message",
688
- { action: "steer", status: "error" },
689
- true,
690
- );
474
+ return result("steer requires runId, taskId, and message", { action: "steer", status: "error" }, true);
691
475
  }
692
476
  const runCwd = locateRunCwd(runId, ctx.cwd);
693
- if (!runCwd)
694
- return result(
695
- `Run '${runId}' not found`,
696
- { action: "steer", status: "error" },
697
- true,
698
- );
477
+ if (!runCwd) return result(`Run '${runId}' not found`, { action: "steer", status: "error" }, true);
699
478
  const loaded = loadRunManifestById(runCwd, runId); // NOTE: no withRunLock - best-effort only; concurrent writes may cause inconsistency
700
- if (!loaded)
701
- return result(
702
- `Run '${runId}' not found`,
703
- { action: "steer", status: "error" },
704
- true,
705
- );
479
+ if (!loaded) return result(`Run '${runId}' not found`, { action: "steer", status: "error" }, true);
706
480
  const task = loaded.tasks.find((t) => t.id === taskId);
707
- if (!task)
708
- return result(
709
- `Task '${taskId}' not found`,
710
- { action: "steer", status: "error" },
711
- true,
712
- );
481
+ if (!task) return result(`Task '${taskId}' not found`, { action: "steer", status: "error" }, true);
713
482
  if (!task.pendingSteers) task.pendingSteers = [];
714
483
  // HIGH-04: Cap pendingSteers array to prevent unbounded memory growth
715
484
  const MAX_PENDING_STEERS = 100;
@@ -735,44 +504,24 @@ export function handleSteer(
735
504
  taskId,
736
505
  data: { message },
737
506
  });
738
- return result(
739
- `Steer queued for task '${taskId}'. It will be delivered when the task's session is ready.`,
740
- { action: "steer", status: "ok" },
741
- );
507
+ return result(`Steer queued for task '${taskId}'. It will be delivered when the task's session is ready.`, {
508
+ action: "steer",
509
+ status: "ok",
510
+ });
742
511
  }
743
512
 
744
- function cacheControlDepsFromContext(
745
- ctx: TeamContext,
746
- ): CacheControlDeps | undefined {
513
+ function cacheControlDepsFromContext(ctx: TeamContext): CacheControlDeps | undefined {
747
514
  if (!ctx.getRunSnapshotCache) return undefined;
748
515
  return { getRunSnapshotCache: ctx.getRunSnapshotCache };
749
516
  }
750
517
 
751
- function handleInvalidate(
752
- params: TeamToolParamsValue,
753
- ctx: TeamContext,
754
- ): PiTeamsToolResult {
518
+ function handleInvalidate(params: TeamToolParamsValue, ctx: TeamContext): PiTeamsToolResult {
755
519
  const runId = params.runId;
756
- if (!runId)
757
- return result(
758
- "Invalidate requires runId.",
759
- { action: "invalidate", status: "error" },
760
- true,
761
- );
520
+ if (!runId) return result("Invalidate requires runId.", { action: "invalidate", status: "error" }, true);
762
521
  const runCwd = locateRunCwd(runId, ctx.cwd);
763
- if (!runCwd)
764
- return result(
765
- `Run '${runId}' not found.`,
766
- { action: "invalidate", status: "error" },
767
- true,
768
- );
522
+ if (!runCwd) return result(`Run '${runId}' not found.`, { action: "invalidate", status: "error" }, true);
769
523
  const deps = cacheControlDepsFromContext(ctx);
770
- if (!deps)
771
- return result(
772
- "Cache invalidation not available (no snapshot cache).",
773
- { action: "invalidate", status: "error" },
774
- true,
775
- );
524
+ if (!deps) return result("Cache invalidation not available (no snapshot cache).", { action: "invalidate", status: "error" }, true);
776
525
  invalidateSnapshot(runId, runCwd, deps);
777
526
  return result(`Cache invalidated for run ${runId}.`, {
778
527
  action: "invalidate",
@@ -792,23 +541,9 @@ function handleInvalidate(
792
541
  * (e.g. .crew, .pi, .tmp-crew-runs)
793
542
  */
794
543
  const MAX_SCAN_ENTRIES = 1000;
795
- const SKIP_SCAN_DIRS = new Set([
796
- "node_modules",
797
- ".git",
798
- ".npm",
799
- ".cache",
800
- ".local",
801
- "proc",
802
- "sys",
803
- "dev",
804
- "Library",
805
- "Applications",
806
- ]);
544
+ const SKIP_SCAN_DIRS = new Set(["node_modules", ".git", ".npm", ".cache", ".local", "proc", "sys", "dev", "Library", "Applications"]);
807
545
 
808
- export function locateRunCwd(
809
- runId: string,
810
- baseCwd: string,
811
- ): string | undefined {
546
+ export function locateRunCwd(runId: string, baseCwd: string): string | undefined {
812
547
  // Fast path: run is in the current CWD
813
548
  if (loadRunManifestById(baseCwd, runId)) {
814
549
  return baseCwd;
@@ -817,19 +552,13 @@ export function locateRunCwd(
817
552
  // Scan immediate child directories, but with defensive bounds.
818
553
  try {
819
554
  const entries = fs.readdirSync(baseCwd, { withFileTypes: true });
820
- const boundedEntries = entries.length > MAX_SCAN_ENTRIES
821
- ? entries.slice(0, MAX_SCAN_ENTRIES)
822
- : entries;
555
+ const boundedEntries = entries.length > MAX_SCAN_ENTRIES ? entries.slice(0, MAX_SCAN_ENTRIES) : entries;
823
556
  for (const entry of boundedEntries) {
824
557
  if (!entry.isDirectory()) continue;
825
558
  if (SKIP_SCAN_DIRS.has(entry.name)) continue;
826
559
  // Skip hidden entries except well-known run-storage prefixes
827
560
  if (entry.name.startsWith(".")) {
828
- if (
829
- !entry.name.startsWith(".crew") &&
830
- !entry.name.startsWith(".pi") &&
831
- !entry.name.startsWith(".tmp-crew")
832
- ) continue;
561
+ if (!entry.name.startsWith(".crew") && !entry.name.startsWith(".pi") && !entry.name.startsWith(".tmp-crew")) continue;
833
562
  }
834
563
  const candidate = path.join(baseCwd, entry.name);
835
564
  if (loadRunManifestById(candidate, runId)) {
@@ -843,32 +572,20 @@ export function locateRunCwd(
843
572
  return undefined;
844
573
  }
845
574
 
846
- async function handleWait(
847
- params: TeamToolParamsValue,
848
- ctx: TeamContext,
849
- ): Promise<PiTeamsToolResult> {
575
+ async function handleWait(params: TeamToolParamsValue, ctx: TeamContext): Promise<PiTeamsToolResult> {
850
576
  const { runId } = params;
851
- if (!runId)
852
- return result(
853
- "wait requires runId.",
854
- { action: "wait", status: "error" },
855
- true,
856
- );
577
+ if (!runId) return result("wait requires runId.", { action: "wait", status: "error" }, true);
857
578
 
858
579
  const timeoutMs = Math.min(
859
580
  Math.max(
860
- typeof params.config?.timeoutMs === "number" &&
861
- Number.isFinite(params.config.timeoutMs)
862
- ? params.config.timeoutMs
863
- : 300_000,
581
+ typeof params.config?.timeoutMs === "number" && Number.isFinite(params.config.timeoutMs) ? params.config.timeoutMs : 300_000,
864
582
  1_000, // minimum 1 s
865
583
  ),
866
584
  3_600_000, // maximum 1 h
867
585
  );
868
586
  const pollIntervalMs = Math.max(
869
587
  Math.min(
870
- typeof params.config?.pollIntervalMs === "number" &&
871
- Number.isFinite(params.config.pollIntervalMs)
588
+ typeof params.config?.pollIntervalMs === "number" && Number.isFinite(params.config.pollIntervalMs)
872
589
  ? params.config.pollIntervalMs
873
590
  : 2000,
874
591
  60_000, // maximum 60 s
@@ -879,11 +596,7 @@ async function handleWait(
879
596
  // Resolve the run's CWD: try ctx.cwd first, then scan child dirs with .crew/
880
597
  const runCwd = locateRunCwd(runId, ctx.cwd);
881
598
  if (!runCwd) {
882
- return result(
883
- `Run '${runId}' not found in '${ctx.cwd}' or its subdirectories.`,
884
- { action: "wait", status: "error", runId },
885
- true,
886
- );
599
+ return result(`Run '${runId}' not found in '${ctx.cwd}' or its subdirectories.`, { action: "wait", status: "error", runId }, true);
887
600
  }
888
601
 
889
602
  try {
@@ -891,16 +604,9 @@ async function handleWait(
891
604
  timeoutMs,
892
605
  pollIntervalMs,
893
606
  });
894
- const taskSummary = tasks
895
- .map((t) => ` ${t.id}: ${t.status}`)
896
- .join("\n");
607
+ const taskSummary = tasks.map((t) => ` ${t.id}: ${t.status}`).join("\n");
897
608
  return result(
898
- [
899
- `Run ${runId} finished: ${manifest.status}`,
900
- `Summary: ${manifest.summary ?? "(none)"}`,
901
- `Tasks:`,
902
- taskSummary,
903
- ].join("\n"),
609
+ [`Run ${runId} finished: ${manifest.status}`, `Summary: ${manifest.summary ?? "(none)"}`, `Tasks:`, taskSummary].join("\n"),
904
610
  {
905
611
  action: "wait",
906
612
  status: manifest.status === "failed" ? "error" : "ok",
@@ -910,18 +616,11 @@ async function handleWait(
910
616
  );
911
617
  } catch (err) {
912
618
  const msg = err instanceof Error ? err.message : String(err);
913
- return result(
914
- `wait failed: ${msg}`,
915
- { action: "wait", status: "error", runId },
916
- true,
917
- );
619
+ return result(`wait failed: ${msg}`, { action: "wait", status: "error", runId }, true);
918
620
  }
919
621
  }
920
622
 
921
- export async function handleTeamTool(
922
- params: TeamToolParamsValue,
923
- ctx: TeamContext,
924
- ): Promise<PiTeamsToolResult> {
623
+ export async function handleTeamTool(params: TeamToolParamsValue, ctx: TeamContext): Promise<PiTeamsToolResult> {
925
624
  const action = params.action ?? "list";
926
625
  switch (action as string) {
927
626
  case "list":
@@ -931,9 +630,7 @@ export async function handleTeamTool(
931
630
  case "init": {
932
631
  const cfg = configRecord(params.config);
933
632
  const ignoreMethod =
934
- typeof cfg.ignoreMethod === "string" &&
935
- (cfg.ignoreMethod === "gitignore" ||
936
- cfg.ignoreMethod === "exclude")
633
+ typeof cfg.ignoreMethod === "string" && (cfg.ignoreMethod === "gitignore" || cfg.ignoreMethod === "exclude")
937
634
  ? cfg.ignoreMethod
938
635
  : undefined;
939
636
  const initialized = initializeProject(ctx.cwd, {
@@ -951,22 +648,11 @@ export async function handleTeamTool(
951
648
  [
952
649
  "Initialized pi-crew project layout.",
953
650
  "Directories:",
954
- ...(initialized.createdDirs.length
955
- ? initialized.createdDirs.map(
956
- (dir) => `- created ${dir}`,
957
- )
958
- : ["- already existed"]),
651
+ ...(initialized.createdDirs.length ? initialized.createdDirs.map((dir) => `- created ${dir}`) : ["- already existed"]),
959
652
  "Copied builtin files:",
960
- ...(initialized.copiedFiles.length
961
- ? initialized.copiedFiles.map((file) => `- ${file}`)
962
- : ["- (none)"]),
653
+ ...(initialized.copiedFiles.length ? initialized.copiedFiles.map((file) => `- ${file}`) : ["- (none)"]),
963
654
  ...(initialized.skippedFiles.length
964
- ? [
965
- "Skipped existing files:",
966
- ...initialized.skippedFiles.map(
967
- (file) => `- ${file}`,
968
- ),
969
- ]
655
+ ? ["Skipped existing files:", ...initialized.skippedFiles.map((file) => `- ${file}`)]
970
656
  : []),
971
657
  `Config: ${initialized.configPath || "(none)"} (${initialized.configScope}${initialized.configCreated ? "; created" : initialized.configSkipped ? "; already existed" : "; unchanged"})`,
972
658
  `Ignore: ${initialized.gitignorePath} (${initialized.gitignoreUpdated ? "updated" : "already configured"})`,
@@ -978,21 +664,12 @@ export async function handleTeamTool(
978
664
  return result(piTeamsHelp(), { action: "help", status: "ok" });
979
665
  case "recommend": {
980
666
  const goal = params.goal ?? params.task;
981
- if (!goal)
982
- return result(
983
- "Recommend requires goal or task.",
984
- { action: "recommend", status: "error" },
985
- true,
986
- );
667
+ if (!goal) return result("Recommend requires goal or task.", { action: "recommend", status: "error" }, true);
987
668
  const loaded = loadConfig(ctx.cwd);
988
- const recommendation = recommendTeam(
989
- goal,
990
- loaded.config.autonomous,
991
- {
992
- teams: allTeams(discoverTeams(ctx.cwd)),
993
- agents: allAgents(discoverAgents(ctx.cwd)),
994
- },
995
- );
669
+ const recommendation = recommendTeam(goal, loaded.config.autonomous, {
670
+ teams: allTeams(discoverTeams(ctx.cwd)),
671
+ agents: allAgents(discoverAgents(ctx.cwd)),
672
+ });
996
673
  return result(formatRecommendation(goal, recommendation), {
997
674
  action: "recommend",
998
675
  status: "ok",
@@ -1000,17 +677,11 @@ export async function handleTeamTool(
1000
677
  }
1001
678
  case "autonomy": {
1002
679
  const patch = autonomousPatchFromConfig(params.config);
1003
- const shouldUpdate = Object.values(patch).some(
1004
- (value) => value !== undefined,
1005
- );
680
+ const shouldUpdate = Object.values(patch).some((value) => value !== undefined);
1006
681
  if (!shouldUpdate) {
1007
682
  const loaded = loadConfig(ctx.cwd);
1008
683
  return result(
1009
- formatAutonomyStatus(
1010
- loaded.config.autonomous,
1011
- loaded.path,
1012
- false,
1013
- ),
684
+ formatAutonomyStatus(loaded.config.autonomous, loaded.path, false),
1014
685
  {
1015
686
  action: "autonomy",
1016
687
  status: loaded.error ? "error" : "ok",
@@ -1020,37 +691,21 @@ export async function handleTeamTool(
1020
691
  }
1021
692
  try {
1022
693
  const saved = updateAutonomousConfig(patch);
1023
- return result(
1024
- formatAutonomyStatus(
1025
- saved.config.autonomous,
1026
- saved.path,
1027
- true,
1028
- ),
1029
- { action: "autonomy", status: "ok" },
1030
- );
694
+ return result(formatAutonomyStatus(saved.config.autonomous, saved.path, true), { action: "autonomy", status: "ok" });
1031
695
  } catch (error) {
1032
- const message =
1033
- error instanceof Error ? error.message : String(error);
1034
- return result(
1035
- message,
1036
- { action: "autonomy", status: "error" },
1037
- true,
1038
- );
696
+ const message = error instanceof Error ? error.message : String(error);
697
+ return result(message, { action: "autonomy", status: "error" }, true);
1039
698
  }
1040
699
  }
1041
700
  case "config": {
1042
701
  const patch = configPatchFromConfig(params.config);
1043
702
  const cfg = configRecord(params.config);
1044
703
  const unsetPaths = Array.isArray(cfg.unset)
1045
- ? cfg.unset.filter(
1046
- (entry): entry is string => typeof entry === "string",
1047
- )
704
+ ? cfg.unset.filter((entry): entry is string => typeof entry === "string")
1048
705
  : typeof cfg.unset === "string"
1049
706
  ? [cfg.unset]
1050
707
  : [];
1051
- const shouldUpdate =
1052
- Object.values(patch).some((value) => value !== undefined) ||
1053
- unsetPaths.length > 0;
708
+ const shouldUpdate = Object.values(patch).some((value) => value !== undefined) || unsetPaths.length > 0;
1054
709
  if (shouldUpdate) {
1055
710
  try {
1056
711
  const saved = updateConfig(patch, {
@@ -1059,22 +714,14 @@ export async function handleTeamTool(
1059
714
  unsetPaths,
1060
715
  });
1061
716
  return result(
1062
- [
1063
- "Updated pi-crew config.",
1064
- `Path: ${saved.path}`,
1065
- "Effective config:",
1066
- JSON.stringify(saved.config, null, 2),
1067
- ].join("\n"),
717
+ ["Updated pi-crew config.", `Path: ${saved.path}`, "Effective config:", JSON.stringify(saved.config, null, 2)].join(
718
+ "\n",
719
+ ),
1068
720
  { action: "config", status: "ok" },
1069
721
  );
1070
722
  } catch (error) {
1071
- const message =
1072
- error instanceof Error ? error.message : String(error);
1073
- return result(
1074
- message,
1075
- { action: "config", status: "error" },
1076
- true,
1077
- );
723
+ const message = error instanceof Error ? error.message : String(error);
724
+ return result(message, { action: "config", status: "error" }, true);
1078
725
  }
1079
726
  }
1080
727
  const loaded = loadConfig(ctx.cwd);
@@ -1086,22 +733,12 @@ export async function handleTeamTool(
1086
733
  JSON.stringify(loaded.config, null, 2),
1087
734
  "Schema: package export ./schema.json",
1088
735
  ];
1089
- return result(
1090
- lines.join("\n"),
1091
- { action: "config", status: loaded.error ? "error" : "ok" },
1092
- Boolean(loaded.error),
1093
- );
736
+ return result(lines.join("\n"), { action: "config", status: loaded.error ? "error" : "ok" }, Boolean(loaded.error));
1094
737
  }
1095
738
  case "validate": {
1096
739
  const report = validateResources(ctx.cwd);
1097
- const hasErrors = report.issues.some(
1098
- (issue) => issue.level === "error",
1099
- );
1100
- return result(
1101
- formatValidationReport(report),
1102
- { action: "validate", status: hasErrors ? "error" : "ok" },
1103
- hasErrors,
1104
- );
740
+ const hasErrors = report.issues.some((issue) => issue.level === "error");
741
+ return result(formatValidationReport(report), { action: "validate", status: hasErrors ? "error" : "ok" }, hasErrors);
1105
742
  }
1106
743
  case "doctor":
1107
744
  return handleDoctor(ctx, params);
@@ -1166,29 +803,21 @@ export async function handleTeamTool(
1166
803
  assertSafePathId("runId", params.runId);
1167
804
  const graph = loadRunGraph(ctx.cwd, params.runId);
1168
805
  return result(
1169
- graph
1170
- ? JSON.stringify(graph, null, 2)
1171
- : "No graph found for this run.",
806
+ graph ? JSON.stringify(graph, null, 2) : "No graph found for this run.",
1172
807
  { action: "graph", status: graph ? "ok" : "error" },
1173
808
  !graph,
1174
809
  );
1175
810
  }
1176
811
  const graphs = listRunGraphs(ctx.cwd);
1177
- return result(
1178
- graphs.length
1179
- ? `Available graphs:\n${graphs.join("\n")}`
1180
- : "No graphs available.",
1181
- { action: "graph", status: "ok" },
1182
- );
812
+ return result(graphs.length ? `Available graphs:\n${graphs.join("\n")}` : "No graphs available.", {
813
+ action: "graph",
814
+ status: "ok",
815
+ });
1183
816
  }
1184
817
  case "search": {
1185
818
  const query = params.goal ?? params.task ?? "";
1186
819
  if (!query) {
1187
- return result(
1188
- "Search requires goal or task query.",
1189
- { action: "search", status: "error" },
1190
- true,
1191
- );
820
+ return result("Search requires goal or task query.", { action: "search", status: "error" }, true);
1192
821
  }
1193
822
  try {
1194
823
  const [agentResults, teamResults] = await Promise.all([
@@ -1199,30 +828,19 @@ export async function handleTeamTool(
1199
828
  if (teamResults.length) {
1200
829
  lines.push("## Teams");
1201
830
  for (const r of teamResults) {
1202
- lines.push(
1203
- `- [${r.team.name}] score=${r.score.toFixed(2)}: ${r.team.description ?? "(no description)"}`,
1204
- );
831
+ lines.push(`- [${r.team.name}] score=${r.score.toFixed(2)}: ${r.team.description ?? "(no description)"}`);
1205
832
  }
1206
833
  }
1207
834
  if (agentResults.length) {
1208
835
  lines.push("## Agents");
1209
836
  for (const r of agentResults) {
1210
- lines.push(
1211
- `- [${r.agent.name}] score=${r.score.toFixed(2)}: ${r.agent.description ?? "(no description)"}`,
1212
- );
837
+ lines.push(`- [${r.agent.name}] score=${r.score.toFixed(2)}: ${r.agent.description ?? "(no description)"}`);
1213
838
  }
1214
839
  }
1215
- return result(
1216
- lines.length ? lines.join("\n") : "No results found.",
1217
- { action: "search", status: "ok" },
1218
- );
840
+ return result(lines.length ? lines.join("\n") : "No results found.", { action: "search", status: "ok" });
1219
841
  } catch (err) {
1220
842
  const msg = err instanceof Error ? err.message : String(err);
1221
- return result(
1222
- `Search failed: ${msg}`,
1223
- { action: "search", status: "error" },
1224
- true,
1225
- );
843
+ return result(`Search failed: ${msg}`, { action: "search", status: "error" }, true);
1226
844
  }
1227
845
  }
1228
846
  case "schedule":
@@ -1230,10 +848,7 @@ export async function handleTeamTool(
1230
848
  case "scheduled":
1231
849
  return handleListScheduled(params, ctx);
1232
850
  case "anchor": {
1233
- const subAction =
1234
- typeof params.config?.subAction === "string"
1235
- ? params.config.subAction
1236
- : "status";
851
+ const subAction = typeof params.config?.subAction === "string" ? params.config.subAction : "status";
1237
852
  switch (subAction) {
1238
853
  case "set":
1239
854
  return handleAnchorSet(params, ctx);
@@ -1275,10 +890,10 @@ export async function handleTeamTool(
1275
890
  case "toggle": {
1276
891
  const service = createAutoSummarizeService();
1277
892
  service.toggle();
1278
- return result(
1279
- `Auto-summarize ${service.isEnabled() ? "enabled" : "disabled"}.`,
1280
- { action: "auto-summarize", status: "ok" },
1281
- );
893
+ return result(`Auto-summarize ${service.isEnabled() ? "enabled" : "disabled"}.`, {
894
+ action: "auto-summarize",
895
+ status: "ok",
896
+ });
1282
897
  }
1283
898
  default:
1284
899
  return handleAutoSummarizeStatus(params, ctx);
@@ -1302,12 +917,7 @@ export async function handleTeamTool(
1302
917
  }
1303
918
  case "cache": {
1304
919
  if (params.goal) {
1305
- const key = computeRunCacheKey(
1306
- params.goal,
1307
- params.team ?? "default",
1308
- params.workflow ?? "default",
1309
- ctx.cwd,
1310
- );
920
+ const key = computeRunCacheKey(params.goal, params.team ?? "default", params.workflow ?? "default", ctx.cwd);
1311
921
  const cached = getCachedRun(ctx.cwd, key);
1312
922
  if (cached) {
1313
923
  return result(
@@ -1332,35 +942,19 @@ export async function handleTeamTool(
1332
942
  });
1333
943
  }
1334
944
  const stats = getCacheStats(ctx.cwd);
1335
- return result(
1336
- `Cache stats: ${stats.entries} entries, ${stats.sizeBytes} bytes`,
1337
- { action: "cache", status: "ok" },
1338
- );
945
+ return result(`Cache stats: ${stats.entries} entries, ${stats.sizeBytes} bytes`, { action: "cache", status: "ok" });
1339
946
  }
1340
947
  case "checkpoint": {
1341
948
  if (!params.runId || !params.taskId) {
1342
- return result(
1343
- "Checkpoint requires runId and taskId.",
1344
- { action: "checkpoint", status: "error" },
1345
- true,
1346
- );
949
+ return result("Checkpoint requires runId and taskId.", { action: "checkpoint", status: "error" }, true);
1347
950
  }
1348
951
  assertSafePathId("runId", params.runId);
1349
952
  assertSafePathId("taskId", params.taskId);
1350
- const stateRoot = path.join(
1351
- projectCrewRoot(ctx.cwd),
1352
- "state",
1353
- "runs",
1354
- params.runId,
1355
- );
953
+ const stateRoot = path.join(projectCrewRoot(ctx.cwd), "state", "runs", params.runId);
1356
954
  const store = new FileCheckpointStore(stateRoot);
1357
955
  const checkpoint = store.load(params.runId, params.taskId);
1358
956
  if (!checkpoint) {
1359
- return result(
1360
- "No checkpoint found.",
1361
- { action: "checkpoint", status: "error" },
1362
- true,
1363
- );
957
+ return result("No checkpoint found.", { action: "checkpoint", status: "error" }, true);
1364
958
  }
1365
959
  return result(
1366
960
  `Checkpoint: step=${checkpoint.step}, progress=${checkpoint.progress}, savedAt=${new Date(checkpoint.savedAt).toISOString()}`,
@@ -1403,15 +997,12 @@ interface CrewRegistry {
1403
997
  // registerAgent/unregisterAgent/listDynamicAgents for cross-extension access.
1404
998
 
1405
999
  export function registerCrewGlobalRegistry(registry: CrewRegistry): void {
1406
- (globalThis as Record<symbol | string, unknown>)[CREW_REGISTRY_KEY] =
1407
- registry;
1000
+ (globalThis as Record<symbol | string, unknown>)[CREW_REGISTRY_KEY] = registry;
1408
1001
  }
1409
1002
 
1410
1003
  /** @internal */
1411
1004
  function getCrewGlobalRegistry(): CrewRegistry | undefined {
1412
- return (globalThis as Record<symbol | string, unknown>)[
1413
- CREW_REGISTRY_KEY
1414
- ] as CrewRegistry | undefined;
1005
+ return (globalThis as Record<symbol | string, unknown>)[CREW_REGISTRY_KEY] as CrewRegistry | undefined;
1415
1006
  }
1416
1007
 
1417
1008
  /** Create and install the global CrewRegistry singleton. Call once at extension init. */