pi-crew 0.9.16 → 0.9.18

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 (435) hide show
  1. package/CHANGELOG.md +130 -0
  2. package/README.md +19 -0
  3. package/dist/build-meta.json +21784 -0
  4. package/dist/index.mjs +83169 -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/migration/atomic-write-v2-migration.md +297 -0
  14. package/docs/patterns/command-agent-skill.md +1 -1
  15. package/docs/perf/performance-review-2026-07.md +287 -0
  16. package/docs/skills/REFERENCE.md +0 -17
  17. package/docs//303/242mmaAAA/303/242 +357 -0
  18. package/index.bundle.ts +25 -0
  19. package/index.ts +95 -4
  20. package/package.json +15 -4
  21. package/skills/iterative-audit/SKILL.md +0 -1
  22. package/skills/widget-rendering/SKILL.md +17 -0
  23. package/src/adapters/claude-adapter.ts +1 -3
  24. package/src/adapters/export-util.ts +16 -16
  25. package/src/adapters/index.ts +5 -5
  26. package/src/agents/agent-config.ts +20 -14
  27. package/src/agents/agent-serializer.ts +1 -1
  28. package/src/agents/discover-agents.ts +83 -39
  29. package/src/benchmark/benchmark-runner.ts +51 -51
  30. package/src/benchmark/feedback-loop.ts +1 -1
  31. package/src/config/config.ts +303 -591
  32. package/src/config/defaults.ts +28 -2
  33. package/src/config/drift-detector.ts +11 -14
  34. package/src/config/markers.ts +201 -203
  35. package/src/config/resilient-parser.ts +14 -6
  36. package/src/config/role-tools.ts +3 -3
  37. package/src/config/suggestions.ts +5 -12
  38. package/src/config/types.ts +9 -25
  39. package/src/errors.ts +151 -157
  40. package/src/extension/action-suggestions.ts +54 -9
  41. package/src/extension/async-notifier.ts +43 -13
  42. package/src/extension/autonomous-policy.ts +77 -37
  43. package/src/extension/command-completions.ts +9 -8
  44. package/src/extension/context-status-injection.ts +14 -12
  45. package/src/extension/crew-autocomplete.ts +8 -16
  46. package/src/extension/crew-cleanup.ts +2 -1
  47. package/src/extension/crew-shortcuts.ts +9 -6
  48. package/src/extension/cross-extension-rpc.ts +136 -42
  49. package/src/extension/help.ts +1 -1
  50. package/src/extension/import-index.ts +10 -5
  51. package/src/extension/knowledge-injection.ts +88 -15
  52. package/src/extension/management.ts +89 -349
  53. package/src/extension/message-renderers.ts +3 -4
  54. package/src/extension/notification-router.ts +22 -5
  55. package/src/extension/notification-sink.ts +6 -3
  56. package/src/extension/pi-api.ts +17 -8
  57. package/src/extension/plan-orchestrate.ts +8 -27
  58. package/src/extension/project-init.ts +21 -6
  59. package/src/extension/register.ts +329 -975
  60. package/src/extension/registration/artifact-cleanup.ts +9 -4
  61. package/src/extension/registration/command-utils.ts +5 -1
  62. package/src/extension/registration/commands.ts +806 -314
  63. package/src/extension/registration/compaction-guard.ts +15 -15
  64. package/src/extension/registration/lifecycle.ts +259 -0
  65. package/src/extension/registration/observability.ts +293 -0
  66. package/src/extension/registration/subagent-helpers.ts +29 -7
  67. package/src/extension/registration/subagent-tools.ts +253 -44
  68. package/src/extension/registration/team-tool.ts +19 -84
  69. package/src/extension/registration/ui.ts +168 -0
  70. package/src/extension/registration/viewers.ts +64 -24
  71. package/src/extension/result-watcher.ts +18 -7
  72. package/src/extension/run-bundle-schema.ts +21 -6
  73. package/src/extension/run-export.ts +15 -6
  74. package/src/extension/run-import.ts +64 -29
  75. package/src/extension/run-index.ts +28 -9
  76. package/src/extension/run-maintenance.ts +32 -12
  77. package/src/extension/session-summary.ts +1 -1
  78. package/src/extension/team-manager-command.ts +64 -7
  79. package/src/extension/team-onboard.ts +149 -150
  80. package/src/extension/team-recommendation.ts +121 -21
  81. package/src/extension/team-tool/anchor.ts +31 -64
  82. package/src/extension/team-tool/api.ts +929 -141
  83. package/src/extension/team-tool/auto-summarize.ts +14 -26
  84. package/src/extension/team-tool/cache-control.ts +1 -5
  85. package/src/extension/team-tool/cancel.ts +138 -38
  86. package/src/extension/team-tool/chain-dispatch.ts +5 -13
  87. package/src/extension/team-tool/chain-executor.ts +29 -51
  88. package/src/extension/team-tool/config-patch.ts +1 -1
  89. package/src/extension/team-tool/context.ts +40 -20
  90. package/src/extension/team-tool/destructive-gate.ts +10 -5
  91. package/src/extension/team-tool/doctor.ts +170 -51
  92. package/src/extension/team-tool/explain.ts +228 -214
  93. package/src/extension/team-tool/failure-patterns.ts +3 -9
  94. package/src/extension/team-tool/goal-wrap.ts +71 -29
  95. package/src/extension/team-tool/goal.ts +185 -35
  96. package/src/extension/team-tool/handle-schedule.ts +34 -15
  97. package/src/extension/team-tool/handle-settings.ts +94 -56
  98. package/src/extension/team-tool/health-monitor.ts +27 -108
  99. package/src/extension/team-tool/inspect.ts +42 -9
  100. package/src/extension/team-tool/intent-policy.ts +4 -1
  101. package/src/extension/team-tool/lifecycle-actions.ts +244 -48
  102. package/src/extension/team-tool/orchestrate.ts +7 -18
  103. package/src/extension/team-tool/parallel-dispatch.ts +51 -29
  104. package/src/extension/team-tool/plan.ts +29 -5
  105. package/src/extension/team-tool/respond.ts +49 -16
  106. package/src/extension/team-tool/run-not-found.ts +3 -8
  107. package/src/extension/team-tool/run.ts +80 -317
  108. package/src/extension/team-tool/status.ts +135 -43
  109. package/src/extension/team-tool/workflow-manage.ts +92 -25
  110. package/src/extension/team-tool-types.ts +8 -1
  111. package/src/extension/team-tool.ts +142 -551
  112. package/src/extension/validate-resources.ts +39 -8
  113. package/src/hooks/registry.ts +66 -17
  114. package/src/hooks/types.ts +1 -1
  115. package/src/i18n.ts +25 -11
  116. package/src/observability/correlation.ts +17 -3
  117. package/src/observability/event-bus.ts +51 -56
  118. package/src/observability/event-to-metric.ts +117 -15
  119. package/src/observability/exporters/otlp-exporter.ts +56 -17
  120. package/src/observability/exporters/prometheus-exporter.ts +1 -1
  121. package/src/observability/metric-registry.ts +16 -4
  122. package/src/observability/metric-retention.ts +8 -2
  123. package/src/observability/metric-sink.ts +11 -3
  124. package/src/observability/metrics-primitives.ts +42 -9
  125. package/src/plugins/plugin-define.ts +2 -2
  126. package/src/plugins/plugin-registry.ts +25 -25
  127. package/src/plugins/plugins/index.ts +1 -1
  128. package/src/plugins/plugins/nextjs.ts +16 -16
  129. package/src/plugins/plugins/vite.ts +7 -11
  130. package/src/plugins/plugins/vitest.ts +6 -11
  131. package/src/runtime/adaptive-plan.ts +225 -40
  132. package/src/runtime/agent-control.ts +58 -15
  133. package/src/runtime/agent-memory.ts +15 -9
  134. package/src/runtime/agent-observability.ts +10 -2
  135. package/src/runtime/anchor-manager.ts +27 -25
  136. package/src/runtime/async-marker.ts +7 -1
  137. package/src/runtime/async-runner.ts +39 -24
  138. package/src/runtime/auto-summarize.ts +7 -13
  139. package/src/runtime/background-runner.ts +189 -251
  140. package/src/runtime/batch-barrier.ts +18 -16
  141. package/src/runtime/cancellation-token.ts +16 -6
  142. package/src/runtime/cancellation.ts +46 -8
  143. package/src/runtime/capability-inventory.ts +6 -4
  144. package/src/runtime/chain-parser.ts +44 -11
  145. package/src/runtime/chain-runner.ts +63 -69
  146. package/src/runtime/checkpoint.ts +12 -56
  147. package/src/runtime/child-pi.ts +344 -79
  148. package/src/runtime/coalesce-tasks.ts +268 -0
  149. package/src/runtime/code-summary.ts +71 -26
  150. package/src/runtime/compact-stages/index.ts +15 -5
  151. package/src/runtime/compact-stages/tail-capture-stage.ts +7 -2
  152. package/src/runtime/compact-stages/truncation-stage.ts +4 -1
  153. package/src/runtime/compaction-summary.ts +17 -10
  154. package/src/runtime/completion-guard.ts +33 -16
  155. package/src/runtime/crash-classification.ts +28 -7
  156. package/src/runtime/crash-recovery.ts +177 -37
  157. package/src/runtime/crew-agent-records.ts +145 -47
  158. package/src/runtime/crew-hooks.ts +9 -24
  159. package/src/runtime/cross-extension-rpc.ts +25 -23
  160. package/src/runtime/custom-tools/irc-tool.ts +43 -15
  161. package/src/runtime/custom-tools/submit-result-tool.ts +16 -5
  162. package/src/runtime/delivery-coordinator.ts +34 -7
  163. package/src/runtime/delta-conflict.ts +9 -21
  164. package/src/runtime/deterministic-ast.ts +1 -1
  165. package/src/runtime/diagnostic-export.ts +53 -20
  166. package/src/runtime/direct-run.ts +12 -2
  167. package/src/runtime/dwf-state-store.ts +1 -1
  168. package/src/runtime/dynamic-workflow-context.ts +187 -59
  169. package/src/runtime/dynamic-workflow-runner.ts +42 -20
  170. package/src/runtime/effectiveness.ts +16 -8
  171. package/src/runtime/errors/crew-errors.ts +7 -11
  172. package/src/runtime/event-stream-bridge.ts +9 -3
  173. package/src/runtime/foreground-control.ts +54 -14
  174. package/src/runtime/foreground-watchdog.ts +9 -6
  175. package/src/runtime/goal-achievement.ts +27 -10
  176. package/src/runtime/goal-evaluator.ts +54 -19
  177. package/src/runtime/goal-loop-runner.ts +280 -99
  178. package/src/runtime/goal-state-store.ts +27 -17
  179. package/src/runtime/green-contract.ts +11 -2
  180. package/src/runtime/group-join.ts +64 -31
  181. package/src/runtime/handoff-manager.ts +37 -42
  182. package/src/runtime/heartbeat-gradient.ts +10 -2
  183. package/src/runtime/heartbeat-watcher.ts +32 -6
  184. package/src/runtime/hidden-handoff.ts +13 -31
  185. package/src/runtime/important-line-classifier.ts +12 -2
  186. package/src/runtime/iteration-hooks.ts +25 -15
  187. package/src/runtime/live-agent-control.ts +55 -7
  188. package/src/runtime/live-agent-manager.ts +130 -27
  189. package/src/runtime/live-control-realtime.ts +23 -3
  190. package/src/runtime/live-irc.ts +4 -1
  191. package/src/runtime/live-session-health.ts +12 -4
  192. package/src/runtime/live-session-runtime.ts +379 -117
  193. package/src/runtime/manifest-cache.ts +28 -12
  194. package/src/runtime/mcp-proxy.ts +10 -18
  195. package/src/runtime/metric-parser.ts +1 -5
  196. package/src/runtime/model-fallback.ts +55 -18
  197. package/src/runtime/model-resolver.ts +2 -6
  198. package/src/runtime/model-scope.ts +19 -3
  199. package/src/runtime/notebook-helpers.ts +60 -62
  200. package/src/runtime/orphan-worker-registry.ts +37 -26
  201. package/src/runtime/output-validator.ts +18 -3
  202. package/src/runtime/overflow-recovery.ts +5 -4
  203. package/src/runtime/parallel-research.ts +29 -5
  204. package/src/runtime/parallel-utils.ts +9 -11
  205. package/src/runtime/path-overlap.ts +150 -0
  206. package/src/runtime/peer-dep.ts +12 -17
  207. package/src/runtime/per-write-validator.ts +1 -3
  208. package/src/runtime/phase-tracker.ts +342 -330
  209. package/src/runtime/pi-args.ts +26 -8
  210. package/src/runtime/pi-json-output.ts +1 -1
  211. package/src/runtime/pi-spawn.ts +30 -19
  212. package/src/runtime/pipeline-runner.ts +56 -55
  213. package/src/runtime/plan-templates.ts +5 -6
  214. package/src/runtime/policy-engine.ts +43 -7
  215. package/src/runtime/post-checks.ts +12 -4
  216. package/src/runtime/post-exit-stdio-guard.ts +2 -2
  217. package/src/runtime/process-lifecycle.ts +20 -10
  218. package/src/runtime/process-status.ts +16 -5
  219. package/src/runtime/progress-event-coalescer.ts +2 -1
  220. package/src/runtime/progress-tracker.ts +103 -103
  221. package/src/runtime/prose-compressor.ts +9 -11
  222. package/src/runtime/recovery-recipes.ts +118 -24
  223. package/src/runtime/replace.ts +25 -10
  224. package/src/runtime/resilient-edit.ts +10 -25
  225. package/src/runtime/result-extractor.ts +2 -6
  226. package/src/runtime/retry-executor.ts +20 -4
  227. package/src/runtime/retry-runner.ts +27 -51
  228. package/src/runtime/role-permission.ts +6 -1
  229. package/src/runtime/run-coalesced-task-group.ts +256 -0
  230. package/src/runtime/run-drift.ts +14 -15
  231. package/src/runtime/run-tracker.ts +6 -28
  232. package/src/runtime/runtime-policy.ts +1 -6
  233. package/src/runtime/runtime-resolver.ts +80 -15
  234. package/src/runtime/scheduler.ts +47 -18
  235. package/src/runtime/semaphore.ts +5 -7
  236. package/src/runtime/sensitive-paths.ts +2 -1
  237. package/src/runtime/session-usage.ts +1 -1
  238. package/src/runtime/settings-store.ts +16 -12
  239. package/src/runtime/sidechain-output.ts +6 -2
  240. package/src/runtime/single-agent-compose.ts +1 -4
  241. package/src/runtime/skill-effectiveness.ts +29 -97
  242. package/src/runtime/skill-instructions.ts +40 -83
  243. package/src/runtime/stale-reconciler.ts +73 -197
  244. package/src/runtime/stream-preview.ts +1 -1
  245. package/src/runtime/streaming-output.ts +1 -1
  246. package/src/runtime/subagent-manager.ts +44 -169
  247. package/src/runtime/subprocess-tool-registry.ts +4 -1
  248. package/src/runtime/supervisor-contact.ts +10 -5
  249. package/src/runtime/task-display.ts +19 -5
  250. package/src/runtime/task-graph-scheduler.ts +95 -21
  251. package/src/runtime/task-graph.ts +5 -11
  252. package/src/runtime/task-health.ts +54 -47
  253. package/src/runtime/task-id.ts +12 -19
  254. package/src/runtime/task-output-context.ts +265 -81
  255. package/src/runtime/task-packet.ts +12 -20
  256. package/src/runtime/task-quality.ts +6 -14
  257. package/src/runtime/task-runner/context-retrieval.ts +4 -13
  258. package/src/runtime/task-runner/live-executor.ts +114 -36
  259. package/src/runtime/task-runner/output-splitter.ts +152 -0
  260. package/src/runtime/task-runner/progress.ts +50 -12
  261. package/src/runtime/task-runner/prompt-builder.ts +31 -7
  262. package/src/runtime/task-runner/prompt-pipeline.ts +31 -7
  263. package/src/runtime/task-runner/result-utils.ts +3 -1
  264. package/src/runtime/task-runner/retrieval-orchestrator.ts +310 -0
  265. package/src/runtime/task-runner/run-projection.ts +27 -8
  266. package/src/runtime/task-runner/state-helpers.ts +50 -14
  267. package/src/runtime/task-runner/tail-read.ts +2 -6
  268. package/src/runtime/task-runner.ts +180 -326
  269. package/src/runtime/team-runner-artifacts.ts +13 -0
  270. package/src/runtime/team-runner.ts +456 -974
  271. package/src/runtime/tool-output-pruner.ts +6 -9
  272. package/src/runtime/tool-progress.ts +11 -21
  273. package/src/runtime/verification-gates.ts +33 -24
  274. package/src/runtime/verification-integrity.ts +2 -7
  275. package/src/runtime/verification-worktree.ts +62 -12
  276. package/src/runtime/worker-heartbeat.ts +5 -1
  277. package/src/runtime/worker-startup.ts +29 -5
  278. package/src/runtime/workflow-state.ts +17 -9
  279. package/src/runtime/workspace-lock.ts +30 -35
  280. package/src/runtime/workspace-tree.ts +20 -32
  281. package/src/runtime/yield-handler.ts +43 -9
  282. package/src/runtime/zombie-scanner.ts +5 -4
  283. package/src/schema/config-schema.ts +266 -172
  284. package/src/schema/team-tool-schema.ts +29 -74
  285. package/src/schema/validation-types.ts +25 -17
  286. package/src/skills/discover-skills.ts +35 -10
  287. package/src/skills/skill-templates.ts +109 -27
  288. package/src/skills/validate.ts +26 -8
  289. package/src/state/active-run-registry.ts +87 -28
  290. package/src/state/artifact-store.ts +9 -5
  291. package/src/state/atomic-write-v2.ts +85 -63
  292. package/src/state/atomic-write.ts +106 -27
  293. package/src/state/blob-store.ts +47 -20
  294. package/src/state/contracts.ts +20 -5
  295. package/src/state/crew-init.ts +5 -22
  296. package/src/state/decision-ledger.ts +19 -73
  297. package/src/state/event-log-rotation.ts +41 -15
  298. package/src/state/event-log.ts +168 -53
  299. package/src/state/event-reconstructor.ts +11 -1
  300. package/src/state/gitignore-manager.ts +2 -8
  301. package/src/state/health-store.ts +57 -57
  302. package/src/state/hook-instinct-bridge.ts +1 -1
  303. package/src/state/hook-integrations.ts +1 -1
  304. package/src/state/instinct-store.ts +17 -5
  305. package/src/state/jsonl-writer.ts +1 -1
  306. package/src/state/locks.ts +23 -9
  307. package/src/state/mailbox.ts +151 -28
  308. package/src/state/observation-store.ts +20 -14
  309. package/src/state/run-cache.ts +142 -135
  310. package/src/state/run-graph.ts +6 -15
  311. package/src/state/run-metrics.ts +5 -18
  312. package/src/state/schedule.ts +15 -9
  313. package/src/state/state-store.ts +137 -47
  314. package/src/state/task-claims.ts +12 -2
  315. package/src/state/tiered-eval.ts +52 -43
  316. package/src/state/types-eval.ts +2 -2
  317. package/src/state/types.ts +24 -20
  318. package/src/state/usage.ts +20 -4
  319. package/src/state/worker-atomic-writer.ts +6 -3
  320. package/src/subagents/index.ts +2 -2
  321. package/src/teams/discover-teams.ts +21 -6
  322. package/src/tools/safe-bash-extension.ts +5 -6
  323. package/src/tools/safe-bash.ts +10 -11
  324. package/src/types/new-api-types.ts +6 -10
  325. package/src/ui/agent-management-overlay.ts +52 -40
  326. package/src/ui/card-colors.ts +13 -4
  327. package/src/ui/crew-footer.ts +8 -7
  328. package/src/ui/crew-select-list.ts +1 -1
  329. package/src/ui/dashboard-panes/agents-pane.ts +41 -25
  330. package/src/ui/dashboard-panes/cancellation-pane.ts +1 -1
  331. package/src/ui/dashboard-panes/capability-pane.ts +32 -15
  332. package/src/ui/dashboard-panes/health-pane.ts +2 -1
  333. package/src/ui/dashboard-panes/metrics-pane.ts +4 -1
  334. package/src/ui/dashboard-panes/progress-pane.ts +12 -9
  335. package/src/ui/heartbeat-aggregator.ts +15 -4
  336. package/src/ui/keybinding-map.ts +40 -7
  337. package/src/ui/live-conversation-overlay.ts +36 -20
  338. package/src/ui/live-duration.ts +1 -4
  339. package/src/ui/live-run-sidebar.ts +88 -25
  340. package/src/ui/loaders.ts +2 -8
  341. package/src/ui/mascot.ts +20 -36
  342. package/src/ui/overlays/agent-picker-overlay.ts +11 -3
  343. package/src/ui/overlays/confirm-overlay.ts +4 -2
  344. package/src/ui/overlays/help-overlay.ts +25 -14
  345. package/src/ui/overlays/mailbox-compose-overlay.ts +48 -11
  346. package/src/ui/overlays/mailbox-compose-preview.ts +20 -5
  347. package/src/ui/overlays/mailbox-detail-overlay.ts +27 -6
  348. package/src/ui/pi-ui-compat.ts +7 -7
  349. package/src/ui/powerbar-publisher.ts +120 -42
  350. package/src/ui/render-diff.ts +10 -3
  351. package/src/ui/render-scheduler.ts +12 -4
  352. package/src/ui/run-action-dispatcher.ts +81 -18
  353. package/src/ui/run-dashboard.ts +172 -76
  354. package/src/ui/run-event-bus.ts +59 -37
  355. package/src/ui/run-snapshot-cache.ts +276 -86
  356. package/src/ui/settings-overlay.ts +361 -74
  357. package/src/ui/status-colors.ts +12 -1
  358. package/src/ui/syntax-highlight.ts +1 -1
  359. package/src/ui/terminal-status.ts +1 -3
  360. package/src/ui/theme-adapter.ts +16 -14
  361. package/src/ui/theme-discovery.ts +13 -2
  362. package/src/ui/tool-progress-formatter.ts +7 -7
  363. package/src/ui/tool-render.ts +128 -56
  364. package/src/ui/tool-renderers/brief-mode.ts +45 -27
  365. package/src/ui/tool-renderers/index.ts +109 -43
  366. package/src/ui/transcript-cache.ts +32 -6
  367. package/src/ui/transcript-entries.ts +25 -23
  368. package/src/ui/transcript-viewer.ts +78 -29
  369. package/src/ui/widget/index.ts +99 -40
  370. package/src/ui/widget/widget-formatters.ts +13 -6
  371. package/src/ui/widget/widget-model.ts +19 -8
  372. package/src/ui/widget/widget-renderer.ts +23 -13
  373. package/src/ui/widget/widget-types.ts +1 -1
  374. package/src/utils/bm25-search.ts +199 -199
  375. package/src/utils/conflict-detect.ts +22 -21
  376. package/src/utils/env-filter.ts +14 -7
  377. package/src/utils/file-coalescer.ts +5 -1
  378. package/src/utils/fingerprint.ts +3 -6
  379. package/src/utils/frontmatter.ts +3 -1
  380. package/src/utils/fs-watch.ts +2 -6
  381. package/src/utils/gh-protocol.ts +119 -44
  382. package/src/utils/git.ts +13 -15
  383. package/src/utils/guards.ts +2 -5
  384. package/src/utils/ids.ts +9 -2
  385. package/src/utils/incremental-reader.ts +14 -3
  386. package/src/utils/internal-error.ts +2 -1
  387. package/src/utils/names.ts +12 -3
  388. package/src/utils/paths.ts +49 -5
  389. package/src/utils/project-detector.ts +2 -2
  390. package/src/utils/redaction.ts +29 -19
  391. package/src/utils/resolve-shell.ts +9 -7
  392. package/src/utils/run-watcher-registry.ts +19 -31
  393. package/src/utils/safe-paths.ts +46 -29
  394. package/src/utils/scan-cache.ts +9 -2
  395. package/src/utils/session-utils.ts +2 -4
  396. package/src/utils/sleep.ts +12 -5
  397. package/src/utils/sse-parser.ts +5 -17
  398. package/src/utils/visual.ts +52 -32
  399. package/src/workflows/discover-workflows.ts +41 -109
  400. package/src/workflows/intermediate-store.ts +5 -21
  401. package/src/workflows/preflight-validator.ts +6 -33
  402. package/src/workflows/topology-analyzer.ts +5 -21
  403. package/src/workflows/workflow-config.ts +7 -6
  404. package/src/worktree/branch-freshness.ts +66 -8
  405. package/src/worktree/cleanup.ts +130 -20
  406. package/src/worktree/worktree-manager.ts +212 -69
  407. package/skills/artifact-analysis-loop/SKILL.md +0 -303
  408. package/skills/detection-pipeline-design/SKILL.md +0 -286
  409. package/skills/hunting-investigation-loop/SKILL.md +0 -402
  410. package/skills/incident-playbook-construction/SKILL.md +0 -384
  411. package/skills/security-review/SKILL.md +0 -561
  412. package/skills/threat-hypothesis-framework/SKILL.md +0 -176
  413. package/skills/ui-render-performance/SKILL.md +0 -58
  414. /package/docs/{followup-review-round3-2026-05-12.md → archive/followup-review-round3-2026-05-12.md} +0 -0
  415. /package/docs/{followup-review-round4-2026-05-13.md → archive/followup-review-round4-2026-05-13.md} +0 -0
  416. /package/docs/{pi-crew-bugs.md → archive/pi-crew-bugs.md} +0 -0
  417. /package/docs/{pi-crew-test-final.md → archive/pi-crew-test-final.md} +0 -0
  418. /package/docs/{pi-crew-test-results.md → archive/pi-crew-test-results.md} +0 -0
  419. /package/docs/{pi-crew-test-round2.md → archive/pi-crew-test-round2.md} +0 -0
  420. /package/docs/{pi-crew-test-round4.md → archive/pi-crew-test-round4.md} +0 -0
  421. /package/docs/{pi-crew-test-round5.md → archive/pi-crew-test-round5.md} +0 -0
  422. /package/docs/{pi-crew-test-round6.md → archive/pi-crew-test-round6.md} +0 -0
  423. /package/docs/{pi-crew-v0.5.10-audit-fix-plan.md → archive/pi-crew-v0.5.10-audit-fix-plan.md} +0 -0
  424. /package/docs/{pi-crew-v0.5.11-audit-fix-plan.md → archive/pi-crew-v0.5.11-audit-fix-plan.md} +0 -0
  425. /package/docs/{pi-crew-v0.5.12-audit-fix-plan.md → archive/pi-crew-v0.5.12-audit-fix-plan.md} +0 -0
  426. /package/docs/{pi-crew-v0.5.13-audit-fix-plan.md → archive/pi-crew-v0.5.13-audit-fix-plan.md} +0 -0
  427. /package/docs/{pi-crew-v0.5.14-audit-fix-plan.md → archive/pi-crew-v0.5.14-audit-fix-plan.md} +0 -0
  428. /package/docs/{pi-crew-v0.5.16-audit-fix-plan.md → archive/pi-crew-v0.5.16-audit-fix-plan.md} +0 -0
  429. /package/docs/{pi-crew-v0.5.17-audit-fix-plan.md → archive/pi-crew-v0.5.17-audit-fix-plan.md} +0 -0
  430. /package/docs/{pi-crew-v0.5.5-audit-fix-plan.md → archive/pi-crew-v0.5.5-audit-fix-plan.md} +0 -0
  431. /package/docs/{pi-crew-v0.5.9-audit-fix-plan.md → archive/pi-crew-v0.5.9-audit-fix-plan.md} +0 -0
  432. /package/docs/{pi-mono-opportunities.md → archive/pi-mono-opportunities.md} +0 -0
  433. /package/docs/{pi-mono-review.md → archive/pi-mono-review.md} +0 -0
  434. /package/docs/{pi-subagent4-comparison.md → archive/pi-subagent4-comparison.md} +0 -0
  435. /package/docs/{pi-subagents3-deep-analysis.md → archive/pi-subagents3-deep-analysis.md} +0 -0
