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,32 +1,32 @@
1
1
  import * as fs from "node:fs";
2
- import type { TeamRunManifest, TeamTaskState, UsageState } from "../state/types.ts";
2
+ import type { MetricRegistry } from "../observability/metric-registry.ts";
3
3
  import { readCrewAgents } from "../runtime/crew-agent-records.ts";
4
- import { getLiveAgentContextPercent } from "../runtime/live-agent-manager.ts";
5
4
  import type { CrewAgentRecord } from "../runtime/crew-agent-runtime.ts";
5
+ import { getLiveAgentContextPercent } from "../runtime/live-agent-manager.ts";
6
6
  import { isDisplayActiveRun, isLikelyOrphanedActiveRun } from "../runtime/process-status.ts";
7
- import { readJsonFileCoalesced } from "../utils/file-coalescer.ts";
8
- import type { CrewTheme } from "./theme-adapter.ts";
9
- import { asCrewTheme, subscribeThemeChange } from "./theme-adapter.ts";
10
- import { applyStatusColor, colorizeStatusGlyphs, iconForStatus, type RunStatus } from "./status-colors.ts";
11
- import { pad, truncate, sanitizeLine, visibleWidth } from "../utils/visual.ts";
12
- import { Box, Text } from "./layout-primitives.ts";
13
- import { DynamicCrewBorder } from "./dynamic-border.ts";
7
+ import type { TeamRunManifest, TeamTaskState, UsageState } from "../state/types.ts";
14
8
  import { aggregateUsage } from "../state/usage.ts";
9
+ import { readJsonFileCoalesced } from "../utils/file-coalescer.ts";
15
10
  import { logInternalError } from "../utils/internal-error.ts";
11
+ import { resolveRealContainedPath } from "../utils/safe-paths.ts";
12
+ import { pad, sanitizeLine, truncate, visibleWidth } from "../utils/visual.ts";
16
13
  import { renderAgentsPane } from "./dashboard-panes/agents-pane.ts";
14
+ import { summarizeTerminalReason } from "./dashboard-panes/cancellation-pane.ts";
15
+ import { renderHealthPane } from "./dashboard-panes/health-pane.ts";
17
16
  import { renderMailboxPane } from "./dashboard-panes/mailbox-pane.ts";
17
+ import { renderMetricsPane } from "./dashboard-panes/metrics-pane.ts";
18
18
  import { renderProgressPane } from "./dashboard-panes/progress-pane.ts";
19
19
  import { renderTranscriptPane } from "./dashboard-panes/transcript-pane.ts";
20
- import { renderHealthPane } from "./dashboard-panes/health-pane.ts";
21
- import { renderMetricsPane } from "./dashboard-panes/metrics-pane.ts";
22
- import { summarizeTerminalReason } from "./dashboard-panes/cancellation-pane.ts";
23
- import { HelpOverlay } from "./overlays/help-overlay.ts";
20
+ import { DynamicCrewBorder } from "./dynamic-border.ts";
24
21
  import { dashboardActionForKey } from "./keybinding-map.ts";
22
+ import { Box, Text } from "./layout-primitives.ts";
23
+ import { HelpOverlay } from "./overlays/help-overlay.ts";
24
+ import { runEventBus } from "./run-event-bus.ts";
25
25
  import type { RunSnapshotCache, RunUiSnapshot } from "./snapshot-types.ts";
26
26
  import { spinnerBucket, spinnerFrame } from "./spinner.ts";
27
- import type { MetricRegistry } from "../observability/metric-registry.ts";
28
- import { resolveRealContainedPath } from "../utils/safe-paths.ts";
29
- import { runEventBus } from "./run-event-bus.ts";
27
+ import { applyStatusColor, colorizeStatusGlyphs, iconForStatus, type RunStatus } from "./status-colors.ts";
28
+ import type { CrewTheme } from "./theme-adapter.ts";
29
+ import { asCrewTheme, subscribeThemeChange } from "./theme-adapter.ts";
30
30
 
