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,7 +1,7 @@
1
1
  import * as fs from "node:fs";
2
2
  import type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from "@earendil-works/pi-coding-agent";
3
3
  import { loadRunManifestById } from "../../state/state-store.ts";
4
- import { savePersistedSubagentRecord, type SubagentRecord, type SubagentSpawnOptions } from "../../subagents/manager.ts";
4
+ import { type SubagentRecord, type SubagentSpawnOptions, savePersistedSubagentRecord } from "../../subagents/manager.ts";
5
5
  import { resolveRealContainedPath } from "../../utils/safe-paths.ts";
6
6
 
7
7
  interface FollowUpCapablePi {
@@ -12,18 +12,33 @@ interface FollowUpCapablePi {
12
12
  export function sendFollowUp(pi: ExtensionAPI, content: string): void {
13
13
  const api = pi as unknown as FollowUpCapablePi;
14
14
  if (typeof api.sendMessage !== "function") return;
15
- api.sendMessage.call(pi, { customType: "pi-crew-subagent-notification", content, display: true }, { deliverAs: "followUp", triggerTurn: true });
15
+ api.sendMessage.call(
16
+ pi,
17
+ { customType: "pi-crew-subagent-notification", content, display: true },
18
+ { deliverAs: "followUp", triggerTurn: true },
19
+ );
16
20
  }
17
21
 
18
22
  export function sendAgentWakeUp(pi: ExtensionAPI, content: string): boolean {
19
23
  const api = pi as unknown as FollowUpCapablePi;
20
24
  try {
21
25
  if (typeof api.sendUserMessage === "function") {
22
- api.sendUserMessage.call(pi, content, { deliverAs: "followUp", triggerTurn: true });
26
+ api.sendUserMessage.call(pi, content, {
27
+ deliverAs: "followUp",
28
+ triggerTurn: true,
29
+ });
23
30
  return true;
24
31
  }
25
32
  if (typeof api.sendMessage === "function") {
26
- api.sendMessage.call(pi, { customType: "pi-crew-subagent-wakeup", content, display: true }, { deliverAs: "followUp", triggerTurn: true });
33
+ api.sendMessage.call(
34
+ pi,
35
+ {
36
+ customType: "pi-crew-subagent-wakeup",
37
+ content,
38
+ display: true,
39
+ },
40
+ { deliverAs: "followUp", triggerTurn: true },
41
+ );
27
42
  return true;
28
43
  }
29
44
  } catch {
@@ -36,12 +51,17 @@ export function refreshPersistedSubagentRecord(ctx: ExtensionContext | Extension
36
51
  if (!record.runId) return record;
37
52
  const loaded = loadRunManifestById(ctx.cwd, record.runId); // NOTE: no withRunLock - best-effort only; concurrent writes may cause inconsistency
38
53
  if (!loaded) return record;
39
- if (loaded.manifest.status === "completed" || loaded.manifest.status === "failed" || loaded.manifest.status === "cancelled" || loaded.manifest.status === "blocked") {
54
+ if (
55
+ loaded.manifest.status === "completed" ||
56
+ loaded.manifest.status === "failed" ||
57
+ loaded.manifest.status === "cancelled" ||
58
+ loaded.manifest.status === "blocked"
59
+ ) {
40
60
  const refreshed = {
41
61
  ...record,
42
62
  status: loaded.manifest.status,
43
63
  error: loaded.manifest.status === "completed" || loaded.manifest.status === "blocked" ? undefined : loaded.manifest.summary,
44
- completedAt: loaded.manifest.status === "blocked" ? undefined : record.completedAt ?? Date.now(),
64
+ completedAt: loaded.manifest.status === "blocked" ? undefined : (record.completedAt ?? Date.now()),
45
65
  };
46
66
  savePersistedSubagentRecord(ctx.cwd, refreshed);
47
67
  return refreshed;
@@ -60,7 +80,9 @@ export function formatSubagentRecord(record: SubagentRecord): string {
60
80
  record.model ? `Model: ${record.model}` : undefined,
61
81
  `Duration: ${duration}`,
62
82
  record.error ? `Error: ${record.error}` : undefined,
63
- ].filter((line): line is string => Boolean(line)).join("\n");
83
+ ]
84
+ .filter((line): line is string => Boolean(line))
85
+ .join("\n");
64
86
  }
65
87
 
66
88
  export function readSubagentRunResult(ctx: ExtensionContext | ExtensionCommandContext, record: SubagentRecord): string | undefined {
@@ -1,11 +1,15 @@
1
1
  import type { ExtensionAPI, ToolDefinition } from "@earendil-works/pi-coding-agent";
2
2
  import { Type } from "@sinclair/typebox";
3
3
  import type { TeamToolParamsValue } from "../../schema/team-tool-schema.ts";
4
+ import { withSessionId } from "../team-tool/context.ts";
4
5
  // Lazy-loaded: team-tool.ts pulls in entire runtime chain.
5
6
  import type { handleTeamTool as HandleTeamToolFn } from "../team-tool.ts";
6
- import { withSessionId } from "../team-tool/context.ts";
7
+
7
8
  let _cachedHandleTeamTool: typeof HandleTeamToolFn | undefined;
8
- async function handleTeamTool(params: Parameters<typeof HandleTeamToolFn>[0], ctx: Parameters<typeof HandleTeamToolFn>[1]): Promise<Awaited<ReturnType<typeof HandleTeamToolFn>>> {
9
+ async function handleTeamTool(
10
+ params: Parameters<typeof HandleTeamToolFn>[0],
11
+ ctx: Parameters<typeof HandleTeamToolFn>[1],
12
+ ): Promise<Awaited<ReturnType<typeof HandleTeamToolFn>>> {
9
13
  if (!_cachedHandleTeamTool) {
10
14
  // LAZY: team-tool.ts pulls in entire runtime chain.
11
15
  const mod = await import("../team-tool.ts");
@@ -13,18 +17,30 @@ async function handleTeamTool(params: Parameters<typeof HandleTeamToolFn>[0], ct
13
17
  }
14
18
  return _cachedHandleTeamTool(params, ctx);
15
19
  }
16
- import { checkSubagentSpawnPermission, currentCrewRole } from "../../runtime/role-permission.ts";
17
- import { readPersistedSubagentRecord, savePersistedSubagentRecord, type SubagentManager, type SubagentSpawnOptions } from "../../subagents/manager.ts";
18
- import type { BatchBarrier } from "../../runtime/batch-barrier.ts";
20
+
21
+ import { Text } from "@earendil-works/pi-tui";
19
22
  import { loadConfig } from "../../config/config.ts";
20
- import { logInternalError } from "../../utils/internal-error.ts";
21
- import { __test__subagentSpawnParams, formatSubagentRecord, readSubagentRunResult, refreshPersistedSubagentRecord, subagentToolResult } from "./subagent-helpers.ts";
22
23
  import { t } from "../../i18n.ts";
23
- import { loadRunManifestById } from "../../state/state-store.ts";
24
+ import type { BatchBarrier } from "../../runtime/batch-barrier.ts";
24
25
  import { readCrewAgents } from "../../runtime/crew-agent-records.ts";
26
+ import { checkSubagentSpawnPermission, currentCrewRole } from "../../runtime/role-permission.ts";
27
+ import { loadRunManifestById } from "../../state/state-store.ts";
28
+ import {
29
+ readPersistedSubagentRecord,
30
+ type SubagentManager,
31
+ type SubagentSpawnOptions,
32
+ savePersistedSubagentRecord,
33
+ } from "../../subagents/manager.ts";
25
34
  import { formatCompactToolProgress } from "../../ui/tool-progress-formatter.ts";
26
- import { Text } from "@earendil-works/pi-tui";
27
35
  import { agentToolRenderer } from "../../ui/tool-renderers/index.ts";
36
+ import { logInternalError } from "../../utils/internal-error.ts";
37
+ import {
38
+ __test__subagentSpawnParams,
39
+ formatSubagentRecord,
40
+ readSubagentRunResult,
41
+ refreshPersistedSubagentRecord,
42
+ subagentToolResult,
43
+ } from "./subagent-helpers.ts";
28
44
 
29
45
  const TOOL_PROGRESS_TICK_MS = 1000;
30
46
 
@@ -38,43 +54,111 @@ export interface SubagentToolRegistrationOptions {
38
54
  batchBarrier?: BatchBarrier;
39
55
  }
40
56
 
41
- export function registerSubagentTools(pi: ExtensionAPI, subagentManager: SubagentManager, options: SubagentToolRegistrationOptions = {}): void {
57
+ export function registerSubagentTools(
58
+ pi: ExtensionAPI,
59
+ subagentManager: SubagentManager,
60
+ options: SubagentToolRegistrationOptions = {},
61
+ ): void {
42
62
  const agentTool: ToolDefinition = {
43
63
  name: "Agent",
44
64
  label: "Agent",
45
- description: "Launch a real pi-crew subagent. Uses pi-crew's durable child-process runtime by default; set run_in_background=true for parallel/background work, then use get_subagent_result.",
46
- promptSnippet: "Use Agent to delegate focused work to a real pi-crew subagent. Use run_in_background=true for parallel work and get_subagent_result to join results.",
65
+ description:
66
+ "Launch a real pi-crew subagent. Uses pi-crew's durable child-process runtime by default; set run_in_background=true for parallel/background work, then use get_subagent_result.",
67
+ promptSnippet:
68
+ "Use Agent to delegate focused work to a real pi-crew subagent. Use run_in_background=true for parallel work and get_subagent_result to join results.",
47
69
  promptGuidelines: [
48
70
  "Use Agent for independent exploration, review, verification, or implementation subtasks instead of doing all work in the parent turn.",
49
71
  "For parallel work, launch multiple Agent calls with run_in_background=true, then call get_subagent_result for each result.",
50
72
  "Available pi-crew subagent types include explorer, planner, analyst, executor, reviewer, verifier, writer, security-reviewer, and test-engineer.",
51
73
  ],
52
74
  parameters: Type.Object({
53
- prompt: Type.String({ description: "The task for the subagent to perform." }),
54
- description: Type.String({ description: "Short 3-5 word task description." }),
55
- subagent_type: Type.String({ description: "pi-crew agent name, e.g. explorer, planner, executor, reviewer, verifier, writer, security-reviewer, test-engineer." }),
56
- model: Type.Optional(Type.String({ description: "Optional model override. If omitted, pi-crew uses Pi-configured model fallback." })),
57
- skill: Type.Optional(Type.Union([Type.String(), Type.Array(Type.String()), Type.Boolean()], { description: "Skill name(s) to inject for this subagent, or false to disable selected/default skills." })),
58
- max_turns: Type.Optional(Type.Number({ description: "Reserved for live-session subagents; child-process runtime may ignore this." })),
59
- run_in_background: Type.Optional(Type.Boolean({ description: "Run in background and return an agent ID immediately." })),
60
- batch_id: Type.Optional(Type.String({ description: "Optional batch grouping id. Background agents sharing the same batch_id receive ONE consolidated completion notification when ALL members finish (instead of N individual notifications). Use this when launching several background agents in one turn and you do not join them immediately. Omit for the default individual-notification behavior." })),
75
+ prompt: Type.String({
76
+ description: "The task for the subagent to perform.",
77
+ }),
78
+ description: Type.String({
79
+ description: "Short 3-5 word task description.",
80
+ }),
81
+ subagent_type: Type.String({
82
+ description:
83
+ "pi-crew agent name, e.g. explorer, planner, executor, reviewer, verifier, writer, security-reviewer, test-engineer.",
84
+ }),
85
+ model: Type.Optional(
86
+ Type.String({
87
+ description: "Optional model override. If omitted, pi-crew uses Pi-configured model fallback.",
88
+ }),
89
+ ),
90
+ skill: Type.Optional(
91
+ Type.Union([Type.String(), Type.Array(Type.String()), Type.Boolean()], {
92
+ description: "Skill name(s) to inject for this subagent, or false to disable selected/default skills.",
93
+ }),
94
+ ),
95
+ max_turns: Type.Optional(
96
+ Type.Number({
97
+ description: "Reserved for live-session subagents; child-process runtime may ignore this.",
98
+ }),
99
+ ),
100
+ run_in_background: Type.Optional(
101
+ Type.Boolean({
102
+ description: "Run in background and return an agent ID immediately.",
103
+ }),
104
+ ),
105
+ batch_id: Type.Optional(
106
+ Type.String({
107
+ description:
108
+ "Optional batch grouping id. Background agents sharing the same batch_id receive ONE consolidated completion notification when ALL members finish (instead of N individual notifications). Use this when launching several background agents in one turn and you do not join them immediately. Omit for the default individual-notification behavior.",
109
+ }),
110
+ ),
61
111
  }) as never,
62
112
  async execute(_id, params, signal, onUpdate, ctx) {
63
113
  // Diagnostic: detect pre-aborted signal before spawn
64
114
  if (signal?.aborted) {
65
- logInternalError("subagent-tools.pre-aborted-signal", undefined, `aborted=true paramsKeys=${Object.keys(params as object).join(",")}`);
66
- return subagentToolResult("Agent tool signal was already aborted before execution started. This usually means Pi cancelled the tool call before it ran.", { action: "agent", status: "error" }, true);
115
+ logInternalError(
116
+ "subagent-tools.pre-aborted-signal",
117
+ undefined,
118
+ `aborted=true paramsKeys=${Object.keys(params as object).join(",")}`,
119
+ );
120
+ return subagentToolResult(
121
+ "Agent tool signal was already aborted before execution started. This usually means Pi cancelled the tool call before it ran.",
122
+ { action: "agent", status: "error" },
123
+ true,
124
+ );
67
125
  }
68
126
  const currentRole = currentCrewRole();
69
127
  const permission = checkSubagentSpawnPermission(currentRole);
70
- if (!permission.allowed) return subagentToolResult(permission.reason ?? "Current role cannot spawn subagents.", { role: currentRole, mode: permission.mode }, true);
128
+ if (!permission.allowed)
129
+ return subagentToolResult(
130
+ permission.reason ?? "Current role cannot spawn subagents.",
131
+ { role: currentRole, mode: permission.mode },
132
+ true,
133
+ );
71
134
  const spawnOptions = __test__subagentSpawnParams(params as Record<string, unknown>, ctx);
72
135
  spawnOptions.ownerSessionGeneration = options.ownerSessionGeneration?.();
73
136
  if (!spawnOptions.prompt.trim()) return subagentToolResult(t("agent.requiresPrompt"), {}, true);
74
137
  // Extract sessionId from sessionManager.getSessionId() so team runs created
75
138
  // by the Agent tool have proper session ownership for isolation.
76
139
  const ctxWithSession = withSessionId(ctx);
77
- const runner = async (currentOptions: SubagentSpawnOptions, childSignal?: AbortSignal) => handleTeamTool({ action: "run", agent: currentOptions.type, goal: currentOptions.prompt, model: currentOptions.model, skill: currentOptions.skill, async: currentOptions.background, config: currentOptions.maxTurns ? { runtime: { maxTurns: currentOptions.maxTurns } } : undefined } as TeamToolParamsValue, { ...ctxWithSession, signal: childSignal, ...(options.startForegroundRun ? { startForegroundRun: (runRunner: (sig?: AbortSignal) => Promise<void>, runId?: string) => options.startForegroundRun!(ctxWithSession, runRunner, runId) } : {}) });
140
+ const runner = async (currentOptions: SubagentSpawnOptions, childSignal?: AbortSignal) =>
141
+ handleTeamTool(
142
+ {
143
+ action: "run",
144
+ agent: currentOptions.type,
145
+ goal: currentOptions.prompt,
146
+ model: currentOptions.model,
147
+ skill: currentOptions.skill,
148
+ async: currentOptions.background,
149
+ config: currentOptions.maxTurns ? { runtime: { maxTurns: currentOptions.maxTurns } } : undefined,
150
+ } as TeamToolParamsValue,
151
+ {
152
+ ...ctxWithSession,
153
+ signal: childSignal,
154
+ ...(options.startForegroundRun
155
+ ? {
156
+ startForegroundRun: (runRunner: (sig?: AbortSignal) => Promise<void>, runId?: string) =>
157
+ options.startForegroundRun!(ctxWithSession, runRunner, runId),
158
+ }
159
+ : {}),
160
+ },
161
+ );
78
162
  const record = subagentManager.spawn(spawnOptions, runner, spawnOptions.background ? undefined : signal);
79
163
  // Rule 1: register batch membership so completions can be coalesced.
80
164
  if (spawnOptions.batchId && spawnOptions.background) {
@@ -85,7 +169,23 @@ export function registerSubagentTools(pi: ExtensionAPI, subagentManager: Subagen
85
169
  // Phase 1.6: Record was terminated for telemetry.
86
170
  record.terminated = true;
87
171
  savePersistedSubagentRecord(ctx.cwd, record);
88
- return { ...subagentToolResult([t("agent.started", { state: record.status === "queued" ? "queued" : "started" }), t("agent.id", { id: record.id }), t("agent.type", { type: record.type }), t("agent.description", { description: record.description }), t("agent.retrieveHint")].join("\n"), { agentId: record.id, status: record.status }), terminate: true };
172
+ return {
173
+ ...subagentToolResult(
174
+ [
175
+ t("agent.started", {
176
+ state: record.status === "queued" ? "queued" : "started",
177
+ }),
178
+ t("agent.id", { id: record.id }),
179
+ t("agent.type", { type: record.type }),
180
+ t("agent.description", {
181
+ description: record.description,
182
+ }),
183
+ t("agent.retrieveHint"),
184
+ ].join("\n"),
185
+ { agentId: record.id, status: record.status },
186
+ ),
187
+ terminate: true,
188
+ };
89
189
  }
90
190
  const stopProgress = startAgentToolProgress(ctx.cwd, record.id, onUpdate as OnUpdate | undefined, subagentManager);
91
191
  try {
@@ -95,10 +195,29 @@ export function registerSubagentTools(pi: ExtensionAPI, subagentManager: Subagen
95
195
  }
96
196
  // Diagnostic: log when foreground subagent ends in "stopped" to surface the abort reason
97
197
  if (record.status === "stopped") {
98
- logInternalError("subagent-tools.foreground-stopped", undefined, `agentId=${record.id} runId=${record.runId ?? ""} error=${record.error ?? "(none)"} result=${(record.result ?? "").slice(0, 200)}`);
198
+ logInternalError(
199
+ "subagent-tools.foreground-stopped",
200
+ undefined,
201
+ `agentId=${record.id} runId=${record.runId ?? ""} error=${record.error ?? "(none)"} result=${(record.result ?? "").slice(0, 200)}`,
202
+ );
99
203
  }
100
204
  const output = readSubagentRunResult(ctx, record) ?? record.result ?? record.error ?? t("agent.noOutput");
101
- const foregroundResult = subagentToolResult([t("agent.foregroundStatus", { id: record.id, status: record.status }), "", output].join("\n"), { agentId: record.id, runId: record.runId, status: record.status }, record.status === "failed" || record.status === "error" || record.status === "stopped");
205
+ const foregroundResult = subagentToolResult(
206
+ [
207
+ t("agent.foregroundStatus", {
208
+ id: record.id,
209
+ status: record.status,
210
+ }),
211
+ "",
212
+ output,
213
+ ].join("\n"),
214
+ {
215
+ agentId: record.id,
216
+ runId: record.runId,
217
+ status: record.status,
218
+ },
219
+ record.status === "failed" || record.status === "error" || record.status === "stopped",
220
+ );
102
221
  if (loadConfig(ctx.cwd).config.tools?.terminateOnForeground === true) {
103
222
  record.terminated = true;
104
223
  savePersistedSubagentRecord(ctx.cwd, record);
@@ -115,7 +234,7 @@ export function registerSubagentTools(pi: ExtensionAPI, subagentManager: Subagen
115
234
  try {
116
235
  return agentToolRenderer.renderResult(result, options, theme, context);
117
236
  } catch (e: any) {
118
- return new Text('agent-err: ' + (e?.message ?? 'unknown'), 0, 0);
237
+ return new Text("agent-err: " + (e?.message ?? "unknown"), 0, 0);
119
238
  }
120
239
  },
121
240
  };
@@ -124,9 +243,27 @@ export function registerSubagentTools(pi: ExtensionAPI, subagentManager: Subagen
124
243
  name: "get_subagent_result",
125
244
  label: "Get Agent Result",
126
245
  description: "Check status and retrieve results from a pi-crew background subagent.",
127
- parameters: Type.Object({ agent_id: Type.String({ description: "Agent ID returned by Agent." }), wait: Type.Optional(Type.Boolean({ description: "Wait for completion before returning." })), verbose: Type.Optional(Type.Boolean({ description: "Include status metadata before output." })) }) as never,
246
+ parameters: Type.Object({
247
+ agent_id: Type.String({
248
+ description: "Agent ID returned by Agent.",
249
+ }),
250
+ wait: Type.Optional(
251
+ Type.Boolean({
252
+ description: "Wait for completion before returning.",
253
+ }),
254
+ ),
255
+ verbose: Type.Optional(
256
+ Type.Boolean({
257
+ description: "Include status metadata before output.",
258
+ }),
259
+ ),
260
+ }) as never,
128
261
  async execute(_id, params, signal, _onUpdate, ctx) {
129
- const p = params as { agent_id?: string; wait?: boolean; verbose?: boolean };
262
+ const p = params as {
263
+ agent_id?: string;
264
+ wait?: boolean;
265
+ verbose?: boolean;
266
+ };
130
267
  if (!p.agent_id) return subagentToolResult(t("result.requiresAgentId"), {}, true);
131
268
  const inMemory = subagentManager.getRecord(p.agent_id);
132
269
  const record = inMemory ?? readPersistedSubagentRecord(ctx.cwd, p.agent_id);
@@ -134,7 +271,12 @@ export function registerSubagentTools(pi: ExtensionAPI, subagentManager: Subagen
134
271
  let current = refreshPersistedSubagentRecord(ctx, record);
135
272
  if (inMemory && current !== inMemory) Object.assign(inMemory, current);
136
273
  if (!inMemory && !current.runId && (current.status === "running" || current.status === "queued")) {
137
- current = { ...current, status: "error", error: t("result.unrecoverable"), completedAt: current.completedAt ?? Date.now() };
274
+ current = {
275
+ ...current,
276
+ status: "error",
277
+ error: t("result.unrecoverable"),
278
+ completedAt: current.completedAt ?? Date.now(),
279
+ };
138
280
  savePersistedSubagentRecord(ctx.cwd, current);
139
281
  }
140
282
  if (p.wait && (current.status === "running" || current.status === "queued")) {
@@ -149,12 +291,22 @@ export function registerSubagentTools(pi: ExtensionAPI, subagentManager: Subagen
149
291
  const maxWaitMs = 300_000; // 5 minutes
150
292
  while (current.status === "running" || current.status === "queued") {
151
293
  if (signal?.aborted) {
152
- current = { ...current, status: "error", error: t("result.waitAborted"), completedAt: Date.now() };
294
+ current = {
295
+ ...current,
296
+ status: "error",
297
+ error: t("result.waitAborted"),
298
+ completedAt: Date.now(),
299
+ };
153
300
  savePersistedSubagentRecord(ctx.cwd, current);
154
301
  break;
155
302
  }
156
303
  if (Date.now() - waitStartMs > maxWaitMs) {
157
- current = { ...current, status: "error", error: t("result.waitTimeout"), completedAt: Date.now() };
304
+ current = {
305
+ ...current,
306
+ status: "error",
307
+ error: t("result.waitTimeout"),
308
+ completedAt: Date.now(),
309
+ };
158
310
  savePersistedSubagentRecord(ctx.cwd, current);
159
311
  break;
160
312
  }
@@ -170,32 +322,85 @@ export function registerSubagentTools(pi: ExtensionAPI, subagentManager: Subagen
170
322
  if (inMemory) inMemory.resultConsumed = true;
171
323
  savePersistedSubagentRecord(ctx.cwd, current);
172
324
  }
173
- const text = [p.verbose ? formatSubagentRecord(current) : undefined, output ? `${p.verbose ? "\n" : ""}${output}` : current.status === "running" || current.status === "queued" ? t("result.stillRunning") : current.error ?? t("agent.noOutput")].filter((line): line is string => Boolean(line)).join("\n");
174
- return subagentToolResult(text, { agentId: current.id, runId: current.runId, status: current.status }, current.status === "failed" || current.status === "error");
325
+ const text = [
326
+ p.verbose ? formatSubagentRecord(current) : undefined,
327
+ output
328
+ ? `${p.verbose ? "\n" : ""}${output}`
329
+ : current.status === "running" || current.status === "queued"
330
+ ? t("result.stillRunning")
331
+ : (current.error ?? t("agent.noOutput")),
332
+ ]
333
+ .filter((line): line is string => Boolean(line))
334
+ .join("\n");
335
+ return subagentToolResult(
336
+ text,
337
+ {
338
+ agentId: current.id,
339
+ runId: current.runId,
340
+ status: current.status,
341
+ },
342
+ current.status === "failed" || current.status === "error",
343
+ );
175
344
  },
176
345
  };
177
346
 
178
347
  const steerSubagentTool: ToolDefinition = {
179
348
  name: "steer_subagent",
180
349
  label: "Steer Agent",
181
- description: "Send a steering note to a running pi-crew subagent. Live-session steering is planned; child-process runs expose durable status and can be cancelled if needed.",
182
- parameters: Type.Object({ agent_id: Type.String(), message: Type.String() }) as never,
350
+ description:
351
+ "Send a steering note to a running pi-crew subagent. Live-session steering is planned; child-process runs expose durable status and can be cancelled if needed.",
352
+ parameters: Type.Object({
353
+ agent_id: Type.String(),
354
+ message: Type.String(),
355
+ }) as never,
183
356
  async execute(_id, params, _signal, _onUpdate, ctx) {
184
357
  const p = params as { agent_id?: string; message?: string };
185
- const record = p.agent_id ? subagentManager.getRecord(p.agent_id) ?? readPersistedSubagentRecord(ctx.cwd, p.agent_id) : undefined;
358
+ const record = p.agent_id
359
+ ? (subagentManager.getRecord(p.agent_id) ?? readPersistedSubagentRecord(ctx.cwd, p.agent_id))
360
+ : undefined;
186
361
  if (!record) return subagentToolResult(t("result.notFound", { id: p.agent_id ?? "" }), {}, true);
187
- return subagentToolResult([t("steer.noted", { id: record.id }), t("steer.unavailable"), record.runId ? t("steer.cancelHint", { runId: record.runId }) : undefined].filter((line): line is string => Boolean(line)).join("\n"), { agentId: record.id, runId: record.runId, status: record.status });
362
+ return subagentToolResult(
363
+ [
364
+ t("steer.noted", { id: record.id }),
365
+ t("steer.unavailable"),
366
+ record.runId ? t("steer.cancelHint", { runId: record.runId }) : undefined,
367
+ ]
368
+ .filter((line): line is string => Boolean(line))
369
+ .join("\n"),
370
+ {
371
+ agentId: record.id,
372
+ runId: record.runId,
373
+ status: record.status,
374
+ },
375
+ );
188
376
  },
189
377
  };
190
378
 
191
- const crewAgentTool: ToolDefinition = { ...agentTool, name: "crew_agent", label: "Crew Agent", description: "Launch a real pi-crew subagent using a conflict-safe pi-crew-specific tool name.", promptSnippet: "Use crew_agent when you need pi-crew subagents and another extension may own the generic Agent tool." };
192
- const crewAgentResultTool: ToolDefinition = { ...getSubagentResultTool, name: "crew_agent_result", label: "Get Crew Agent Result", description: "Check status and retrieve results from a pi-crew subagent using the conflict-safe tool name." };
193
- const crewAgentSteerTool: ToolDefinition = { ...steerSubagentTool, name: "crew_agent_steer", label: "Steer Crew Agent", description: "Send a steering note to a pi-crew subagent using the conflict-safe tool name." };
379
+ const crewAgentTool: ToolDefinition = {
380
+ ...agentTool,
381
+ name: "crew_agent",
382
+ label: "Crew Agent",
383
+ description: "Launch a real pi-crew subagent using a conflict-safe pi-crew-specific tool name.",
384
+ promptSnippet: "Use crew_agent when you need pi-crew subagents and another extension may own the generic Agent tool.",
385
+ };
386
+ const crewAgentResultTool: ToolDefinition = {
387
+ ...getSubagentResultTool,
388
+ name: "crew_agent_result",
389
+ label: "Get Crew Agent Result",
390
+ description: "Check status and retrieve results from a pi-crew subagent using the conflict-safe tool name.",
391
+ };
392
+ const crewAgentSteerTool: ToolDefinition = {
393
+ ...steerSubagentTool,
394
+ name: "crew_agent_steer",
395
+ label: "Steer Crew Agent",
396
+ description: "Send a steering note to a pi-crew subagent using the conflict-safe tool name.",
397
+ };
194
398
  const toolConfig = loadConfig(process.cwd()).config.tools;
195
399
  const enableSteer = toolConfig?.enableSteer !== false;
196
400
  const enableClaudeStyleAliases = toolConfig?.enableClaudeStyleAliases !== false;
197
401
 
198
- for (const extraTool of enableSteer ? [crewAgentTool, crewAgentResultTool, crewAgentSteerTool] : [crewAgentTool, crewAgentResultTool]) pi.registerTool(extraTool);
402
+ for (const extraTool of enableSteer ? [crewAgentTool, crewAgentResultTool, crewAgentSteerTool] : [crewAgentTool, crewAgentResultTool])
403
+ pi.registerTool(extraTool);
199
404
  if (enableClaudeStyleAliases) {
200
405
  for (const extraTool of enableSteer ? [agentTool, getSubagentResultTool, steerSubagentTool] : [agentTool, getSubagentResultTool]) {
201
406
  try {
@@ -222,7 +427,11 @@ function startAgentToolProgress(cwd: string, agentRecordId: string, onUpdate: On
222
427
  if (loaded) {
223
428
  manifest = loaded.manifest;
224
429
  tasks = loaded.tasks;
225
- try { agents = readCrewAgents(loaded.manifest); } catch { /* ignore */ }
430
+ try {
431
+ agents = readCrewAgents(loaded.manifest);
432
+ } catch {
433
+ /* ignore */
434
+ }
226
435
  }
227
436
  }
228
437
  const text = formatCompactToolProgress({