@@ -1,17 +1,24 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import * as fs from "node:fs";
3
3
  import * as path from "node:path";
4
- import { readCrewAgents, readCrewAgentsAsync, agentsPath, agentOutputPath } from "../runtime/crew-agent-records.ts";
4
+ import { agentOutputPath, agentsPath, readCrewAgents, readCrewAgentsAsync } from "../runtime/crew-agent-records.ts";
5
5
  import type { CrewAgentRecord } from "../runtime/crew-agent-runtime.ts";
6
6
  import { isActiveRunStatus } from "../runtime/process-status.ts";
7
7
  import type { TeamEvent } from "../state/event-log.ts";
8
+ import { sequencePath } from "../state/event-log.ts";
8
9
  import type { MailboxMessageStatus } from "../state/mailbox.ts";
9
10
  import { loadRunManifestById, loadRunManifestByIdAsync } from "../state/state-store.ts";
10
11
  import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
11
- import type { RunSnapshotCache as RunSnapshotCacheBase, RunUiGroupJoin, RunUiMailbox, RunUiProgress, RunUiSnapshot, RunUiUsage } from "./snapshot-types.ts";
12
- import { runEventBus } from "./run-event-bus.ts";
13
12
  import { extractDwfPhaseState } from "./dwf-phase-display.ts";