31
31
  interface DashboardComponent {
32
32
  invalidate(): void;
@@ -66,7 +66,24 @@ export interface RunDashboardOptions {
66
66
  */
67
67
  let lastActivePane: "agents" | "progress" | "mailbox" | "output" | "health" | "metrics" = "agents";
68
68
 
69
- export type RunDashboardAction = "status" | "summary" | "artifacts" | "api" | "events" | "agents" | "agent-events" | "agent-output" | "agent-transcript" | "agent-live" | "mailbox" | "reload" | "mailbox-detail" | "health-recovery" | "health-kill-stale" | "health-diagnostic-export" | "notifications-dismiss";
69
+ export type RunDashboardAction =
70
+ | "status"
71
+ | "summary"
72
+ | "artifacts"
73
+ | "api"
74
+ | "events"
75
+ | "agents"
76
+ | "agent-events"
77
+ | "agent-output"
78
+ | "agent-transcript"
79
+ | "agent-live"
80
+ | "mailbox"
81
+ | "reload"
82
+ | "mailbox-detail"
83
+ | "health-recovery"
84
+ | "health-kill-stale"
85
+ | "health-diagnostic-export"
86
+ | "notifications-dismiss";
70
87
  export interface RunDashboardSelection {
71
88
  runId: string;
72
89
  action: RunDashboardAction;
@@ -199,7 +216,8 @@ function agentPreviewLine(agent: CrewAgentRecord, task: TeamTaskState | undefine
199
216
  agent.progress?.activityState,
200
217
  options.showModel !== false && modelForAgent(agent, task) ? `model=${modelForAgent(agent, task)}` : undefined,
201
218
  options.showTokens !== false
202
- ? formatTokens(usageForAgent(agent, task)) ?? (agent.progress?.tokens !== undefined ? `tok=${agent.progress.tokens}` : undefined)
219
+ ? (formatTokens(usageForAgent(agent, task)) ??
220
+ (agent.progress?.tokens !== undefined ? `tok=${agent.progress.tokens}` : undefined))
203
221
  : undefined,
204
222
  options.showTools !== false && agent.progress?.currentTool ? `tool=${agent.progress.currentTool}` : undefined,
205
223
  options.showTools !== false && agent.toolUses !== undefined ? `${agent.toolUses} tools` : undefined,
@@ -208,8 +226,12 @@ function agentPreviewLine(agent: CrewAgentRecord, task: TeamTaskState | undefine
208
226
  agent.startedAt ? `age=${formatAge(agent.completedAt ?? agent.startedAt)}` : undefined,
209
227
  ].filter((part): part is string => Boolean(part));
210
228
  const recent = agent.progress?.recentOutput?.at(-1);
211
- const icon = iconForStatus(agent.status, { runningGlyph: spinnerFrame(agent.taskId) });
212
- return sanitizeLine(`Agent: ${icon} ${agent.taskId} ${agent.role}->${agent.agent}${stats.length ? ` · ${stats.join(" · ")}` : ""}${recent ? ` ⎿ ${recent}` : ""}`);
229
+ const icon = iconForStatus(agent.status, {
230
+ runningGlyph: spinnerFrame(agent.taskId),
231
+ });
232
+ return sanitizeLine(
233
+ `Agent: ${icon} ${agent.taskId} ${agent.role}->${agent.agent}${stats.length ? ` · ${stats.join(" · ")}` : ""}${recent ? ` ⎿ ${recent}` : ""}`,
234
+ );
213
235
  }
214
236
 
215
237
  function readAgentPreview(run: TeamRunManifest, maxLines = 5, options: RunDashboardOptions = {}): string[] {
@@ -218,20 +240,27 @@ function readAgentPreview(run: TeamRunManifest, maxLines = 5, options: RunDashbo
218
240
  const agents = snapshot?.agents ?? readCrewAgents(run);
219
241
  const tasks = snapshot?.tasks ?? readRunTasks(run, options.snapshotCache);
220
242
  if (!agents.length) return ["Agents: (none)"];
221
- const totals = tasks.reduce((acc, task) => {
222
- acc.input += task.usage?.input ?? 0;
223
- acc.output += task.usage?.output ?? 0;
224
- acc.cacheRead += task.usage?.cacheRead ?? 0;
225
- acc.cacheWrite += task.usage?.cacheWrite ?? 0;
226
- acc.cost += task.usage?.cost ?? 0;
227
- return acc;
228
- }, { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0 } as { input: number; output: number; cacheRead: number; cacheWrite: number; cost: number });
243
+ const totals = tasks.reduce(
244
+ (acc, task) => {
245
+ acc.input += task.usage?.input ?? 0;
246
+ acc.output += task.usage?.output ?? 0;
247
+ acc.cacheRead += task.usage?.cacheRead ?? 0;
248
+ acc.cacheWrite += task.usage?.cacheWrite ?? 0;
249
+ acc.cost += task.usage?.cost ?? 0;
250
+ return acc;
251
+ },
252
+ { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0 } as {
253
+ input: number;
254
+ output: number;
255
+ cacheRead: number;
256
+ cacheWrite: number;
257
+ cost: number;
258
+ },
259
+ );
229
260
  const header = formatTokens(totals) ? `Agents: ${formatTokens(totals)}` : "Agents:";
230
261
  return [
231
262
  header,
232
- ...agents
233
- .slice(0, maxLines)
234
- .map((agent) => agentPreviewLine(agent, taskForAgent(tasks, agent), options)),
263
+ ...agents.slice(0, maxLines).map((agent) => agentPreviewLine(agent, taskForAgent(tasks, agent), options)),
235
264
  ...(agents.length > maxLines ? [`Agents: +${agents.length - maxLines} more`] : []),
236
265
  ];
237
266
  } catch (error) {
@@ -255,10 +284,18 @@ function runLabel(run: TeamRunManifest, selected: boolean, snapshotCache?: RunSn
255
284
  const stale = isLikelyOrphanedActiveRun(run, agents);
256
285
  const running = agents.find((agent) => agent.status === "running");
257
286
  const queued = agents.find((agent) => agent.status === "queued");
258
- const step = stale ? "orphaned queued run" : running ? `step ${running.taskId}` : queued ? `queued ${queued.taskId}` : `agents ${agents.length}`;
287
+ const step = stale
288
+ ? "orphaned queued run"
289
+ : running
290
+ ? `step ${running.taskId}`
291
+ : queued
292
+ ? `queued ${queued.taskId}`
293
+ : `agents ${agents.length}`;
259
294
  const status: RunStatus = stale ? "stale" : (run.status as RunStatus);
260
295
  const marker = selected ? "›" : " ";
261
- const icon = iconForStatus(status, { runningGlyph: spinnerFrame(run.runId) });
296
+ const icon = iconForStatus(status, {
297
+ runningGlyph: spinnerFrame(run.runId),
298
+ });
262
299
  // L-5: unified " · " separator (was "|").
263
300
  // L-3: keep the GOAL (the human identifier) visible on narrow terminals —
264
301
  // when the full line overflows, sacrifice the meta prefix (runId/status
@@ -304,8 +341,12 @@ function resolveRuns(runs: TeamRunManifest[], snapshotCache?: RunSnapshotCache):
304
341
  function groupedRuns(runs: TeamRunManifest[], snapshotCache?: RunSnapshotCache): Array<{ label: string; run?: TeamRunManifest }> {
305
342
  const resolved = resolveRuns(runs, snapshotCache);
306
343
  const rows: Array<{ label: string; run?: TeamRunManifest }> = [];
307
- const active = runs.filter((run) => isDisplayActiveRun(resolved.get(run.runId)?.snapshot?.manifest ?? run, resolved.get(run.runId)?.agents ?? []));
308
- const rest = runs.filter((run) => !isDisplayActiveRun(resolved.get(run.runId)?.snapshot?.manifest ?? run, resolved.get(run.runId)?.agents ?? []));
344
+ const active = runs.filter((run) =>
345
+ isDisplayActiveRun(resolved.get(run.runId)?.snapshot?.manifest ?? run, resolved.get(run.runId)?.agents ?? []),
346
+ );
347
+ const rest = runs.filter(
348
+ (run) => !isDisplayActiveRun(resolved.get(run.runId)?.snapshot?.manifest ?? run, resolved.get(run.runId)?.agents ?? []),
349
+ );
309
350
  if (active.length) rows.push({ label: "Active" }, ...active.map((run) => ({ label: run.runId, run })));
310
351
  if (rest.length) rows.push({ label: "Recent" }, ...rest.map((run) => ({ label: run.runId, run })));
311
352
  return rows;
@@ -355,11 +396,15 @@ export class RunDashboard implements DashboardComponent {
355
396
  this.options = options;
356
397
  this.unsubscribeTheme = subscribeThemeChange(theme, () => this.invalidateAndRender());
357
398
  this.unsubscribeEventBus = (() => {
358
- const unsub1 = runEventBus.onChannel("run:state", () => this.invalidateAndRender());
359
- const unsub2 = runEventBus.onChannel("worker:lifecycle", () => this.invalidateAndRender());
360
- const unsub3 = runEventBus.onChannel("ui:invalidate", () => this.invalidateAndRender());
361
- return () => { unsub1(); unsub2(); unsub3(); };
362
- })();
399
+ const unsub1 = runEventBus.onChannel("run:state", () => this.invalidateAndRender());
400
+ const unsub2 = runEventBus.onChannel("worker:lifecycle", () => this.invalidateAndRender());
401
+ const unsub3 = runEventBus.onChannel("ui:invalidate", () => this.invalidateAndRender());
402
+ return () => {
403
+ unsub1();
404
+ unsub2();
405
+ unsub3();
406
+ };
407
+ })();
363
408
  }
364
409
 
365
410
  /**
@@ -373,7 +418,11 @@ export class RunDashboard implements DashboardComponent {
373
418
  */
374
419
  private invalidateAndRender(): void {
375
420
  this.invalidate();
376
- try { this.options.requestRender?.(); } catch { /* host may not expose requestRender */ }
421
+ try {
422
+ this.options.requestRender?.();
423
+ } catch {
424
+ /* host may not expose requestRender */
425
+ }
377
426
  }
378
427
 
379
428
  /**
@@ -396,7 +445,9 @@ export class RunDashboard implements DashboardComponent {
396
445
  const next = this.options.runProvider();
397
446
  this.runs = Array.isArray(next) ? next : this.runs;
398
447
  if (selectedRunId) {
399
- const nextIndex = groupedRuns(this.runs, this.options.snapshotCache).filter((row) => row.run).findIndex((row) => row.run?.runId === selectedRunId);
448
+ const nextIndex = groupedRuns(this.runs, this.options.snapshotCache)
449
+ .filter((row) => row.run)
450
+ .findIndex((row) => row.run?.runId === selectedRunId);
400
451
  if (nextIndex >= 0) this.selected = nextIndex;
401
452
  else this.selected = 0;
402
453
  }
@@ -428,16 +479,19 @@ export class RunDashboard implements DashboardComponent {
428
479
 
429
480
  private buildSignature(): string {
430
481
  let hasRunning = false;
431
- const statuses = this.runs.map((run) => {
432
- const snapshot = snapshotFor(run, this.options.snapshotCache);
433
- const displayRun = snapshot?.manifest ?? run;
434
- const agents = snapshot?.agents ?? agentsFor(run, this.options.snapshotCache);
435
- const stale = isLikelyOrphanedActiveRun(displayRun, agents);
436
- const status: RunStatus = stale ? "stale" : (displayRun.status as RunStatus);
437
- if (status === "running" || agents.some((agent) => agent.status === "running")) hasRunning = true;
438
- return snapshot?.signature ?? `${displayRun.runId}:${displayRun.status}:${displayRun.updatedAt}:${status}`;
439
- }).join("|");
440
- const metricsSig = this.activePane === "metrics" ? `:metrics=${this.options.registry?.snapshot().length ?? 0}:${spinnerBucket()}` : "";
482
+ const statuses = this.runs
483
+ .map((run) => {
484
+ const snapshot = snapshotFor(run, this.options.snapshotCache);
485
+ const displayRun = snapshot?.manifest ?? run;
486
+ const agents = snapshot?.agents ?? agentsFor(run, this.options.snapshotCache);
487
+ const stale = isLikelyOrphanedActiveRun(displayRun, agents);
488
+ const status: RunStatus = stale ? "stale" : (displayRun.status as RunStatus);
489
+ if (status === "running" || agents.some((agent) => agent.status === "running")) hasRunning = true;
490
+ return snapshot?.signature ?? `${displayRun.runId}:${displayRun.status}:${displayRun.updatedAt}:${status}`;
491
+ })
492
+ .join("|");
493
+ const metricsSig =
494
+ this.activePane === "metrics" ? `:metrics=${this.options.registry?.snapshot().length ?? 0}:${spinnerBucket()}` : "";
441
495
  return `${this.selected}:${this.showHelp ? 1 : 0}:${this.showFullProgress ? 1 : 0}:${this.activePane}:${statuses}${hasRunning ? `:spin=${spinnerBucket()}` : ""}${metricsSig}`;
442
496
  }
443
497
 
@@ -460,10 +514,7 @@ export class RunDashboard implements DashboardComponent {
460
514
  return this.renderUnsafe(width);
461
515
  } catch (error) {
462
516
  logInternalError("run-dashboard.render", error);
463
- return renderLines([
464
- "Dashboard error — see logs for details.",
465
- "Press r to reload · Esc to close.",
466
- ], width);
517
+ return renderLines(["Dashboard error — see logs for details.", "Press r to reload · Esc to close."], width);
467
518
  }
468
519
  }
469
520
 
@@ -478,7 +529,7 @@ export class RunDashboard implements DashboardComponent {
478
529
  const border = (left: string, right: string) => `${fg("border", left)}${borderFill(borderWidth)}${fg("border", right)}`;
479
530
  const row = (text: string) => `│ ${pad(truncate(text, innerWidth - 1), innerWidth - 1)}│`;
480
531
  const sep = () => border("├", "┤");
481
-
532
+
482
533
  const lines: string[] = [];
483
534
  if (this.showHelp) {
484
535
  // K-1: help overlay replaces the dashboard body until dismissed.
@@ -486,7 +537,9 @@ export class RunDashboard implements DashboardComponent {
486
537
  } else {
487
538
  lines.push(
488
539
  border("╭", "╮"),
489
- row(`${fg("accent", "▐")} ${this.theme.bold("pi-crew")} · ${this.runs.length} runs ${fg("dim", "1-6 pane · ↑↓ · Enter · ? help · Esc")}`),
540
+ row(
541
+ `${fg("accent", "▐")} ${this.theme.bold("pi-crew")} · ${this.runs.length} runs ${fg("dim", "1-6 pane · ↑↓ · Enter · ? help · Esc")}`,
542
+ ),
490
543
  sep(),
491
544
  );
492
545
 
@@ -504,7 +557,10 @@ export class RunDashboard implements DashboardComponent {
504
557
  if (selectableCount <= RUN_LIST_MAX) {
505
558
  // Common case (≤8 runs): keep the Active/Recent group headers.
506
559
  for (const rowItem of allGrouped) {
507
- if (!rowItem.run) { lines.push(row(fg("dim", `── ${rowItem.label} ──`))); continue; }
560
+ if (!rowItem.run) {
561
+ lines.push(row(fg("dim", `── ${rowItem.label} ──`)));
562
+ continue;
563
+ }
508
564
  const idx = selectable.findIndex((c) => c.run?.runId === rowItem.run?.runId);
509
565
  const snap = snapshotFor(rowItem.run, this.options.snapshotCache);
510
566
  const run = snap?.manifest ?? rowItem.run;
@@ -527,7 +583,8 @@ export class RunDashboard implements DashboardComponent {
527
583
  const label = runLabel(run, gi === this.selected, this.options.snapshotCache, innerWidth - 2);
528
584
  lines.push(row(applyStatusColor(this.theme, status, label)));
529
585
  }
530
- if (win.hasBottom) lines.push(row(fg("dim", `↓ ${selectableCount - (this.runScrollOffset + win.slots)} more below`)));
586
+ if (win.hasBottom)
587
+ lines.push(row(fg("dim", `↓ ${selectableCount - (this.runScrollOffset + win.slots)} more below`)));
531
588
  }
532
589
 
533
590
  // Selected run detail — compact
@@ -544,21 +601,36 @@ export class RunDashboard implements DashboardComponent {
544
601
  const isTerminal = statusStr === "failed" || statusStr === "cancelled" || statusStr === "stopped";
545
602
  const reason = isTerminal ? summarizeTerminalReason(r, selectedTasks, snap?.cancellationReason) : undefined;
546
603
  const reasonSuffix = reason ? ` · ${truncate(sanitizeLine(reason), 40)}` : "";
547
- lines.push(row(fg("dim", sanitizeLine(` ${r.team}/${r.workflow ?? "default"} · ${statusStr} · ${r.runId.slice(-10)}${reasonSuffix}`))));
604
+ lines.push(
605
+ row(
606
+ fg(
607
+ "dim",
608
+ sanitizeLine(
609
+ ` ${r.team}/${r.workflow ?? "default"} · ${statusStr} · ${r.runId.slice(-10)}${reasonSuffix}`,
610
+ ),
611
+ ),
612
+ ),
613
+ );
548
614
 
549
615
  // Pane content (max 8 lines) — F-2: colorize embedded status glyphs.
550
616
  const paneLines = snap
551
- ? this.activePane === "agents" ? renderAgentsPane(snap, this.options)
552
- : this.activePane === "progress" ? renderProgressPane(snap)
553
- : this.activePane === "mailbox" ? renderMailboxPane(snap)
554
- : this.activePane === "health" ? renderHealthPane(snap, { isForeground: !r.async })
555
- : this.activePane === "metrics" ? renderMetricsPane(snap, { registry: this.options.registry })
556
- : renderTranscriptPane(snap)
557
- : [
558
- ...readAgentPreview(r, 4, this.options),
559
- ...readProgressPreview(r, 2),
560
- ];
561
- const filteredPane = paneLines.filter(l => l && !l.includes("(none)") && l.trim() !== "");
617
+ ? this.activePane === "agents"
618
+ ? renderAgentsPane(snap, this.options)
619
+ : this.activePane === "progress"
620
+ ? renderProgressPane(snap)
621
+ : this.activePane === "mailbox"
622
+ ? renderMailboxPane(snap)
623
+ : this.activePane === "health"
624
+ ? renderHealthPane(snap, {
625
+ isForeground: !r.async,
626
+ })
627
+ : this.activePane === "metrics"
628
+ ? renderMetricsPane(snap, {
629
+ registry: this.options.registry,
630
+ })
631
+ : renderTranscriptPane(snap)
632
+ : [...readAgentPreview(r, 4, this.options), ...readProgressPreview(r, 2)];
633
+ const filteredPane = paneLines.filter((l) => l && !l.includes("(none)") && l.trim() !== "");
562
634
  if (filteredPane.length > 0) {
563
635
  lines.push(row(fg("dim", `── ${this.activePane} ──`)));
564
636
  for (const line of filteredPane.slice(0, 8)) {
@@ -573,14 +645,23 @@ export class RunDashboard implements DashboardComponent {
573
645
 
574
646
  // One-line footer — V-1: width-padded so the right edge doesn't jitter.
575
647
  const usage = aggregateUsage(selectedTasks);
576
- const u = usage ?? { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0 };
648
+ const u = usage ?? {
649
+ input: 0,
650
+ output: 0,
651
+ cacheRead: 0,
652
+ cacheWrite: 0,
653
+ cost: 0,
654
+ };
577
655
  const tok = (u.input ?? 0) + (u.output ?? 0) + (u.cacheRead ?? 0) + (u.cacheWrite ?? 0);
578
656
  const tokStr = tok > 0 ? (tok >= 1000 ? `${(tok / 1000).toFixed(1)}k tok` : `${tok} tok`) : "";
579
657
  let ctxPct: number | undefined;
580
658
  for (const agent of agents) {
581
659
  if (agent.status === "running" && agent.runtime === "live-session") {
582
660
  const pct = getLiveAgentContextPercent(agent.taskId);
583
- if (pct != null) { ctxPct = pct; break; }
661
+ if (pct != null) {
662
+ ctxPct = pct;
663
+ break;
664
+ }
584
665
  }
585
666
  }
586
667
  const ctxStr = ctxPct != null ? `${Math.round(ctxPct)}% ctx` : "";
@@ -607,7 +688,10 @@ export class RunDashboard implements DashboardComponent {
607
688
  lines.push(bottom);
608
689
  }
609
690
 
610
- this.cachedLines = renderLines(lines.map((line) => truncate(line, width)), width);
691
+ this.cachedLines = renderLines(
692
+ lines.map((line) => truncate(line, width)),
693
+ width,
694
+ );
611
695
  this.cachedVersion = signature;
612
696
  this.cachedWidth = width;
613
697
  }
@@ -637,7 +721,19 @@ export class RunDashboard implements DashboardComponent {
637
721
  this.done(selectedRunId ? { runId: selectedRunId, action: "status" } : undefined);
638
722
  return;
639
723
  }
640
- if (action === "summary" || action === "artifacts" || action === "api" || action === "agents" || action === "mailbox" || action === "reload" || action === "mailbox-detail" || action === "health-recovery" || action === "health-kill-stale" || action === "health-diagnostic-export" || action === "notifications-dismiss") {
724
+ if (
725
+ action === "summary" ||
726
+ action === "artifacts" ||
727
+ action === "api" ||
728
+ action === "agents" ||
729
+ action === "mailbox" ||
730
+ action === "reload" ||
731
+ action === "mailbox-detail" ||
732
+ action === "health-recovery" ||
733
+ action === "health-kill-stale" ||
734
+ action === "health-diagnostic-export" ||
735
+ action === "notifications-dismiss"
736
+ ) {
641
737
  this.done(selectedRunId ? { runId: selectedRunId, action } : action === "reload" ? { runId: "", action } : undefined);
642
738
  return;
643
739
  }
@@ -16,32 +16,31 @@ export type RunEventType =
16
16
  | "run.cache_invalidated";
17
17
 
18
18
  /** Typed channel names for category-based event subscription. */
19
- export type EventChannel =
20
- | "worker:progress"
21
- | "worker:lifecycle"
22
- | "worker:stream"
23
- | "run:state"
24
- | "ui:invalidate";
19
+ export type EventChannel = "worker:progress" | "worker:lifecycle" | "worker:stream" | "run:state" | "ui:invalidate";
25
20
 
26
21
  /** Sets used by classifyEventChannel for O(1) lookup. */
27
- const WORKER_PROGRESS_TYPES = new Set([
28
- "tool_execution_start", "tool_result", "agent_progress", "worker_status",
29
- ]);
22
+ const WORKER_PROGRESS_TYPES = new Set(["tool_execution_start", "tool_result", "agent_progress", "worker_status"]);
30
23
  const WORKER_LIFECYCLE_TYPES = new Set([
31
- "task.started", "task.completed", "task.failed", "task.needs_attention",
32
- "task_started", "task_completed", "task_failed", "task_cancelled",
33
- "run.started", "run.completed", "run.cancelled", "run.failed",
34
- "run_started", "run_completed", "run_cancelled", "run_blocked",
35
- ]);
36
- const WORKER_STREAM_TYPES = new Set([
37
- "stdout_chunk", "stderr_chunk", "stream",
38
- ]);
39
- const RUN_STATE_TYPES = new Set([
40
- "manifest.saved", "task.claimed", "task.unclaimed", "mailbox_updated",
41
- ]);
42
- const UI_INVALIDATE_TYPES = new Set([
43
- "effectiveness_changed", "snapshot_stale", "run.cache_invalidated",
24
+ "task.started",
25
+ "task.completed",
26
+ "task.failed",
27
+ "task.needs_attention",
28
+ "task_started",
29
+ "task_completed",
30
+ "task_failed",
31
+ "task_cancelled",
32
+ "run.started",
33
+ "run.completed",
34
+ "run.cancelled",
35
+ "run.failed",
36
+ "run_started",
37
+ "run_completed",
38
+ "run_cancelled",
39
+ "run_blocked",
44
40
  ]);
41
+ const WORKER_STREAM_TYPES = new Set(["stdout_chunk", "stderr_chunk", "stream"]);
42
+ const RUN_STATE_TYPES = new Set(["manifest.saved", "task.claimed", "task.unclaimed", "mailbox_updated"]);
43
+ const UI_INVALIDATE_TYPES = new Set(["effectiveness_changed", "snapshot_stale", "run.cache_invalidated"]);
45
44
 
46
45
  /** Classify an event type string into a typed channel. */
47
46
  export function classifyEventChannel(type: string): EventChannel {
@@ -86,12 +85,17 @@ class RunEventBus {
86
85
  const listeners = this.#listeners.get(runId) ?? new Set();
87
86
  listeners.add(callback);
88
87
  this.#listeners.set(runId, listeners);
89
- return () => { listeners.delete(callback); if (listeners.size === 0) this.#listeners.delete(runId); };
88
+ return () => {
89
+ listeners.delete(callback);
90
+ if (listeners.size === 0) this.#listeners.delete(runId);
91
+ };
90
92
  }
91
93
 
92
94
  onAny(callback: RunEventCallback): () => void {
93
95
  this.#globalListeners.add(callback);
94
- return () => { this.#globalListeners.delete(callback); };
96
+ return () => {
97
+ this.#globalListeners.delete(callback);
98
+ };
95
99
  }
96
100
 
97
101
  off(runId: string, callback: RunEventCallback): void {
@@ -151,17 +155,15 @@ class RunEventBus {
151
155
  * fan-out to other subscribers).
152
156
  * @returns unsubscribe handle (detaches the live listener).
153
157
  */
154
- onWithReplay(
155
- runId: string,
156
- eventsPath: string,
157
- lastSeenSeq: number,
158
- callback: RunEventCallback,
159
- ): () => void {
158
+ onWithReplay(runId: string, eventsPath: string, lastSeenSeq: number, callback: RunEventCallback): () => void {
160
159
  // Phase 1: replay missed events from the durable log directly to this
161
160
  // callback. Bounded by limit; readEventsCursor already tail-caps.
162
161
  let maxReplayedSeq = lastSeenSeq;
163
162
  try {
164
- const cursor = readEventsCursor(eventsPath, { sinceSeq: lastSeenSeq, limit: 1000 });
163
+ const cursor = readEventsCursor(eventsPath, {
164
+ sinceSeq: lastSeenSeq,
165
+ limit: 1000,
166
+ });
165
167
  for (const teamEvent of cursor.events) {
166
168
  const type = teamEventToRunEventType(teamEvent);
167
169
  if (!type) continue; // not all TeamEvents map to a RunEventType
@@ -174,7 +176,11 @@ class RunEventBus {
174
176
  channel: classifyEventChannel(type),
175
177
  seq: teamEvent.metadata?.seq,
176
178
  };
177
- try { callback(payload); } catch { /* subscriber errors are non-fatal */ }
179
+ try {
180
+ callback(payload);
181
+ } catch {
182
+ /* subscriber errors are non-fatal */
183
+ }
178
184
  if (typeof teamEvent.metadata?.seq === "number") {
179
185
  maxReplayedSeq = Math.max(maxReplayedSeq, teamEvent.metadata.seq);
180
186
  }
@@ -208,20 +214,32 @@ class RunEventBus {
208
214
  const listeners = this.#listeners.get(event.runId);
209
215
  if (listeners) {
210
216
  for (const cb of listeners) {
211
- try { cb(event); } catch { /* subscriber errors are non-fatal */ }
217
+ try {
218
+ cb(event);
219
+ } catch {
220
+ /* subscriber errors are non-fatal */
221
+ }
212
222
  }
213
223
  }
214
224
 
215
225
  // Existing: global listeners
216
226
  for (const cb of this.#globalListeners) {
217
- try { cb(event); } catch { /* subscriber errors are non-fatal */ }
227
+ try {
228
+ cb(event);
229
+ } catch {
230
+ /* subscriber errors are non-fatal */
231
+ }
218
232
  }
219
233
 
220
234
  // New: channel listeners
221
235
  const channelListeners = this.#channelListeners.get(channel);
222
236
  if (channelListeners) {
223
237
  for (const cb of channelListeners) {
224
- try { cb(event); } catch { /* subscriber errors are non-fatal */ }
238
+ try {
239
+ cb(event);
240
+ } catch {
241
+ /* subscriber errors are non-fatal */
242
+ }
225
243
  }
226
244
  }
227
245
 
@@ -232,7 +250,11 @@ class RunEventBus {
232
250
  const runChannelListeners = runMap.get(channel);
233
251
  if (runChannelListeners) {
234
252
  for (const cb of runChannelListeners) {
235
- try { cb(event); } catch { /* subscriber errors are non-fatal */ }
253
+ try {
254
+ cb(event);
255
+ } catch {
256
+ /* subscriber errors are non-fatal */
257
+ }
236
258
  }
237
259
  }
238
260
  }
@@ -290,4 +312,4 @@ export function emitFromTeamEvent(event: TeamEvent): void {
290
312
  // delivery against replayed events.
291
313
  seq: event.metadata?.seq,
292
314
  });
293
- }
315
+ }