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,14 +1,10 @@
1
- import type { TeamContext } from "../team-tool/context.ts";
2
1
  import { loadConfig, updateConfig } from "../../config/config.ts";
2
+ import { suggestConfigKey } from "../../config/suggestions.ts";
3
+ import { discoverPiThemes, formatThemesListing, setPiTheme } from "../../ui/theme-discovery.ts";
3
4
  import { configPatchFromConfig } from "../team-tool/config-patch.ts";
5
+ import type { TeamContext } from "../team-tool/context.ts";
4
6
  import { result } from "../team-tool/context.ts";
5
7
  import type { PiTeamsToolResult } from "../tool-result.ts";
6
- import { suggestConfigKey } from "../../config/suggestions.ts";
7
- import {
8
- formatThemesListing,
9
- discoverPiThemes,
10
- setPiTheme,
11
- } from "../../ui/theme-discovery.ts";
12
8
 
13
9
  // ---------------------------------------------------------------------------
14
10
  // Effective defaults — values used when config key is not set
@@ -40,9 +36,9 @@ const EFFECTIVE_DEFAULTS: Record<string, unknown> = {
40
36
  "autonomous.injectPolicy": true,
41
37
  "autonomous.preferAsyncForLongTasks": false,
42
38
  "autonomous.allowWorktreeSuggestion": true,
43
- "executeWorkers": true,
44
- "asyncByDefault": false,
45
- "notifierIntervalMs": 5000,
39
+ executeWorkers: true,
40
+ asyncByDefault: false,
41
+ notifierIntervalMs: 5000,
46
42
  "reliability.autoRetry": false,
47
43
  "reliability.autoRecover": false,
48
44
  "reliability.cleanupOrphanedTempDirs": true,
@@ -88,7 +84,11 @@ function formatValue(value: unknown, key?: string): string {
88
84
 
89
85
  function parseValue(raw: string): unknown {
90
86
  // JSON handles strings (quoted), numbers, booleans, null, arrays, objects.
91
- try { return JSON.parse(raw); } catch { /* keep as string */ }
87
+ try {
88
+ return JSON.parse(raw);
89
+ } catch {
90
+ /* keep as string */
91
+ }
92
92
  return raw;
93
93
  }
94
94
 
@@ -107,9 +107,7 @@ function flattenConfig(obj: unknown, prefix: string = ""): string[] {
107
107
  // Check if it's a "leaf object" — a value-type record like agent overrides
108
108
  // where keys are agent names and values are { model, thinking, ... }
109
109
  const entries = Object.entries(value as Record<string, unknown>);
110
- const allLeafValues = entries.every(([, v]) =>
111
- v === undefined || v === null || typeof v !== "object" || Array.isArray(v)
112
- );
110
+ const allLeafValues = entries.every(([, v]) => v === undefined || v === null || typeof v !== "object" || Array.isArray(v));
113
111
  if (allLeafValues && entries.length > 0) {
114
112
  // It's a flat record like { explorer: { model: "...", thinking: "..." } }
115
113
  // Check if nested values are objects (agent overrides pattern)
@@ -285,7 +283,10 @@ export function handleSettings(params: { config?: Record<string, unknown> }, ctx
285
283
  for (const w of loaded.warnings) lines.push(` ${w}`);
286
284
  }
287
285
  lines.push("", USAGE);
288
- return result(lines.join("\n"), { ...OK, count: flatLines.length } as never);
286
+ return result(lines.join("\n"), {
287
+ ...OK,
288
+ count: flatLines.length,
289
+ } as never);
289
290
  }
290
291
 
291
292
  // team-settings json — full JSON dump
@@ -294,7 +295,7 @@ export function handleSettings(params: { config?: Record<string, unknown> }, ctx
294
295
  `// pi-crew effective config (merged from all sources)`,
295
296
  `// Config file: ${loaded.path}`,
296
297
  `// Sources: ${loaded.paths?.join(", ") ?? loaded.path}`,
297
- ...loaded.warnings?.map(w => `// WARNING: ${w}`) ?? [],
298
+ ...(loaded.warnings?.map((w) => `// WARNING: ${w}`) ?? []),
298
299
  "",
299
300
  JSON.stringify(effective, null, 2),
300
301
  ];
@@ -310,15 +311,15 @@ export function handleSettings(params: { config?: Record<string, unknown> }, ctx
310
311
  lines.push(` ${key}${marker}`);
311
312
  }
312
313
  lines.push("", "✓ = currently set in config. Keys without ✓ use defaults.", "", USAGE);
313
- return result(lines.join("\n"), { ...OK, count: KNOWN_KEYS.size } as never);
314
+ return result(lines.join("\n"), {
315
+ ...OK,
316
+ count: KNOWN_KEYS.size,
317
+ } as never);
314
318
  }
315
319
 
316
320
  // team-settings paths — show all config file paths
317
321
  if (args === "path" || args === "paths") {
318
- const lines = [
319
- "pi-crew config paths:",
320
- ` User config: ${loaded.path}`,
321
- ];
322
+ const lines = ["pi-crew config paths:", ` User config: ${loaded.path}`];
322
323
  if (ctx.cwd && loaded.paths) {
323
324
  for (const p of loaded.paths) {
324
325
  if (p !== loaded.path) lines.push(` Additional: ${p}`);
@@ -337,7 +338,9 @@ export function handleSettings(params: { config?: Record<string, unknown> }, ctx
337
338
  if (args === "theme" || args.startsWith("theme ")) {
338
339
  const name = args === "theme" ? "" : args.slice(6).trim();
339
340
  if (!name) {
340
- const available = discoverPiThemes().map((t) => t.name).join(", ");
341
+ const available = discoverPiThemes()
342
+ .map((t) => t.name)
343
+ .join(", ");
341
344
  return result(
342
345
  `Usage: team-settings theme <name>\n\nAvailable Pi themes: ${available}\n\nBrowse all: team-settings themes`,
343
346
  { ...ERR },
@@ -356,14 +359,10 @@ export function handleSettings(params: { config?: Record<string, unknown> }, ctx
356
359
  }
357
360
  try {
358
361
  const savedTo = setPiTheme(name);
359
- return result(
360
- [
361
- `✓ Pi theme set to '${name}'`,
362
- ` Written to: ${savedTo}`,
363
- ` Applied live — no restart needed.`,
364
- ].join("\n"),
365
- { ...OK, theme: name } as never,
366
- );
362
+ return result([`✓ Pi theme set to '${name}'`, ` Written to: ${savedTo}`, ` Applied live — no restart needed.`].join("\n"), {
363
+ ...OK,
364
+ theme: name,
365
+ } as never);
367
366
  } catch (error) {
368
367
  return result(error instanceof Error ? error.message : String(error), { ...ERR }, true);
369
368
  }
@@ -382,23 +381,29 @@ export function handleSettings(params: { config?: Record<string, unknown> }, ctx
382
381
  if (args === "scope" || args.startsWith("scope ")) {
383
382
  const scopeArg = args === "scope" ? "" : args.slice(6).trim();
384
383
  if (!scopeArg) {
385
- return result([
386
- `Current write scope: ${scope}`,
387
- ` user → writes to ${loaded.path}`,
388
- ` project → writes to ${projectConfigPath(ctx.cwd)}`,
389
- "Usage: team-settings scope [user|project]",
390
- ].join("\n"), { ...OK, scope } as never);
384
+ return result(
385
+ [
386
+ `Current write scope: ${scope}`,
387
+ ` user → writes to ${loaded.path}`,
388
+ ` project writes to ${projectConfigPath(ctx.cwd)}`,
389
+ "Usage: team-settings scope [user|project]",
390
+ ].join("\n"),
391
+ { ...OK, scope } as never,
392
+ );
391
393
  }
392
394
  if (scopeArg !== "user" && scopeArg !== "project") {
393
395
  return result("Scope must be 'user' or 'project'.", { ...ERR }, true);
394
396
  }
395
- return result([
396
- `Write scope is a per-command option. Use:`,
397
- ` team-settings set <key> <value> (writes to ${scopeArg === "project" ? "project" : "user"} config)`,
398
- ``,
399
- `To change scope for a single command, pass scope in the team tool:`,
400
- ` team(action="settings", config={ args: "set <key> <value>", scope: "${scopeArg}" })`,
401
- ].join("\n"), { ...OK } as never);
397
+ return result(
398
+ [
399
+ `Write scope is a per-command option. Use:`,
400
+ ` team-settings set <key> <value> (writes to ${scopeArg === "project" ? "project" : "user"} config)`,
401
+ ``,
402
+ `To change scope for a single command, pass scope in the team tool:`,
403
+ ` team(action="settings", config={ args: "set <key> <value>", scope: "${scopeArg}" })`,
404
+ ].join("\n"),
405
+ { ...OK } as never,
406
+ );
402
407
  }
403
408
 
404
409
  // team-settings get <key>
@@ -413,7 +418,11 @@ export function handleSettings(params: { config?: Record<string, unknown> }, ctx
413
418
  if (suggestion) note = `\n(did you mean '${suggestion}'?)`;
414
419
  else note = "\n(unknown key — may not take effect)";
415
420
  }
416
- return result(`${key} = ${formatValue(value, key)}${note}`, { ...OK, key, value } as never);
421
+ return result(`${key} = ${formatValue(value, key)}${note}`, {
422
+ ...OK,
423
+ key,
424
+ value,
425
+ } as never);
417
426
  }
418
427
 
419
428
  // team-settings unset <key>
@@ -422,7 +431,10 @@ export function handleSettings(params: { config?: Record<string, unknown> }, ctx
422
431
  if (!key) return result("Usage: team-settings unset <key>", { ...ERR }, true);
423
432
  try {
424
433
  const saved = updateConfig({}, { cwd: ctx.cwd, scope, unsetPaths: [key] });
425
- return result(`Unset ${key}\nSaved to: ${saved.path}`, { ...OK, key } as never);
434
+ return result(`Unset ${key}\nSaved to: ${saved.path}`, {
435
+ ...OK,
436
+ key,
437
+ } as never);
426
438
  } catch (error) {
427
439
  return result(error instanceof Error ? error.message : String(error), { ...ERR }, true);
428
440
  }
@@ -432,7 +444,12 @@ export function handleSettings(params: { config?: Record<string, unknown> }, ctx
432
444
  if (args.startsWith("set ")) {
433
445
  const rest = args.slice(4).trim();
434
446
  const spaceIdx = rest.indexOf(" ");
435
- if (spaceIdx === -1) return result("Usage: team-settings set <key> <value>\nExample: team-settings set runtime.mode child-process", { ...ERR }, true);
447
+ if (spaceIdx === -1)
448
+ return result(
449
+ "Usage: team-settings set <key> <value>\nExample: team-settings set runtime.mode child-process",
450
+ { ...ERR },
451
+ true,
452
+ );
436
453
  const key = rest.slice(0, spaceIdx);
437
454
  const rawValue = rest.slice(spaceIdx + 1).trim();
438
455
  if (!key) return result("Usage: team-settings set <key> <value>", { ...ERR }, true);
@@ -450,23 +467,44 @@ export function handleSettings(params: { config?: Record<string, unknown> }, ctx
450
467
  let warning = "";
451
468
  if (!KNOWN_KEYS.has(key) && !key.startsWith("agents.overrides.") && !key.startsWith("ui.")) {
452
469
  const suggestion = suggestConfigKey(key, KNOWN_SORTED);
453
- warning = suggestion ? `\nWarning: unknown key. Did you mean '${suggestion}'?` : "\nWarning: unknown key — verify it exists in config schema.";
470
+ warning = suggestion
471
+ ? `\nWarning: unknown key. Did you mean '${suggestion}'?`
472
+ : "\nWarning: unknown key — verify it exists in config schema.";
454
473
  }
455
474
 
456
475
  // Check if project config would sanitize this key
457
476
  if (scope === "project") {
458
- const sensitiveKeys = ["executeWorkers", "asyncByDefault", "runtime.mode", "runtime.preferLiveSession", "runtime.allowChildProcessFallback", "runtime.inheritContext", "runtime.isolationPolicy", "autonomous.profile", "autonomous.enabled", "autonomous.injectPolicy", "agents.overrides", "agents.disableBuiltins"];
459
- if (sensitiveKeys.some(k => key === k || key.startsWith(k + "."))) {
460
- warning += "\nNote: this key is sensitive and will be ignored in project-level config for security. Set it in user scope instead.";
477
+ const sensitiveKeys = [
478
+ "executeWorkers",
479
+ "asyncByDefault",
480
+ "runtime.mode",
481
+ "runtime.preferLiveSession",
482
+ "runtime.allowChildProcessFallback",
483
+ "runtime.inheritContext",
484
+ "runtime.isolationPolicy",
485
+ "autonomous.profile",
486
+ "autonomous.enabled",
487
+ "autonomous.injectPolicy",
488
+ "agents.overrides",
489
+ "agents.disableBuiltins",
490
+ ];
491
+ if (sensitiveKeys.some((k) => key === k || key.startsWith(k + "."))) {
492
+ warning +=
493
+ "\nNote: this key is sensitive and will be ignored in project-level config for security. Set it in user scope instead.";
461
494
  }
462
495
  }
463
496
 
464
- return result([
465
- `Set ${key} = ${formatValue(value, key)}`,
466
- `Effective: ${formatValue(effectiveValue, key)}`,
467
- `Saved to: ${saved.path}`,
468
- warning,
469
- ].filter(Boolean).join("\n"), { ...OK, key, value } as never);
497
+ return result(
498
+ [
499
+ `Set ${key} = ${formatValue(value, key)}`,
500
+ `Effective: ${formatValue(effectiveValue, key)}`,
501
+ `Saved to: ${saved.path}`,
502
+ warning,
503
+ ]
504
+ .filter(Boolean)
505
+ .join("\n"),
506
+ { ...OK, key, value } as never,
507
+ );
470
508
  } catch (error) {
471
509
  return result(error instanceof Error ? error.message : String(error), { ...ERR }, true);
472
510
  }
@@ -4,17 +4,13 @@
4
4
  import * as fs from "node:fs";
5
5
  import * as os from "node:os";
6
6
  import * as path from "node:path";
7
- import { listRuns } from "../run-index.ts";
8
7
  import { readCrewAgents } from "../../runtime/crew-agent-records.ts";
9
- import {
10
- isActiveRunStatus,
11
- hasStaleAsyncProcess,
12
- isLikelyOrphanedActiveRun,
13
- } from "../../runtime/process-status.ts";
14
- import { result, type TeamContext } from "./context.ts";
8
+ import { hasStaleAsyncProcess, isActiveRunStatus, isLikelyOrphanedActiveRun } from "../../runtime/process-status.ts";
15
9
  import type { TeamToolParamsValue } from "../../schema/team-tool-schema.ts";
16
- import type { PiTeamsToolResult } from "../tool-result.ts";
17
10
  import type { TeamRunManifest, TeamTaskState } from "../../state/types.ts";
11
+ import { listRuns } from "../run-index.ts";
12
+ import type { PiTeamsToolResult } from "../tool-result.ts";
13
+ import { result, type TeamContext } from "./context.ts";
18
14
 
19
15
  // ── Types ────────────────────────────────────────────────────────────
20
16
 
@@ -69,9 +65,7 @@ export const STUCK_TASK_THRESHOLD_MS = 5 * 60 * 1000; // 5 minutes
69
65
  function readRunTasks(stateRoot: string): TeamTaskState[] {
70
66
  const tasksPath = path.join(stateRoot, "tasks.json");
71
67
  try {
72
- return JSON.parse(
73
- fs.readFileSync(tasksPath, "utf-8"),
74
- ) as TeamTaskState[];
68
+ return JSON.parse(fs.readFileSync(tasksPath, "utf-8")) as TeamTaskState[];
75
69
  } catch {
76
70
  return [];
77
71
  }
@@ -81,10 +75,7 @@ function readRunTasks(stateRoot: string): TeamTaskState[] {
81
75
  * Detect "stuck" tasks: tasks with status "running" whose last heartbeat or
82
76
  * activity timestamp is older than STUCK_TASK_THRESHOLD_MS.
83
77
  */
84
- export function detectStuckTasks(
85
- run: { runId: string; stateRoot: string },
86
- now: number,
87
- ): StuckTask[] {
78
+ export function detectStuckTasks(run: { runId: string; stateRoot: string }, now: number): StuckTask[] {
88
79
  const tasks = readRunTasks(run.stateRoot);
89
80
  const stuck: StuckTask[] = [];
90
81
 
@@ -92,23 +83,14 @@ export function detectStuckTasks(
92
83
  if (task.status !== "running") continue;
93
84
 
94
85
  // Check agentProgress.lastActivityAt first, then heartbeat.lastSeenAt, then startedAt
95
- const activityAt = task.agentProgress?.lastActivityAt
96
- ? new Date(task.agentProgress.lastActivityAt).getTime()
97
- : Number.NaN;
98
- const heartbeatAt = task.heartbeat?.lastSeenAt
99
- ? new Date(task.heartbeat.lastSeenAt).getTime()
100
- : Number.NaN;
101
- const startedAt = task.startedAt
102
- ? new Date(task.startedAt).getTime()
103
- : Number.NaN;
86
+ const activityAt = task.agentProgress?.lastActivityAt ? new Date(task.agentProgress.lastActivityAt).getTime() : Number.NaN;
87
+ const heartbeatAt = task.heartbeat?.lastSeenAt ? new Date(task.heartbeat.lastSeenAt).getTime() : Number.NaN;
88
+ const startedAt = task.startedAt ? new Date(task.startedAt).getTime() : Number.NaN;
104
89
 
105
90
  // Use the most recent valid timestamp
106
91
  let latest = Number.NaN;
107
92
  for (const ts of [activityAt, heartbeatAt, startedAt]) {
108
- if (
109
- Number.isFinite(ts) &&
110
- (!Number.isFinite(latest) || ts > latest)
111
- ) {
93
+ if (Number.isFinite(ts) && (!Number.isFinite(latest) || ts > latest)) {
112
94
  latest = ts;
113
95
  }
114
96
  }
@@ -135,40 +117,25 @@ export function detectStuckTasks(
135
117
  * Read-only — does NOT mutate anything.
136
118
  * Pattern adapted from stale-reconciler.ts:reconcileOrphanedTempWorkspaces().
137
119
  */
138
- export function scanZombieTempWorkspaces(
139
- tmpDir: string,
140
- now: number,
141
- ): ZombieWorkspace[] {
120
+ export function scanZombieTempWorkspaces(tmpDir: string, now: number): ZombieWorkspace[] {
142
121
  if (!tmpDir || !fs.existsSync(tmpDir)) return [];
143
122
  const zombies: ZombieWorkspace[] = [];
144
123
 
145
124
  try {
146
125
  const entries = fs.readdirSync(tmpDir, { withFileTypes: true });
147
126
  for (const entry of entries) {
148
- if (!entry.isDirectory() || !entry.name.startsWith("pi-crew-"))
149
- continue;
127
+ if (!entry.isDirectory() || !entry.name.startsWith("pi-crew-")) continue;
150
128
  const workspaceDir = path.join(tmpDir, entry.name);
151
- const stateRunsDir = path.join(
152
- workspaceDir,
153
- ".crew",
154
- "state",
155
- "runs",
156
- );
129
+ const stateRunsDir = path.join(workspaceDir, ".crew", "state", "runs");
157
130
  if (!fs.existsSync(stateRunsDir)) continue;
158
131
 
159
132
  let runCount = 0;
160
133
  try {
161
134
  for (const runDir of fs.readdirSync(stateRunsDir)) {
162
- const manifestPath = path.join(
163
- stateRunsDir,
164
- runDir,
165
- "manifest.json",
166
- );
135
+ const manifestPath = path.join(stateRunsDir, runDir, "manifest.json");
167
136
  if (fs.existsSync(manifestPath)) {
168
137
  try {
169
- const manifest = JSON.parse(
170
- fs.readFileSync(manifestPath, "utf-8"),
171
- ) as { runId?: string; status?: string };
138
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8")) as { runId?: string; status?: string };
172
139
  if (manifest.runId) runCount++;
173
140
  } catch {
174
141
  /* skip corrupt manifest */
@@ -224,29 +191,16 @@ export function collectTempWorkspaceRuns(
224
191
  try {
225
192
  const entries = fs.readdirSync(tmpDir, { withFileTypes: true });
226
193
  for (const entry of entries) {
227
- if (!entry.isDirectory() || !entry.name.startsWith("pi-crew-"))
228
- continue;
229
- const stateRunsDir = path.join(
230
- tmpDir,
231
- entry.name,
232
- ".crew",
233
- "state",
234
- "runs",
235
- );
194
+ if (!entry.isDirectory() || !entry.name.startsWith("pi-crew-")) continue;
195
+ const stateRunsDir = path.join(tmpDir, entry.name, ".crew", "state", "runs");
236
196
  if (!fs.existsSync(stateRunsDir)) continue;
237
197
 
238
198
  try {
239
199
  for (const runDir of fs.readdirSync(stateRunsDir)) {
240
- const manifestPath = path.join(
241
- stateRunsDir,
242
- runDir,
243
- "manifest.json",
244
- );
200
+ const manifestPath = path.join(stateRunsDir, runDir, "manifest.json");
245
201
  if (!fs.existsSync(manifestPath)) continue;
246
202
  try {
247
- const manifest = JSON.parse(
248
- fs.readFileSync(manifestPath, "utf-8"),
249
- ) as {
203
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8")) as {
250
204
  runId?: string;
251
205
  status?: string;
252
206
  cwd?: string;
@@ -256,15 +210,8 @@ export function collectTempWorkspaceRuns(
256
210
  updatedAt?: string;
257
211
  summary?: string;
258
212
  };
259
- if (!manifest.runId || primaryIds.has(manifest.runId))
260
- continue;
261
- if (
262
- manifest.status &&
263
- manifest.cwd &&
264
- manifest.stateRoot &&
265
- manifest.artifactsRoot &&
266
- manifest.updatedAt
267
- ) {
213
+ if (!manifest.runId || primaryIds.has(manifest.runId)) continue;
214
+ if (manifest.status && manifest.cwd && manifest.stateRoot && manifest.artifactsRoot && manifest.updatedAt) {
268
215
  runs.push({
269
216
  runId: manifest.runId!,
270
217
  status: manifest.status,
@@ -296,18 +243,7 @@ export function collectTempWorkspaceRuns(
296
243
  */
297
244
  export function countStatuses(
298
245
  runs: Array<{ status: string }>,
299
- ): Pick<
300
- HealthCounts,
301
- | "total"
302
- | "running"
303
- | "completed"
304
- | "failed"
305
- | "cancelled"
306
- | "blocked"
307
- | "queued"
308
- | "planning"
309
- | "waiting"
310
- > {
246
+ ): Pick<HealthCounts, "total" | "running" | "completed" | "failed" | "cancelled" | "blocked" | "queued" | "planning" | "waiting"> {
311
247
  const counts = {
312
248
  total: runs.length,
313
249
  running: 0,
@@ -392,11 +328,7 @@ export function buildHealthReport(
392
328
 
393
329
  for (const run of allRuns) {
394
330
  // 1. Ghost: active status but cwd no longer exists
395
- if (
396
- isActiveRunStatus(run.status) &&
397
- run.cwd &&
398
- !fs.existsSync(run.cwd)
399
- ) {
331
+ if (isActiveRunStatus(run.status) && run.cwd && !fs.existsSync(run.cwd)) {
400
332
  ghost.push({
401
333
  runId: run.runId,
402
334
  reason: "dead-cwd",
@@ -406,10 +338,7 @@ export function buildHealthReport(
406
338
  }
407
339
 
408
340
  // 2. Corrupted: state root or artifacts root missing
409
- if (
410
- !fs.existsSync(run.stateRoot) ||
411
- !fs.existsSync(run.artifactsRoot)
412
- ) {
341
+ if (!fs.existsSync(run.stateRoot) || !fs.existsSync(run.artifactsRoot)) {
413
342
  corrupted.push({
414
343
  runId: run.runId,
415
344
  reason: "missing-state-or-artifacts",
@@ -514,19 +443,12 @@ export function buildHealthReport(
514
443
  if (zombieWorkspaces.length > 0) {
515
444
  lines.push("Zombie /tmp/ workspaces:");
516
445
  for (const z of zombieWorkspaces) {
517
- lines.push(
518
- ` - ${z.dir} (${z.runCount} run${z.runCount !== 1 ? "s" : ""})`,
519
- );
446
+ lines.push(` - ${z.dir} (${z.runCount} run${z.runCount !== 1 ? "s" : ""})`);
520
447
  }
521
448
  lines.push("");
522
449
  }
523
450
 
524
- const hasIssues =
525
- ghost.length > 0 ||
526
- orphaned.length > 0 ||
527
- corrupted.length > 0 ||
528
- allStuck.length > 0 ||
529
- zombieWorkspaces.length > 0;
451
+ const hasIssues = ghost.length > 0 || orphaned.length > 0 || corrupted.length > 0 || allStuck.length > 0 || zombieWorkspaces.length > 0;
530
452
 
531
453
  if (!hasIssues) {
532
454
  lines.push("All runs healthy.");
@@ -544,10 +466,7 @@ export function buildHealthReport(
544
466
 
545
467
  // ── Main handler ─────────────────────────────────────────────────────
546
468
 
547
- export function handleHealthMonitor(
548
- ctx: TeamContext,
549
- params: TeamToolParamsValue,
550
- ): PiTeamsToolResult {
469
+ export function handleHealthMonitor(ctx: TeamContext, params: TeamToolParamsValue): PiTeamsToolResult {
551
470
  const { text, counts, hasIssues } = buildHealthReport(ctx, params);
552
471
 
553
472
  return result(
@@ -1,12 +1,12 @@
1
1
  import type { TeamToolParamsValue } from "../../schema/team-tool-schema.ts";
2
2
  import { readEvents } from "../../state/event-log.ts";
3
3
  import { loadRunManifestById } from "../../state/state-store.ts";
4
- import { aggregateUsage, formatUsage, formatCostReport } from "../../state/usage.ts";
5
- import type { PiTeamsToolResult } from "../tool-result.ts";
4
+ import { aggregateUsage, formatCostReport, formatUsage } from "../../state/usage.ts";
6
5
  import { locateRunCwd } from "../team-tool.ts";
6
+ import type { PiTeamsToolResult } from "../tool-result.ts";
7
7
  import { result, type TeamContext } from "./context.ts";
8
- import { RUN_NOT_FOUND_HINT } from "./run-not-found.ts";
9
8
  import { formatFailurePatterns } from "./failure-patterns.ts";
9
+ import { RUN_NOT_FOUND_HINT } from "./run-not-found.ts";
10
10
 
11
11
  export function handleEvents(params: TeamToolParamsValue, ctx: TeamContext): PiTeamsToolResult {
12
12
  if (!params.runId) return result("Events requires runId.", { action: "events", status: "error" }, true);
@@ -15,8 +15,21 @@ export function handleEvents(params: TeamToolParamsValue, ctx: TeamContext): PiT
15
15
  const loaded = loadRunManifestById(runCwd, params.runId); // NOTE: no withRunLock - best-effort only; concurrent writes may cause inconsistency
16
16
  if (!loaded) return result(`Run '${params.runId}' not found.${RUN_NOT_FOUND_HINT}`, { action: "events", status: "error" }, true);
17
17
  const events = readEvents(loaded.manifest.eventsPath);
18
- const lines = [`Events for ${loaded.manifest.runId}:`, ...(events.length ? events.map((event) => `${event.time} ${event.type}${event.taskId ? ` ${event.taskId}` : ""}${event.message ? `: ${event.message}` : ""}${event.data ? ` ${JSON.stringify(event.data)}` : ""}`) : ["(none)"])];
19
- return result(lines.join("\n"), { action: "events", status: "ok", runId: loaded.manifest.runId, artifactsRoot: loaded.manifest.artifactsRoot });
18
+ const lines = [
19
+ `Events for ${loaded.manifest.runId}:`,
20
+ ...(events.length
21
+ ? events.map(
22
+ (event) =>
23
+ `${event.time} ${event.type}${event.taskId ? ` ${event.taskId}` : ""}${event.message ? `: ${event.message}` : ""}${event.data ? ` ${JSON.stringify(event.data)}` : ""}`,
24
+ )
25
+ : ["(none)"]),
26
+ ];
27
+ return result(lines.join("\n"), {
28
+ action: "events",
29
+ status: "ok",
30
+ runId: loaded.manifest.runId,
31
+ artifactsRoot: loaded.manifest.artifactsRoot,
32
+ });
20
33
  }
21
34
 
22
35
  export function handleArtifacts(params: TeamToolParamsValue, ctx: TeamContext): PiTeamsToolResult {
@@ -25,8 +38,21 @@ export function handleArtifacts(params: TeamToolParamsValue, ctx: TeamContext):
25
38
  if (!runCwd) return result(`Run '${params.runId}' not found.${RUN_NOT_FOUND_HINT}`, { action: "artifacts", status: "error" }, true);
26
39
  const loaded = loadRunManifestById(runCwd, params.runId); // NOTE: no withRunLock - best-effort only; concurrent writes may cause inconsistency
27
40
  if (!loaded) return result(`Run '${params.runId}' not found.${RUN_NOT_FOUND_HINT}`, { action: "artifacts", status: "error" }, true);
28
- const lines = [`Artifacts for ${loaded.manifest.runId}:`, ...(loaded.manifest.artifacts.length ? loaded.manifest.artifacts.map((artifact) => `- ${artifact.kind}: ${artifact.path}${artifact.sizeBytes !== undefined ? ` (${artifact.sizeBytes} bytes)` : ""}${artifact.contentHash ? ` sha256=${artifact.contentHash.slice(0, 12)}` : ""}`) : ["- (none)"])];
29
- return result(lines.join("\n"), { action: "artifacts", status: "ok", runId: loaded.manifest.runId, artifactsRoot: loaded.manifest.artifactsRoot });
41
+ const lines = [
42
+ `Artifacts for ${loaded.manifest.runId}:`,
43
+ ...(loaded.manifest.artifacts.length
44
+ ? loaded.manifest.artifacts.map(
45
+ (artifact) =>
46
+ `- ${artifact.kind}: ${artifact.path}${artifact.sizeBytes !== undefined ? ` (${artifact.sizeBytes} bytes)` : ""}${artifact.contentHash ? ` sha256=${artifact.contentHash.slice(0, 12)}` : ""}`,
47
+ )
48
+ : ["- (none)"]),
49
+ ];
50
+ return result(lines.join("\n"), {
51
+ action: "artifacts",
52
+ status: "ok",
53
+ runId: loaded.manifest.runId,
54
+ artifactsRoot: loaded.manifest.artifactsRoot,
55
+ });
30
56
  }
31
57
 
32
58
  export function handleSummary(params: TeamToolParamsValue, ctx: TeamContext): PiTeamsToolResult {
@@ -49,7 +75,14 @@ export function handleSummary(params: TeamToolParamsValue, ctx: TeamContext): Pi
49
75
  ...(failurePatternLines.length > 0 ? ["", ...failurePatternLines] : []),
50
76
  "",
51
77
  "Tasks:",
52
- ...loaded.tasks.map((task) => `- ${task.id}: ${task.status} (${task.role} -> ${task.agent})${task.error ? ` - ${task.error}` : ""}`),
78
+ ...loaded.tasks.map(
79
+ (task) => `- ${task.id}: ${task.status} (${task.role} -> ${task.agent})${task.error ? ` - ${task.error}` : ""}`,
80
+ ),
53
81
  ];
54
- return result(lines.join("\n"), { action: "summary", status: "ok", runId: loaded.manifest.runId, artifactsRoot: loaded.manifest.artifactsRoot });
82
+ return result(lines.join("\n"), {
83
+ action: "summary",
84
+ status: "ok",
85
+ runId: loaded.manifest.runId,
86
+ artifactsRoot: loaded.manifest.artifactsRoot,
87
+ });
55
88
  }
@@ -36,7 +36,10 @@ export function enforceDestructiveIntent(
36
36
  const label = DESTRUCTIVE_ACTION_LABELS[action];
37
37
  return result(
38
38
  `Destructive action '${label}' requires config.intent when policy.requireIntentForDestructiveActions is enabled.`,
39
- { action: action === "delete" ? "management" : action, status: "error" },
39
+ {
40
+ action: action === "delete" ? "management" : action,
41
+ status: "error",
42
+ },
40
43
  true,
41
44
  );
42
45
  }