14
- import { sequencePath } from "../state/event-log.ts";
13
+ import { runEventBus } from "./run-event-bus.ts";
14
+ import type {
15
+ RunSnapshotCache as RunSnapshotCacheBase,
16
+ RunUiGroupJoin,
17
+ RunUiMailbox,
18
+ RunUiProgress,
19
+ RunUiSnapshot,
20
+ RunUiUsage,
21
+ } from "./snapshot-types.ts";
15
22
 
16
23
  export interface RunSnapshotCache extends RunSnapshotCacheBase {
17
24
  preloadStale(runId: string): Promise<RunUiSnapshot | undefined>;
@@ -90,7 +97,9 @@ function eventsStamp(eventsPath: string): FileStamp {
90
97
  const raw = fs.readFileSync(sequencePath(eventsPath), "utf-8");
91
98
  const seq = Number.parseInt(raw.trim(), 10);
92
99
  if (Number.isFinite(seq) && seq >= 0) return { mtimeMs: 0, size: seq + 1 };
93
- } catch { /* fall through to legacy stat */ }
100
+ } catch {
101
+ /* fall through to legacy stat */
102
+ }
94
103
  return stampFile(eventsPath);
95
104
  }
96
105
 
@@ -99,12 +108,20 @@ async function eventsStampAsync(eventsPath: string): Promise<FileStamp> {
99
108
  const raw = await fs.promises.readFile(sequencePath(eventsPath), "utf-8");
100
109
  const seq = Number.parseInt(raw.trim(), 10);
101
110
  if (Number.isFinite(seq) && seq >= 0) return { mtimeMs: 0, size: seq + 1 };
102
- } catch { /* fall through to legacy stat */ }
111
+ } catch {
112
+ /* fall through to legacy stat */
113
+ }
103
114
  return stampFileAsync(eventsPath);
104
115
  }
105
116
 
106
117
  function combineStamps(stamps: FileStamp[]): FileStamp {
107
- return stamps.reduce((acc, stamp) => ({ mtimeMs: Math.max(acc.mtimeMs, stamp.mtimeMs), size: acc.size + stamp.size }), zeroStamp());
118
+ return stamps.reduce(
119
+ (acc, stamp) => ({
120
+ mtimeMs: Math.max(acc.mtimeMs, stamp.mtimeMs),
121
+ size: acc.size + stamp.size,
122
+ }),
123
+ zeroStamp(),
124
+ );
108
125
  }
109
126
 
110
127
  function mailboxStamp(manifest: TeamRunManifest): FileStamp {
@@ -116,7 +133,9 @@ function mailboxStamp(manifest: TeamRunManifest): FileStamp {
116
133
  ];
117
134
  const tasksRoot = path.join(root, "tasks");
118
135
  try {
119
- for (const entry of fs.readdirSync(tasksRoot, { withFileTypes: true })) {
136
+ for (const entry of fs.readdirSync(tasksRoot, {
137
+ withFileTypes: true,
138
+ })) {
120
139
  if (!entry.isDirectory()) continue;
121
140
  stamps.push(stampFile(path.join(tasksRoot, entry.name, "inbox.jsonl")));
122
141
  stamps.push(stampFile(path.join(tasksRoot, entry.name, "outbox.jsonl")));
@@ -136,7 +155,9 @@ async function mailboxStampAsync(manifest: TeamRunManifest): Promise<FileStamp>
136
155
  ];
137
156
  const tasksRoot = path.join(root, "tasks");
138
157
  try {
139
- for (const entry of await fs.promises.readdir(tasksRoot, { withFileTypes: true })) {
158
+ for (const entry of await fs.promises.readdir(tasksRoot, {
159
+ withFileTypes: true,
160
+ })) {
140
161
  if (!entry.isDirectory()) continue;
141
162
  stamps.push(await stampFileAsync(path.join(tasksRoot, entry.name, "inbox.jsonl")));
142
163
  stamps.push(await stampFileAsync(path.join(tasksRoot, entry.name, "outbox.jsonl")));
@@ -168,11 +189,13 @@ function sameStamp(a: FileStamp, b: FileStamp): boolean {
168
189
  }
169
190
 
170
191
  function sameStamps(a: SnapshotStamps, b: SnapshotStamps): boolean {
171
- return sameStamp(a.manifest, b.manifest)
172
- && sameStamp(a.tasks, b.tasks)
173
- && sameStamp(a.agents, b.agents)
174
- && sameStamp(a.events, b.events)
175
- && sameStamp(a.mailbox, b.mailbox);
192
+ return (
193
+ sameStamp(a.manifest, b.manifest) &&
194
+ sameStamp(a.tasks, b.tasks) &&
195
+ sameStamp(a.agents, b.agents) &&
196
+ sameStamp(a.events, b.events) &&
197
+ sameStamp(a.mailbox, b.mailbox)
198
+ );
176
199
  }
177
200
 
178
201
  function readTasks(tasksPath: string): TeamTaskState[] {
@@ -195,10 +218,12 @@ function tailJsonlLines<T>(filePath: string, limit: number, parse: (line: string
195
218
  const buffer = Buffer.alloc(bytesToRead);
196
219
  fs.readSync(fd, buffer, 0, bytesToRead, stat.size - bytesToRead);
197
220
  const lines = buffer.toString("utf-8").split(/\r?\n/).filter(Boolean);
198
- return lines.flatMap((line) => {
199
- const item = parse(line);
200
- return item ? [item] : [];
201
- }).slice(-limit);
221
+ return lines
222
+ .flatMap((line) => {
223
+ const item = parse(line);
224
+ return item ? [item] : [];
225
+ })
226
+ .slice(-limit);
202
227
  } finally {
203
228
  fs.closeSync(fd);
204
229
  }
@@ -218,10 +243,12 @@ async function tailJsonlLinesAsync<T>(filePath: string, limit: number, parse: (l
218
243
  const buffer = Buffer.alloc(bytesToRead);
219
244
  await handle.read(buffer, 0, bytesToRead, stat.size - bytesToRead);
220
245
  const lines = buffer.toString("utf-8").split(/\r?\n/).filter(Boolean);
221
- return lines.flatMap((line) => {
222
- const item = parse(line);
223
- return item ? [item] : [];
224
- }).slice(-limit);
246
+ return lines
247
+ .flatMap((line) => {
248
+ const item = parse(line);
249
+ return item ? [item] : [];
250
+ })
251
+ .slice(-limit);
225
252
  } finally {
226
253
  await handle.close();
227
254
  }
@@ -294,21 +321,39 @@ function recentOutputLines(manifest: TeamRunManifest, agents: CrewAgentRecord[],
294
321
  const outputPath = safeAgentOutputPath(manifest, agent);
295
322
  return outputPath ? tailLines(outputPath, limit) : [];
296
323
  });
297
- return [...fromProgress, ...fromFiles].map((line) => line.replace(/\s+/g, " ").trim()).filter(Boolean).slice(-limit);
324
+ return [...fromProgress, ...fromFiles]
325
+ .map((line) => line.replace(/\s+/g, " ").trim())
326
+ .filter(Boolean)
327
+ .slice(-limit);
298
328
  }
299
329
 
300
330
  async function recentOutputLinesAsync(manifest: TeamRunManifest, agents: CrewAgentRecord[], limit: number): Promise<string[]> {
301
331
  const fromProgress = agents.flatMap((agent) => agent.progress?.recentOutput ?? []);
302
- const fromFilesArrays = await Promise.all(agents.map((agent) => {
303
- const outputPath = safeAgentOutputPath(manifest, agent);
304
- return outputPath ? tailLinesAsync(outputPath, limit) : Promise.resolve([]);
305
- }));
332
+ const fromFilesArrays = await Promise.all(
333
+ agents.map((agent) => {
334
+ const outputPath = safeAgentOutputPath(manifest, agent);
335
+ return outputPath ? tailLinesAsync(outputPath, limit) : Promise.resolve([]);
336
+ }),
337
+ );
306
338
  const fromFiles = fromFilesArrays.flat();
307
- return [...fromProgress, ...fromFiles].map((line) => line.replace(/\s+/g, " ").trim()).filter(Boolean).slice(-limit);
339
+ return [...fromProgress, ...fromFiles]
340
+ .map((line) => line.replace(/\s+/g, " ").trim())
341
+ .filter(Boolean)
342
+ .slice(-limit);
308
343
  }
309
344
 
310
345
  function progressFromTasks(tasks: TeamTaskState[]): RunUiProgress {
311
- const progress: RunUiProgress = { total: tasks.length, completed: 0, running: 0, failed: 0, queued: 0, waiting: 0, cancelled: 0, skipped: 0, needsAttention: 0 };
346
+ const progress: RunUiProgress = {
347
+ total: tasks.length,
348
+ completed: 0,
349
+ running: 0,
350
+ failed: 0,
351
+ queued: 0,
352
+ waiting: 0,
353
+ cancelled: 0,
354
+ skipped: 0,
355
+ needsAttention: 0,
356
+ };
312
357
  for (const task of tasks) {
313
358
  if (task.status === "completed") progress.completed += 1;
314
359
  else if (task.status === "running") progress.running += 1;
@@ -323,19 +368,25 @@ function progressFromTasks(tasks: TeamTaskState[]): RunUiProgress {
323
368
  }
324
369
 
325
370
  function usageFrom(tasks: TeamTaskState[], agents: CrewAgentRecord[]): RunUiUsage {
326
- const taskUsage = tasks.reduce((acc, task) => {
327
- acc.tokensIn += task.usage?.input ?? 0;
328
- acc.tokensOut += task.usage?.output ?? 0;
329
- acc.toolUses += task.agentProgress?.toolCount ?? 0;
330
- return acc;
331
- }, { tokensIn: 0, tokensOut: 0, toolUses: 0 });
371
+ const taskUsage = tasks.reduce(
372
+ (acc, task) => {
373
+ acc.tokensIn += task.usage?.input ?? 0;
374
+ acc.tokensOut += task.usage?.output ?? 0;
375
+ acc.toolUses += task.agentProgress?.toolCount ?? 0;
376
+ return acc;
377
+ },
378
+ { tokensIn: 0, tokensOut: 0, toolUses: 0 },
379
+ );
332
380
  if (taskUsage.tokensIn || taskUsage.tokensOut || taskUsage.toolUses) return taskUsage;
333
- return agents.reduce((acc, agent) => {
334
- acc.tokensIn += agent.usage?.input ?? 0;
335
- acc.tokensOut += agent.usage?.output ?? agent.progress?.tokens ?? 0;
336
- acc.toolUses += agent.toolUses ?? agent.progress?.toolCount ?? 0;
337
- return acc;
338
- }, { tokensIn: 0, tokensOut: 0, toolUses: 0 });
381
+ return agents.reduce(
382
+ (acc, agent) => {
383
+ acc.tokensIn += agent.usage?.input ?? 0;
384
+ acc.tokensOut += agent.usage?.output ?? agent.progress?.tokens ?? 0;
385
+ acc.toolUses += agent.toolUses ?? agent.progress?.toolCount ?? 0;
386
+ return acc;
387
+ },
388
+ { tokensIn: 0, tokensOut: 0, toolUses: 0 },
389
+ );
339
390
  }
340
391
 
341
392
  function isMailboxStatus(value: unknown): value is MailboxMessageStatus {
@@ -377,9 +428,17 @@ function readGroupJoinMailbox(filePath: string, delivery: Record<string, Mailbox
377
428
  const parsed = JSON.parse(line) as unknown;
378
429
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return undefined;
379
430
  const message = parsed as { id?: unknown; data?: unknown };
380
- const data = message.data && typeof message.data === "object" && !Array.isArray(message.data) ? message.data as Record<string, unknown> : undefined;
431
+ const data =
432
+ message.data && typeof message.data === "object" && !Array.isArray(message.data)
433
+ ? (message.data as Record<string, unknown>)
434
+ : undefined;
381
435
  if (typeof message.id !== "string" || data?.kind !== "group_join" || typeof data.requestId !== "string") return undefined;
382
- return { requestId: data.requestId, messageId: message.id, partial: data.partial === true, ack: delivery[message.id] === "acknowledged" ? "acknowledged" as const : "pending" as const };
436
+ return {
437
+ requestId: data.requestId,
438
+ messageId: message.id,
439
+ partial: data.partial === true,
440
+ ack: delivery[message.id] === "acknowledged" ? ("acknowledged" as const) : ("pending" as const),
441
+ };
383
442
  } catch {
384
443
  return undefined;
385
444
  }
@@ -392,9 +451,17 @@ async function readGroupJoinMailboxAsync(filePath: string, delivery: Record<stri
392
451
  const parsed = JSON.parse(line) as unknown;
393
452
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return undefined;
394
453
  const message = parsed as { id?: unknown; data?: unknown };
395
- const data = message.data && typeof message.data === "object" && !Array.isArray(message.data) ? message.data as Record<string, unknown> : undefined;
454
+ const data =
455
+ message.data && typeof message.data === "object" && !Array.isArray(message.data)
456
+ ? (message.data as Record<string, unknown>)
457
+ : undefined;
396
458
  if (typeof message.id !== "string" || data?.kind !== "group_join" || typeof data.requestId !== "string") return undefined;
397
- return { requestId: data.requestId, messageId: message.id, partial: data.partial === true, ack: delivery[message.id] === "acknowledged" ? "acknowledged" as const : "pending" as const };
459
+ return {
460
+ requestId: data.requestId,
461
+ messageId: message.id,
462
+ partial: data.partial === true,
463
+ ack: delivery[message.id] === "acknowledged" ? ("acknowledged" as const) : ("pending" as const),
464
+ };
398
465
  } catch {
399
466
  return undefined;
400
467
  }
@@ -435,10 +502,20 @@ function readMailboxCounts(filePath: string, delivery: Record<string, MailboxMes
435
502
  try {
436
503
  const parsed = JSON.parse(line) as unknown;
437
504
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return 0;
438
- const msg = parsed as { id?: unknown; status?: unknown; kind?: unknown; data?: unknown };
505
+ const msg = parsed as {
506
+ id?: unknown;
507
+ status?: unknown;
508
+ kind?: unknown;
509
+ data?: unknown;
510
+ };
439
511
  if (typeof msg.id !== "string" || !isMailboxStatus(msg.status)) return 0;
440
512
  if (msg.status !== "acknowledged" && delivery[msg.id] !== "acknowledged") {
441
- const kind = typeof msg.kind === "string" ? msg.kind : typeof (msg.data as Record<string, unknown>)?.kind === "string" ? (msg.data as Record<string, unknown>).kind as string : undefined;
513
+ const kind =
514
+ typeof msg.kind === "string"
515
+ ? msg.kind
516
+ : typeof (msg.data as Record<string, unknown>)?.kind === "string"
517
+ ? ((msg.data as Record<string, unknown>).kind as string)
518
+ : undefined;
442
519
  if (kind === "steer") kindCounts.steer++;
443
520
  else if (kind === "follow-up") kindCounts.followUp++;
444
521
  else if (kind === "response") kindCounts.response++;
@@ -451,19 +528,36 @@ function readMailboxCounts(filePath: string, delivery: Record<string, MailboxMes
451
528
  }
452
529
  }) as number[];
453
530
  const count = items.reduce((sum, val) => sum + val, 0);
454
- return { count, approximate: tailApproximate(filePath), steer: kindCounts.steer, followUp: kindCounts.followUp, response: kindCounts.response, message: kindCounts.message };
531
+ return {
532
+ count,
533
+ approximate: tailApproximate(filePath),
534
+ steer: kindCounts.steer,
535
+ followUp: kindCounts.followUp,
536
+ response: kindCounts.response,
537
+ message: kindCounts.message,
538
+ };
455
539
  }
456
540
 
457
541
  async function readMailboxCountsAsync(filePath: string, delivery: Record<string, MailboxMessageStatus>): Promise<MailboxKindCount> {
458
542
  const kindCounts = { steer: 0, followUp: 0, response: 0, message: 0 };
459
- const items = await tailJsonlLinesAsync(filePath, MAX_TAIL_LINES, (line) => {
543
+ const items = (await tailJsonlLinesAsync(filePath, MAX_TAIL_LINES, (line) => {
460
544
  try {
461
545
  const parsed = JSON.parse(line) as unknown;
462
546
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return 0;
463
- const msg = parsed as { id?: unknown; status?: unknown; kind?: unknown; data?: unknown };
547
+ const msg = parsed as {
548
+ id?: unknown;
549
+ status?: unknown;
550
+ kind?: unknown;
551
+ data?: unknown;
552
+ };
464
553
  if (typeof msg.id !== "string" || !isMailboxStatus(msg.status)) return 0;
465
554
  if (msg.status !== "acknowledged" && delivery[msg.id] !== "acknowledged") {
466
- const kind = typeof msg.kind === "string" ? msg.kind : typeof (msg.data as Record<string, unknown>)?.kind === "string" ? (msg.data as Record<string, unknown>).kind as string : undefined;
555
+ const kind =
556
+ typeof msg.kind === "string"
557
+ ? msg.kind
558
+ : typeof (msg.data as Record<string, unknown>)?.kind === "string"
559
+ ? ((msg.data as Record<string, unknown>).kind as string)
560
+ : undefined;
467
561
  if (kind === "steer") kindCounts.steer++;
468
562
  else if (kind === "follow-up") kindCounts.followUp++;
469
563
  else if (kind === "response") kindCounts.response++;
@@ -474,9 +568,16 @@ async function readMailboxCountsAsync(filePath: string, delivery: Record<string,
474
568
  } catch {
475
569
  return 0;
476
570
  }
477
- }) as number[];
571
+ })) as number[];
478
572
  const count = items.reduce((sum, val) => sum + val, 0);
479
- return { count, approximate: await tailApproximateAsync(filePath), steer: kindCounts.steer, followUp: kindCounts.followUp, response: kindCounts.response, message: kindCounts.message };
573
+ return {
574
+ count,
575
+ approximate: await tailApproximateAsync(filePath),
576
+ steer: kindCounts.steer,
577
+ followUp: kindCounts.followUp,
578
+ response: kindCounts.response,
579
+ message: kindCounts.message,
580
+ };
480
581
  }
481
582
 
482
583
  function groupJoinsFrom(manifest: TeamRunManifest): RunUiGroupJoin[] {
@@ -509,7 +610,9 @@ function mailboxFrom(manifest: TeamRunManifest, agents: CrewAgentRecord[]): RunU
509
610
  let outbox = readMailboxCounts(path.join(root, "outbox.jsonl"), delivery);
510
611
  const tasksRoot = path.join(root, "tasks");
511
612
  try {
512
- for (const entry of fs.readdirSync(tasksRoot, { withFileTypes: true })) {
613
+ for (const entry of fs.readdirSync(tasksRoot, {
614
+ withFileTypes: true,
615
+ })) {
513
616
  if (!entry.isDirectory()) continue;
514
617
  const taskInbox = readMailboxCounts(path.join(tasksRoot, entry.name, "inbox.jsonl"), delivery);
515
618
  const taskOutbox = readMailboxCounts(path.join(tasksRoot, entry.name, "outbox.jsonl"), delivery);
@@ -521,8 +624,14 @@ function mailboxFrom(manifest: TeamRunManifest, agents: CrewAgentRecord[]): RunU
521
624
  }
522
625
  const attentionAgents = agents.filter((agent) => agent.progress?.activityState === "needs_attention").length;
523
626
  return {
524
- inboxUnread: inbox.count, outboxPending: outbox.count, needsAttention: inbox.count + attentionAgents, approximate: inbox.approximate || outbox.approximate,
525
- steerUnread: inbox.steer + outbox.steer, followUpUnread: inbox.followUp + outbox.followUp, responseUnread: inbox.response + outbox.response, messageUnread: inbox.message + outbox.message,
627
+ inboxUnread: inbox.count,
628
+ outboxPending: outbox.count,
629
+ needsAttention: inbox.count + attentionAgents,
630
+ approximate: inbox.approximate || outbox.approximate,
631
+ steerUnread: inbox.steer + outbox.steer,
632
+ followUpUnread: inbox.followUp + outbox.followUp,
633
+ responseUnread: inbox.response + outbox.response,
634
+ messageUnread: inbox.message + outbox.message,
526
635
  };
527
636
  }
528
637
 
@@ -533,7 +642,9 @@ async function mailboxFromAsync(manifest: TeamRunManifest, agents: CrewAgentReco
533
642
  let outbox = await readMailboxCountsAsync(path.join(root, "outbox.jsonl"), delivery);
534
643
  const tasksRoot = path.join(root, "tasks");
535
644
  try {
536
- for (const entry of await fs.promises.readdir(tasksRoot, { withFileTypes: true })) {
645
+ for (const entry of await fs.promises.readdir(tasksRoot, {
646
+ withFileTypes: true,
647
+ })) {
537
648
  if (!entry.isDirectory()) continue;
538
649
  const taskInbox = await readMailboxCountsAsync(path.join(tasksRoot, entry.name, "inbox.jsonl"), delivery);
539
650
  const taskOutbox = await readMailboxCountsAsync(path.join(tasksRoot, entry.name, "outbox.jsonl"), delivery);
@@ -545,33 +656,59 @@ async function mailboxFromAsync(manifest: TeamRunManifest, agents: CrewAgentReco
545
656
  }
546
657
  const attentionAgents = agents.filter((agent) => agent.progress?.activityState === "needs_attention").length;
547
658
  return {
548
- inboxUnread: inbox.count, outboxPending: outbox.count, needsAttention: inbox.count + attentionAgents, approximate: inbox.approximate || outbox.approximate,
549
- steerUnread: inbox.steer + outbox.steer, followUpUnread: inbox.followUp + outbox.followUp, responseUnread: inbox.response + outbox.response, messageUnread: inbox.message + outbox.message,
659
+ inboxUnread: inbox.count,
660
+ outboxPending: outbox.count,
661
+ needsAttention: inbox.count + attentionAgents,
662
+ approximate: inbox.approximate || outbox.approximate,
663
+ steerUnread: inbox.steer + outbox.steer,
664
+ followUpUnread: inbox.followUp + outbox.followUp,
665
+ responseUnread: inbox.response + outbox.response,
666
+ messageUnread: inbox.message + outbox.message,
550
667
  };
551
668
  }
552
669
 
553
670
  function cancellationReasonFromEvents(events: TeamEvent[]): string | undefined {
554
- return [...events].reverse().find((event) => event.type === "run.cancelled" && typeof event.data?.reason === "string")?.data?.reason as string | undefined;
671
+ return [...events].reverse().find((event) => event.type === "run.cancelled" && typeof event.data?.reason === "string")?.data?.reason as
672
+ | string
673
+ | undefined;
555
674
  }
556
675
 
557
676
  function signatureFor(input: Omit<RunUiSnapshot, "signature" | "fetchedAt" | "sliceSignatures">, stamps: SnapshotStamps): string {
558
677
  try {
559
678
  const digest = createHash("sha256");
560
- digest.update(JSON.stringify({
561
- run: [input.manifest.runId, input.manifest.status, input.manifest.updatedAt, input.manifest.artifacts.length],
562
- tasks: input.tasks.map((task) => [task.id, task.status, task.startedAt, task.finishedAt, task.agentProgress, task.usage]),
563
- agents: input.agents.map((agent) => [agent.id, agent.status, agent.startedAt, agent.completedAt, agent.toolUses, agent.progress, agent.usage, agent.model]),
564
- progress: input.progress,
565
- usage: input.usage,
566
- mailbox: input.mailbox,
567
- groupJoins: input.groupJoins,
568
- events: input.recentEvents.map((event) => [event.metadata?.seq, event.time, event.type, event.taskId, event.message, event.data?.reason]),
569
- cancellationReason: input.cancellationReason,
570
- dwfPhaseState: input.dwfPhaseState,
571
- output: input.recentOutputLines,
572
- stamps,
573
- }));
574
- return digest.digest("hex").slice(0, 16);
679
+ digest.update(
680
+ JSON.stringify({
681
+ run: [input.manifest.runId, input.manifest.status, input.manifest.updatedAt, input.manifest.artifacts.length],
682
+ tasks: input.tasks.map((task) => [task.id, task.status, task.startedAt, task.finishedAt, task.agentProgress, task.usage]),
683
+ agents: input.agents.map((agent) => [
684
+ agent.id,
685
+ agent.status,
686
+ agent.startedAt,
687
+ agent.completedAt,
688
+ agent.toolUses,
689
+ agent.progress,
690
+ agent.usage,
691
+ agent.model,
692
+ ]),
693
+ progress: input.progress,
694
+ usage: input.usage,
695
+ mailbox: input.mailbox,
696
+ groupJoins: input.groupJoins,
697
+ events: input.recentEvents.map((event) => [
698
+ event.metadata?.seq,
699
+ event.time,
700
+ event.type,
701
+ event.taskId,
702
+ event.message,
703
+ event.data?.reason,
704
+ ]),
705
+ cancellationReason: input.cancellationReason,
706
+ dwfPhaseState: input.dwfPhaseState,
707
+ output: input.recentOutputLines,
708
+ stamps,
709
+ }),
710
+ );
711
+ return digest.digest("hex").slice(0, 16);
575
712
  } catch {
576
713
  // Circular reference or non-serializable data — fall back to timestamp.
577
714
  return String(Date.now());
@@ -593,10 +730,30 @@ function sliceSignaturesFor(input: Omit<RunUiSnapshot, "signature" | "fetchedAt"
593
730
  };
594
731
  return {
595
732
  tasks: hash(input.tasks.map((task) => [task.id, task.status, task.startedAt, task.finishedAt, task.agentProgress, task.usage])),
596
- agents: hash(input.agents.map((agent) => [agent.id, agent.status, agent.startedAt, agent.completedAt, agent.toolUses, agent.progress, agent.usage, agent.model])),
733
+ agents: hash(
734
+ input.agents.map((agent) => [
735
+ agent.id,
736
+ agent.status,
737
+ agent.startedAt,
738
+ agent.completedAt,
739
+ agent.toolUses,
740
+ agent.progress,
741
+ agent.usage,
742
+ agent.model,
743
+ ]),
744
+ ),
597
745
  mailbox: hash([input.mailbox, input.groupJoins]),
598
746
  progress: hash([input.progress, input.usage, input.cancellationReason]),
599
- events: hash(input.recentEvents.map((event) => [event.metadata?.seq, event.time, event.type, event.taskId, event.message, event.data?.reason])),
747
+ events: hash(
748
+ input.recentEvents.map((event) => [
749
+ event.metadata?.seq,
750
+ event.time,
751
+ event.type,
752
+ event.taskId,
753
+ event.message,
754
+ event.data?.reason,
755
+ ]),
756
+ ),
600
757
  };
601
758
  }
602
759
 
@@ -623,7 +780,13 @@ async function stampsForAsync(manifest: TeamRunManifest, _agents: CrewAgentRecor
623
780
  eventsStampAsync(manifest.eventsPath),
624
781
  mailboxStampAsync(manifest),
625
782
  ]);
626
- return { manifest: manifestStamp, tasks: tasksStamp, agents: agentsStamp, events: eventsStampValue, mailbox };
783
+ return {
784
+ manifest: manifestStamp,
785
+ tasks: tasksStamp,
786
+ agents: agentsStamp,
787
+ events: eventsStampValue,
788
+ mailbox,
789
+ };
627
790
  }
628
791
 
629
792
  export function createRunSnapshotCache(cwd: string, options: RunSnapshotCacheOptions = {}): RunSnapshotCache {
@@ -691,8 +854,18 @@ export function createRunSnapshotCache(cwd: string, options: RunSnapshotCacheOpt
691
854
  recentOutputLines: recentOutputLines(loaded.manifest, agents, recentOutputLimit),
692
855
  };
693
856
  const stamps = stampsFor(loaded.manifest, agents);
694
- const snapshot: RunUiSnapshot = { ...base, fetchedAt: Date.now(), signature: signatureFor(base, stamps), sliceSignatures: sliceSignaturesFor(base) };
695
- return { snapshot, stamps, loadedAtMs: snapshot.fetchedAt, lastAccessMs: snapshot.fetchedAt };
857
+ const snapshot: RunUiSnapshot = {
858
+ ...base,
859
+ fetchedAt: Date.now(),
860
+ signature: signatureFor(base, stamps),
861
+ sliceSignatures: sliceSignaturesFor(base),
862
+ };
863
+ return {
864
+ snapshot,
865
+ stamps,
866
+ loadedAtMs: snapshot.fetchedAt,
867
+ lastAccessMs: snapshot.fetchedAt,
868
+ };
696
869
  }
697
870
 
698
871
  async function buildAsync(runId: string, previous?: CacheEntry): Promise<CacheEntry> {
@@ -738,8 +911,18 @@ export function createRunSnapshotCache(cwd: string, options: RunSnapshotCacheOpt
738
911
  recentOutputLines: recentOutput,
739
912
  };
740
913
  const stamps = await stampsForAsync(loaded.manifest, agents);
741
- const snapshot: RunUiSnapshot = { ...base, fetchedAt: Date.now(), signature: signatureFor(base, stamps), sliceSignatures: sliceSignaturesFor(base) };
742
- return { snapshot, stamps, loadedAtMs: snapshot.fetchedAt, lastAccessMs: snapshot.fetchedAt };
914
+ const snapshot: RunUiSnapshot = {
915
+ ...base,
916
+ fetchedAt: Date.now(),
917
+ signature: signatureFor(base, stamps),
918
+ sliceSignatures: sliceSignaturesFor(base),
919
+ };
920
+ return {
921
+ snapshot,
922
+ stamps,
923
+ loadedAtMs: snapshot.fetchedAt,
924
+ lastAccessMs: snapshot.fetchedAt,
925
+ };
743
926
  }
744
927
 
745
928
  function currentStamps(previous: CacheEntry): SnapshotStamps {
@@ -819,10 +1002,17 @@ export function createRunSnapshotCache(cwd: string, options: RunSnapshotCacheOpt
819
1002
  const scheduleRefresh = (runId: string): void => {
820
1003
  const existing = pendingRefreshes.get(runId);
821
1004
  if (existing) clearTimeout(existing);
822
- pendingRefreshes.set(runId, setTimeout(() => {
823
- pendingRefreshes.delete(runId);
824
- try { localRefreshIfStale(runId); } catch { /* best-effort; widget falls back gracefully */ }
825
- }, INVAL_COALESCE_MS));
1005
+ pendingRefreshes.set(
1006
+ runId,
1007
+ setTimeout(() => {
1008
+ pendingRefreshes.delete(runId);
1009
+ try {
1010
+ localRefreshIfStale(runId);
1011
+ } catch {
1012
+ /* best-effort; widget falls back gracefully */
1013
+ }
1014
+ }, INVAL_COALESCE_MS),
1015
+ );
826
1016
  };
827
1017
  const unsubState = runEventBus.onChannel("run:state", (event) => {
828
1018
  if (entries.has(event.runId)) scheduleRefresh(event.runId);