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,21 +1,21 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
- import type { TeamRunManifest, TeamTaskState } from "./types.ts";
4
- import { canTransitionRunStatus } from "./contracts.ts";
5
- import { unregisterActiveRun } from "./active-run-registry.ts";
6
- import { atomicWriteJson, atomicWriteJsonAsync, atomicWriteJsonCoalesced, readJsonFile } from "./atomic-write.ts";
7
- import { appendEvent } from "./event-log.ts";
8
3
  import { DEFAULT_CACHE, DEFAULT_PATHS } from "../config/defaults.ts";
4
+ import { errors } from "../errors.ts";
5
+ import type { TeamConfig } from "../teams/team-config.ts";
9
6
  import { createRunId, createTaskId } from "../utils/ids.ts";
7
+ import { logInternalError } from "../utils/internal-error.ts";
10
8
  import { findRepoRoot, projectCrewRoot, userCrewRoot } from "../utils/paths.ts";
11
9
  import { assertSafePathId, resolveContainedRelativePath, resolveRealContainedPath } from "../utils/safe-paths.ts";
12
- import { withRunLock, withRunLockSync } from "./locks.ts";
13
- import { logInternalError } from "../utils/internal-error.ts";
14
- import { errors } from "../errors.ts";
15
- import type { TeamConfig } from "../teams/team-config.ts";
16
- import type { WorkflowConfig } from "../workflows/workflow-config.ts";
17
10
  import { toPiSessionId } from "../utils/session-utils.ts";
11
+ import type { WorkflowConfig } from "../workflows/workflow-config.ts";
12
+ import { unregisterActiveRun } from "./active-run-registry.ts";
13
+ import { atomicWriteJson, atomicWriteJsonAsync, atomicWriteJsonCoalesced, readJsonFile } from "./atomic-write.ts";
14
+ import { canTransitionRunStatus } from "./contracts.ts";
15
+ import { appendEvent } from "./event-log.ts";
18
16
  import { HealthStore } from "./health-store.ts";
17
+ import { withRunLock, withRunLockSync } from "./locks.ts";
18
+ import type { TeamRunManifest, TeamTaskState } from "./types.ts";
19
19
 
20
20
  /**
21
21
  * stat() the manifest with a brief retry on Windows for the AV-scan window.
@@ -42,7 +42,9 @@ function statManifestWithWindowsRetry(manifestPath: string): fs.Stats {
42
42
  const code = (error as NodeJS.ErrnoException).code;
43
43
  if (!retryable.has(code ?? "")) throw error;
44
44
  const end = Date.now() + Math.min(8, 1 * 2 ** attempt);
45
- while (Date.now() < end) { /* brief spin to ride out the AV scan window */ }
45
+ while (Date.now() < end) {
46
+ /* brief spin to ride out the AV scan window */
47
+ }
46
48
  }
47
49
  }
48
50
  return fs.statSync(manifestPath); // last attempt — let caller's catch handle ENOENT
@@ -111,7 +113,10 @@ function setManifestCache(stateRoot: string, entry: ManifestCacheEntry): void {
111
113
  let oldestTime = Infinity;
112
114
  for (const [key, val] of manifestCache.entries()) {
113
115
  const t = val.cachedAt ?? 0;
114
- if (t < oldestTime) { oldestTime = t; oldestKey = key; }
116
+ if (t < oldestTime) {
117
+ oldestTime = t;
118
+ oldestKey = key;
119
+ }
115
120
  }
116
121
  if (!oldestKey) break;
117
122
  manifestCache.delete(oldestKey);
@@ -151,7 +156,13 @@ function validateRunManifestPaths(cwd: string, runId: string, manifest: TeamRunM
151
156
  // Issue 2 fix: Reject manifests missing status field to prevent undefined
152
157
  // behavior in callers like canTransitionRunStatus(manifest.status, newStatus).
153
158
  if (!manifest.status || typeof manifest.status !== "string") return false;
154
- if (manifest.runId !== runId || manifest.stateRoot !== stateRoot || manifest.tasksPath !== tasksPath || manifest.eventsPath !== path.join(stateRoot, "events.jsonl")) return false;
159
+ if (
160
+ manifest.runId !== runId ||
161
+ manifest.stateRoot !== stateRoot ||
162
+ manifest.tasksPath !== tasksPath ||
163
+ manifest.eventsPath !== path.join(stateRoot, "events.jsonl")
164
+ )
165
+ return false;
155
166
  const artifactsParent = path.join(scopeBaseRoot(cwd), DEFAULT_PATHS.state.artifactsSubdir);
156
167
  const expectedArtifactsRoot = resolveContainedRelativePath(artifactsParent, runId, "runId");
157
168
  if (manifest.artifactsRoot !== expectedArtifactsRoot) return false;
@@ -197,7 +208,10 @@ export function createTasksFromWorkflow(runId: string, workflow: WorkflowConfig,
197
208
  const role = team.roles.find((candidate) => candidate.name === step.role);
198
209
  const id = stepToTaskId.get(step.id) ?? createTaskId(step.id, index);
199
210
  const dependencies = step.dependsOn ?? [];
200
- const children = workflow.steps.filter((candidate) => candidate.dependsOn?.includes(step.id)).map((candidate) => stepToTaskId.get(candidate.id)).filter((childId): childId is string => childId !== undefined);
211
+ const children = workflow.steps
212
+ .filter((candidate) => candidate.dependsOn?.includes(step.id))
213
+ .map((candidate) => stepToTaskId.get(candidate.id))
214
+ .filter((childId): childId is string => childId !== undefined);
201
215
  return {
202
216
  id,
203
217
  runId,
@@ -268,8 +282,13 @@ export function createRunManifest(params: {
268
282
  // "unknown"). Include it explicitly in the thrown message so CI logs and
269
283
  // production callers can see WHY the write failed instead of ": unknown".
270
284
  const cause = result.error ? `: ${result.error}` : "";
271
- throw errors.fileWrite(paths.stateRoot, { code: "EWRITEFAIL" } as NodeJS.ErrnoException)
272
- .withContext(`saveManifestAndTasksAtomicSync: manifestWritten=${result.manifestWritten}, tasksWritten=${result.tasksWritten}${cause}`);
285
+ throw errors
286
+ .fileWrite(paths.stateRoot, {
287
+ code: "EWRITEFAIL",
288
+ } as NodeJS.ErrnoException)
289
+ .withContext(
290
+ `saveManifestAndTasksAtomicSync: manifestWritten=${result.manifestWritten}, tasksWritten=${result.tasksWritten}${cause}`,
291
+ );
273
292
  }
274
293
  appendEvent(paths.eventsPath, {
275
294
  type: "run.created",
@@ -278,8 +297,16 @@ export function createRunManifest(params: {
278
297
  metadata: {
279
298
  seq: 1,
280
299
  provenance: "team_runner",
281
- sessionIdentity: { title: params.team.name, workspace: params.cwd, purpose: params.goal },
282
- ownership: { owner: params.team.name, workflowScope: params.workflow?.name ?? "manual", watcherAction: "act" },
300
+ sessionIdentity: {
301
+ title: params.team.name,
302
+ workspace: params.cwd,
303
+ purpose: params.goal,
304
+ },
305
+ ownership: {
306
+ owner: params.team.name,
307
+ workflowScope: params.workflow?.name ?? "manual",
308
+ watcherAction: "act",
309
+ },
283
310
  confidence: "high",
284
311
  },
285
312
  });
@@ -395,20 +422,34 @@ export function saveRunTasks(manifest: TeamRunManifest, tasks: TeamTaskState[]):
395
422
  * see the previous on-disk content while the write is still buffered).
396
423
  * Bulk update paths that fan out into multiple writer call sites are the
397
424
  * intended use case. Single-update + read-update loops (e.g.
398
- * persistSingleTaskUpdate) should keep using saveRunTasks.
425
+ * persistSingleTaskUpdate) should keep using saveRunTasks — OR call
426
+ * `flushPendingAtomicWrites()` immediately before their read to force
427
+ * any pending coalesced writes to land on disk first.
428
+ *
429
+ * (perf review 2026-07 F4) — now used by persistSingleTaskUpdate's
430
+ * non-terminal checkpoint path; that caller calls flushPendingAtomicWrites()
431
+ * before its read-modify-write load to defeat the stale-read window.
399
432
  */
400
433
  /** @internal */
401
- function saveRunTasksCoalesced(manifest: TeamRunManifest, tasks: TeamTaskState[]): void {
434
+ export function saveRunTasksCoalesced(manifest: TeamRunManifest, tasks: TeamTaskState[]): void {
402
435
  // FIX: Invalidate cache BEFORE atomic write to prevent stale cache serving.
403
436
  invalidateRunCache(manifest.stateRoot);
404
- try { fs.statSync(manifest.stateRoot); } catch { return; }
437
+ try {
438
+ fs.statSync(manifest.stateRoot);
439
+ } catch {
440
+ return;
441
+ }
405
442
  atomicWriteJsonCoalesced(manifest.tasksPath, tasks);
406
443
  }
407
444
 
408
445
  export async function saveRunTasksAsync(manifest: TeamRunManifest, tasks: TeamTaskState[]): Promise<void> {
409
446
  // FIX: Invalidate cache BEFORE atomic write to prevent stale cache serving.
410
447
  invalidateRunCache(manifest.stateRoot);
411
- try { fs.statSync(manifest.stateRoot); } catch { return; }
448
+ try {
449
+ fs.statSync(manifest.stateRoot);
450
+ } catch {
451
+ return;
452
+ }
412
453
  await atomicWriteJsonAsync(manifest.tasksPath, tasks);
413
454
  }
414
455
 
@@ -490,18 +531,32 @@ export interface UpdateRunStatusOptions {
490
531
  metadata?: Parameters<typeof appendEvent>[1]["metadata"];
491
532
  }
492
533
 
493
- export function updateRunStatus(manifest: TeamRunManifest, status: TeamRunManifest["status"], summary?: string, options: UpdateRunStatusOptions = {}): TeamRunManifest {
534
+ export function updateRunStatus(
535
+ manifest: TeamRunManifest,
536
+ status: TeamRunManifest["status"],
537
+ summary?: string,
538
+ options: UpdateRunStatusOptions = {},
539
+ ): TeamRunManifest {
494
540
  if (!canTransitionRunStatus(manifest.status, status)) {
495
541
  throw errors.invalidStatusTransition(manifest.status, status);
496
542
  }
497
- const updated: TeamRunManifest = { ...manifest, status, updatedAt: new Date().toISOString(), summary: summary ?? manifest.summary };
543
+ const updated: TeamRunManifest = {
544
+ ...manifest,
545
+ status,
546
+ updatedAt: new Date().toISOString(),
547
+ summary: summary ?? manifest.summary,
548
+ };
498
549
  saveRunManifest(updated);
499
550
  // Unregister from active-run-index when run reaches a terminal status.
500
551
  // Without this, stale entries accumulate (e.g. integration tests in /tmp) and
501
552
  // Pi UI shows ghost "queued" runs that are actually completed/failed/cancelled.
502
553
  // Note: "blocked" is excluded because blocked runs can be unblocked later.
503
554
  if (status === "completed" || status === "failed" || status === "cancelled") {
504
- try { unregisterActiveRun(updated.runId); } catch { /* non-critical */ }
555
+ try {
556
+ unregisterActiveRun(updated.runId);
557
+ } catch {
558
+ /* non-critical */
559
+ }
505
560
  }
506
561
  appendEvent(updated.eventsPath, {
507
562
  type: `run.${status}`,
@@ -510,8 +565,16 @@ export function updateRunStatus(manifest: TeamRunManifest, status: TeamRunManife
510
565
  ...(options.data ? { data: options.data } : {}),
511
566
  metadata: {
512
567
  provenance: "team_runner",
513
- sessionIdentity: { title: updated.team, workspace: updated.cwd, purpose: updated.goal },
514
- ownership: { owner: updated.team, workflowScope: updated.workflow ?? "manual", watcherAction: "act" },
568
+ sessionIdentity: {
569
+ title: updated.team,
570
+ workspace: updated.cwd,
571
+ purpose: updated.goal,
572
+ },
573
+ ownership: {
574
+ owner: updated.team,
575
+ workflowScope: updated.workflow ?? "manual",
576
+ watcherAction: "act",
577
+ },
515
578
  confidence: "high",
516
579
  ...options.metadata,
517
580
  },
@@ -574,12 +637,12 @@ export function loadRunManifestById(cwd: string, runId: string): { manifest: Tea
574
637
  }
575
638
  const tasksMtimeMs = tasksStat?.mtimeMs ?? 0;
576
639
  if (
577
- cached
578
- && cached.manifestMtimeMs === manifestStat.mtimeMs
579
- && cached.manifestSize === manifestStat.size
580
- && cached.tasksMtimeMs === tasksMtimeMs
581
- && cached.tasksSize === (tasksStat?.size ?? 0)
582
- && cached.generation === manifestCacheGeneration
640
+ cached &&
641
+ cached.manifestMtimeMs === manifestStat.mtimeMs &&
642
+ cached.manifestSize === manifestStat.size &&
643
+ cached.tasksMtimeMs === tasksMtimeMs &&
644
+ cached.tasksSize === (tasksStat?.size ?? 0) &&
645
+ cached.generation === manifestCacheGeneration
583
646
  ) {
584
647
  // TTL eviction: expire stale entries even if mtime matches
585
648
  // FIX: Also evict entries where cachedAt is undefined — such entries are
@@ -592,7 +655,7 @@ export function loadRunManifestById(cwd: string, runId: string): { manifest: Tea
592
655
  } else if (!validateRunManifestPaths(cwd, runId, cached.manifest, stateRoot, tasksPath)) {
593
656
  manifestCache.delete(stateRoot);
594
657
  return undefined;
595
- } else if (!fs.existsSync(tasksPath)) {
658
+ } else if (!fs.existsSync(tasksPath)) {
596
659
  // Tasks file was deleted after cache was populated — this is a cache miss,
597
660
  // not a manifest inconsistency. The cache check passes because
598
661
  // tasksMtimeMs=0 and tasksSize=0 match a cache entry written when tasks.json
@@ -621,8 +684,11 @@ export function loadRunManifestById(cwd: string, runId: string): { manifest: Tea
621
684
  const freshTasksStat = fs.existsSync(tasksPath) ? fs.statSync(tasksPath) : undefined;
622
685
  tasks = readJsonFile<TeamTaskState[]>(tasksPath) ?? [];
623
686
  // If size/mtime didn't change between stat and read, we're consistent.
624
- if (freshStat.mtimeMs === manifestStat.mtimeMs && freshStat.size === manifestStat.size
625
- && (!freshTasksStat || (freshTasksStat.mtimeMs === tasksStat?.mtimeMs && freshTasksStat.size === tasksStat?.size))) {
687
+ if (
688
+ freshStat.mtimeMs === manifestStat.mtimeMs &&
689
+ freshStat.size === manifestStat.size &&
690
+ (!freshTasksStat || (freshTasksStat.mtimeMs === tasksStat?.mtimeMs && freshTasksStat.size === tasksStat?.size))
691
+ ) {
626
692
  break;
627
693
  }
628
694
  attempts += 1;
@@ -637,7 +703,9 @@ export function loadRunManifestById(cwd: string, runId: string): { manifest: Tea
637
703
  // Round 19: downgrade to debug — retry-loop instability is expected under
638
704
  // concurrent writes (live team runs constantly append to tasks.json).
639
705
  // This is best-effort by design; strict consistency requires withRunLock().
640
- console.debug(`[state-store] loadRunManifestById: retry loop detected instability for run ${runId} after ${attempts} attempt(s) — best-effort only, use withRunLock() for strict consistency`);
706
+ console.debug(
707
+ `[state-store] loadRunManifestById: retry loop detected instability for run ${runId} after ${attempts} attempt(s) — best-effort only, use withRunLock() for strict consistency`,
708
+ );
641
709
  }
642
710
  // NOTE: manifest mtime may legitimately be >= tasks mtime because
643
711
  // saveManifestAndTasksAtomicSync writes manifest before tasks. However,
@@ -659,7 +727,10 @@ export function loadRunManifestById(cwd: string, runId: string): { manifest: Tea
659
727
  return { manifest, tasks: tasks ?? [] };
660
728
  }
661
729
 
662
- export async function loadRunManifestByIdAsync(cwd: string, runId: string): Promise<{ manifest: TeamRunManifest; tasks: TeamTaskState[] } | undefined> {
730
+ export async function loadRunManifestByIdAsync(
731
+ cwd: string,
732
+ runId: string,
733
+ ): Promise<{ manifest: TeamRunManifest; tasks: TeamTaskState[] } | undefined> {
663
734
  const stateRoot = resolveRunStateRoot(cwd, runId);
664
735
  if (!stateRoot) return undefined;
665
736
  const manifestPath = path.join(stateRoot, "manifest.json");
@@ -681,7 +752,14 @@ export async function loadRunManifestByIdAsync(cwd: string, runId: string): Prom
681
752
  tasksStat = undefined;
682
753
  }
683
754
  const tasksMtimeMs = tasksStat?.mtimeMs ?? 0;
684
- if (cached && cached.manifestMtimeMs === manifestStat.mtimeMs && cached.manifestSize === manifestStat.size && cached.tasksMtimeMs === tasksMtimeMs && cached.tasksSize === (tasksStat?.size ?? 0) && cached.generation === manifestCacheGeneration) {
755
+ if (
756
+ cached &&
757
+ cached.manifestMtimeMs === manifestStat.mtimeMs &&
758
+ cached.manifestSize === manifestStat.size &&
759
+ cached.tasksMtimeMs === tasksMtimeMs &&
760
+ cached.tasksSize === (tasksStat?.size ?? 0) &&
761
+ cached.generation === manifestCacheGeneration
762
+ ) {
685
763
  // TTL eviction: expire stale entries even if mtime matches
686
764
  // FIX: Also evict entries where cachedAt is undefined — such entries are
687
765
  // effectively immortal otherwise (the `cached.cachedAt &&` check would skip
@@ -693,10 +771,10 @@ export async function loadRunManifestByIdAsync(cwd: string, runId: string): Prom
693
771
  } else if (!validateRunManifestPaths(cwd, runId, cached.manifest, stateRoot, tasksPath)) {
694
772
  manifestCache.delete(stateRoot);
695
773
  return undefined;
696
- } else if (!fs.existsSync(tasksPath)) {
697
- // Tasks file was deleted after cache was populated — do not serve stale cache.
698
- manifestCache.delete(stateRoot);
699
- return undefined;
774
+ } else if (!fs.existsSync(tasksPath)) {
775
+ // Tasks file was deleted after cache was populated — do not serve stale cache.
776
+ manifestCache.delete(stateRoot);
777
+ return undefined;
700
778
  } else {
701
779
  return { manifest: cached.manifest, tasks: cached.tasks ?? [] };
702
780
  }
@@ -714,8 +792,11 @@ export async function loadRunManifestByIdAsync(cwd: string, runId: string): Prom
714
792
  const freshTasksStat = await fs.promises.stat(tasksPath).catch(() => undefined);
715
793
  tasks = (await readJsonFileAsync<TeamTaskState[]>(tasksPath)) ?? [];
716
794
  // If size/mtime didn't change between stat and read, we're consistent.
717
- if (freshStat.mtimeMs === manifestStat.mtimeMs && freshStat.size === manifestStat.size
718
- && (!freshTasksStat || (freshTasksStat.mtimeMs === tasksStat?.mtimeMs && freshTasksStat.size === tasksStat?.size))) {
795
+ if (
796
+ freshStat.mtimeMs === manifestStat.mtimeMs &&
797
+ freshStat.size === manifestStat.size &&
798
+ (!freshTasksStat || (freshTasksStat.mtimeMs === tasksStat?.mtimeMs && freshTasksStat.size === tasksStat?.size))
799
+ ) {
719
800
  break;
720
801
  }
721
802
  attempts += 1;
@@ -730,7 +811,9 @@ export async function loadRunManifestByIdAsync(cwd: string, runId: string): Prom
730
811
  // Round 19: downgrade to debug — retry-loop instability is expected under
731
812
  // concurrent writes (live team runs constantly append to tasks.json).
732
813
  // This is best-effort by design; strict consistency requires withRunLock().
733
- console.debug(`[state-store] loadRunManifestByIdAsync: retry loop detected instability for run ${runId} after ${attempts} attempt(s) — best-effort only, use withRunLock() for strict consistency`);
814
+ console.debug(
815
+ `[state-store] loadRunManifestByIdAsync: retry loop detected instability for run ${runId} after ${attempts} attempt(s) — best-effort only, use withRunLock() for strict consistency`,
816
+ );
734
817
  }
735
818
  // NOTE: manifest mtime may legitimately be >= tasks mtime because
736
819
  // saveManifestAndTasksAtomicSync writes manifest before tasks. However,
@@ -742,6 +825,13 @@ export async function loadRunManifestByIdAsync(cwd: string, runId: string): Prom
742
825
  // It does not indicate corruption on its own.
743
826
 
744
827
  if (!manifest || !validateRunManifestPaths(cwd, runId, manifest, stateRoot, tasksPath)) return undefined;
745
- setManifestCache(stateRoot, { manifest, tasks: tasks ?? [], manifestMtimeMs: manifestStat.mtimeMs, manifestSize: manifestStat.size, tasksMtimeMs, tasksSize: tasksStat?.size ?? 0 });
828
+ setManifestCache(stateRoot, {
829
+ manifest,
830
+ tasks: tasks ?? [],
831
+ manifestMtimeMs: manifestStat.mtimeMs,
832
+ manifestSize: manifestStat.size,
833
+ tasksMtimeMs,
834
+ tasksSize: tasksStat?.size ?? 0,
835
+ });
746
836
  return { manifest, tasks: tasks ?? [] };
747
837
  }
@@ -8,7 +8,11 @@ export interface TaskClaimState {
8
8
  }
9
9
 
10
10
  export function createTaskClaim(owner: string, leaseMs = 5 * 60_000, now = new Date()): TaskClaimState {
11
- return { owner, token: randomUUID(), leasedUntil: new Date(now.getTime() + leaseMs).toISOString() };
11
+ return {
12
+ owner,
13
+ token: randomUUID(),
14
+ leasedUntil: new Date(now.getTime() + leaseMs).toISOString(),
15
+ };
12
16
  }
13
17
 
14
18
  export function isTaskClaimExpired(claim: TaskClaimState | undefined, now = new Date()): boolean {
@@ -43,7 +47,13 @@ export function releaseTaskClaim<T extends TeamTaskState>(task: T, owner: string
43
47
  return { ...task, claim: undefined };
44
48
  }
45
49
 
46
- export function transitionClaimedTaskStatus<T extends TeamTaskState>(task: T, owner: string, token: string, status: T["status"], now = new Date()): T {
50
+ export function transitionClaimedTaskStatus<T extends TeamTaskState>(
51
+ task: T,
52
+ owner: string,
53
+ token: string,
54
+ status: T["status"],
55
+ now = new Date(),
56
+ ): T {
47
57
  if (!canUseTaskClaim(task, owner, token, now)) {
48
58
  throw new Error(`Task '${task.id}' claim is not held by '${owner}' or has expired.`);
49
59
  }
@@ -1,15 +1,15 @@
1
1
  /**
2
2
  * Tiered Evaluation System
3
- *
3
+ *
4
4
  * Inspired by agent-eval's judge tiers, this module provides a hierarchical
5
5
  * evaluation system where checks are grouped by computational cost and reliability:
6
- *
6
+ *
7
7
  * - Tier 1 (deterministic): Fast checks (~1s timeout) - file exists, parse errors, etc.
8
8
  * - Tier 2 (pattern): Medium checks (~5s timeout) - grep, regex, structural checks
9
9
  * - Tier 3 (llm): Expensive checks (~60s timeout) - LLM-based evaluation
10
10
  */
11
11
 
12
- import type { EvalTier, TierConfig, EvalResult } from "./types-eval.ts";
12
+ import type { EvalResult, EvalTier, TierConfig } from "./types-eval.ts";
13
13
 
14
14
  /**
15
15
  * Default tier configurations with increasing timeouts for more expensive evaluations.
@@ -40,7 +40,7 @@ export const TIER_CONFIGS: Record<EvalTier, TierConfig> = {
40
40
  */
41
41
  export const DEFAULT_TIER_CONFIGS = TIER_CONFIGS;
42
42
 
43
- export type { EvalTier, TierConfig, EvalResult };
43
+ export type { EvalResult, EvalTier, TierConfig };
44
44
 
45
45
  /**
46
46
  * Individual evaluation check with its assigned tier.
@@ -99,21 +99,21 @@ export interface TieredEvalResult {
99
99
  /**
100
100
  * TieredEvalRunner executes evaluation checks in tiered order,
101
101
  * with appropriate timeouts for each tier level.
102
- *
102
+ *
103
103
  * Supports two execution modes:
104
104
  * - runTieredEval: Runs all checks regardless of failures
105
105
  * - runTieredEvalFailFast: Stops at first failure (like ECC promotion gates)
106
- *
106
+ *
107
107
  * @example
108
108
  * ```typescript
109
109
  * const runner = new TieredEvalRunner();
110
- *
110
+ *
111
111
  * // Run all checks
112
112
  * const allResults = await runner.runTieredEval('task-1', [
113
113
  * { tier: 1, check: () => fs.existsSync('output.json') },
114
114
  * { tier: 2, check: async () => (await run('grep', ['pattern', 'output.json'])).exitCode === 0 }
115
115
  * ]);
116
- *
116
+ *
117
117
  * // Fail-fast mode
118
118
  * const failFastResult = await runner.runTieredEvalFailFast('task-2', [
119
119
  * { tier: 1, check: () => fs.existsSync('output.json') },
@@ -129,7 +129,7 @@ export class TieredEvalRunner {
129
129
 
130
130
  /**
131
131
  * Creates a new TieredEvalRunner instance.
132
- *
132
+ *
133
133
  * @param config - Optional configuration to override defaults
134
134
  */
135
135
  constructor(config?: TieredEvalRunnerConfig) {
@@ -154,7 +154,7 @@ export class TieredEvalRunner {
154
154
 
155
155
  /**
156
156
  * Gets the effective timeout for a given tier.
157
- *
157
+ *
158
158
  * @param tier - The evaluation tier
159
159
  * @returns The timeout in milliseconds (after multiplier is applied)
160
160
  */
@@ -164,7 +164,7 @@ export class TieredEvalRunner {
164
164
 
165
165
  /**
166
166
  * Gets the configuration for a specific tier.
167
- *
167
+ *
168
168
  * @param tier - The evaluation tier
169
169
  * @returns The tier configuration
170
170
  */
@@ -174,15 +174,12 @@ export class TieredEvalRunner {
174
174
 
175
175
  /**
176
176
  * Runs a check with the specified timeout.
177
- *
177
+ *
178
178
  * @param check - The check function to run
179
179
  * @param tier - The tier this check belongs to
180
180
  * @returns The result of the check
181
181
  */
182
- private async runCheckWithTimeout(
183
- check: () => Promise<boolean> | boolean,
184
- tier: EvalTier,
185
- ): Promise<CheckResult> {
182
+ private async runCheckWithTimeout(check: () => Promise<boolean> | boolean, tier: EvalTier): Promise<CheckResult> {
186
183
  const timeout = this.getTimeout(tier);
187
184
  const startTime = Date.now();
188
185
 
@@ -228,11 +225,11 @@ export class TieredEvalRunner {
228
225
 
229
226
  /**
230
227
  * Runs all evaluation checks and returns results for each.
231
- *
228
+ *
232
229
  * @param taskId - Identifier for the task being evaluated
233
230
  * @param checks - Array of checks to run, each with a tier assignment
234
231
  * @returns Array of evaluation results for each check
235
- *
232
+ *
236
233
  * @example
237
234
  * ```typescript
238
235
  * const results = await runner.runTieredEval('task-123', [
@@ -240,19 +237,20 @@ export class TieredEvalRunner {
240
237
  * { tier: 2, check: async () => (await grep('output.json', 'pattern')).found },
241
238
  * { tier: 3, check: async () => llmJudge.evaluate(output) }
242
239
  * ]);
243
- *
240
+ *
244
241
  * // Check if all passed
245
242
  * const allPassed = results.every(r => r.passed);
246
243
  * ```
247
244
  */
248
245
  async runTieredEval(
249
246
  taskId: string,
250
- checks: Array<{ tier: EvalTier; check: () => Promise<boolean> | boolean }>,
247
+ checks: Array<{
248
+ tier: EvalTier;
249
+ check: () => Promise<boolean> | boolean;
250
+ }>,
251
251
  ): Promise<EvalResult[]> {
252
252
  // Sort checks by tier if configured (lower tiers first)
253
- const sortedChecks = this.sortByTier
254
- ? [...checks].sort((a, b) => a.tier - b.tier)
255
- : checks;
253
+ const sortedChecks = this.sortByTier ? [...checks].sort((a, b) => a.tier - b.tier) : checks;
256
254
 
257
255
  const results: EvalResult[] = [];
258
256
 
@@ -267,14 +265,14 @@ export class TieredEvalRunner {
267
265
 
268
266
  /**
269
267
  * Runs evaluation checks in fail-fast mode, stopping at the first failure.
270
- *
268
+ *
271
269
  * This is useful for promotion gates where cheaper checks should run first
272
270
  * and any failure should stop the evaluation immediately.
273
- *
271
+ *
274
272
  * @param taskId - Identifier for the task being evaluated
275
273
  * @param checks - Array of checks to run, each with a tier assignment
276
274
  * @returns Array of evaluation results (may be shorter than input if fail-fast triggered)
277
- *
275
+ *
278
276
  * @example
279
277
  * ```typescript
280
278
  * const results = await runner.runTieredEvalFailFast('task-123', [
@@ -282,7 +280,7 @@ export class TieredEvalRunner {
282
280
  * { tier: 2, check: async () => (await grep('output.json', 'pattern')).found },
283
281
  * { tier: 3, check: async () => llmJudge.evaluate(output) }
284
282
  * ]);
285
- *
283
+ *
286
284
  * if (results.length < checks.length) {
287
285
  * console.log(`Failed at tier ${results[results.length - 1].tier}`);
288
286
  * }
@@ -290,12 +288,13 @@ export class TieredEvalRunner {
290
288
  */
291
289
  async runTieredEvalFailFast(
292
290
  taskId: string,
293
- checks: Array<{ tier: EvalTier; check: () => Promise<boolean> | boolean }>,
291
+ checks: Array<{
292
+ tier: EvalTier;
293
+ check: () => Promise<boolean> | boolean;
294
+ }>,
294
295
  ): Promise<EvalResult[]> {
295
296
  // Sort checks by tier if configured (lower tiers first)
296
- const sortedChecks = this.sortByTier
297
- ? [...checks].sort((a, b) => a.tier - b.tier)
298
- : checks;
297
+ const sortedChecks = this.sortByTier ? [...checks].sort((a, b) => a.tier - b.tier) : checks;
299
298
 
300
299
  const results: EvalResult[] = [];
301
300
 
@@ -315,7 +314,7 @@ export class TieredEvalRunner {
315
314
 
316
315
  /**
317
316
  * Runs evaluation checks and returns a structured result object.
318
- *
317
+ *
319
318
  * @param taskId - Identifier for the task being evaluated
320
319
  * @param checks - Array of checks to run, each with a tier assignment
321
320
  * @param failFast - Whether to stop at first failure (default: false)
@@ -323,12 +322,13 @@ export class TieredEvalRunner {
323
322
  */
324
323
  async runEval(
325
324
  taskId: string,
326
- checks: Array<{ tier: EvalTier; check: () => Promise<boolean> | boolean }>,
325
+ checks: Array<{
326
+ tier: EvalTier;
327
+ check: () => Promise<boolean> | boolean;
328
+ }>,
327
329
  failFast = false,
328
330
  ): Promise<TieredEvalResult> {
329
- const sortedChecks = this.sortByTier
330
- ? [...checks].sort((a, b) => a.tier - b.tier)
331
- : checks;
331
+ const sortedChecks = this.sortByTier ? [...checks].sort((a, b) => a.tier - b.tier) : checks;
332
332
 
333
333
  const results: CheckResult[] = [];
334
334
  let totalDurationMs = 0;
@@ -361,9 +361,9 @@ export class TieredEvalRunner {
361
361
 
362
362
  /**
363
363
  * Runs checks in parallel within each tier, but sequentially across tiers.
364
- *
364
+ *
365
365
  * This optimizes execution time when multiple checks exist at the same tier level.
366
- *
366
+ *
367
367
  * @param taskId - Identifier for the task being evaluated
368
368
  * @param checks - Array of checks to run
369
369
  * @param failFast - Whether to stop at first failure (default: false)
@@ -371,11 +371,20 @@ export class TieredEvalRunner {
371
371
  */
372
372
  async runTieredEvalParallel(
373
373
  taskId: string,
374
- checks: Array<{ tier: EvalTier; check: () => Promise<boolean> | boolean }>,
374
+ checks: Array<{
375
+ tier: EvalTier;
376
+ check: () => Promise<boolean> | boolean;
377
+ }>,
375
378
  failFast = false,
376
379
  ): Promise<TieredEvalResult> {
377
380
  // Group checks by tier
378
- const checksByTier = new Map<EvalTier, Array<{ check: () => Promise<boolean> | boolean; originalIndex: number }>>();
381
+ const checksByTier = new Map<
382
+ EvalTier,
383
+ Array<{
384
+ check: () => Promise<boolean> | boolean;
385
+ originalIndex: number;
386
+ }>
387
+ >();
379
388
 
380
389
  checks.forEach((c, originalIndex) => {
381
390
  const existing = checksByTier.get(c.tier) || [];
@@ -431,7 +440,7 @@ export class TieredEvalRunner {
431
440
 
432
441
  /**
433
442
  * Creates a new runner with overridden tier configurations.
434
- *
443
+ *
435
444
  * @param overrides - Tier configurations to override
436
445
  * @returns A new TieredEvalRunner instance
437
446
  */
@@ -447,10 +456,10 @@ export class TieredEvalRunner {
447
456
 
448
457
  /**
449
458
  * Convenience function to create a TieredEvalRunner with default configuration.
450
- *
459
+ *
451
460
  * @param config - Optional configuration overrides
452
461
  * @returns A new TieredEvalRunner instance
453
- *
462
+ *
454
463
  * @example
455
464
  * ```typescript
456
465
  * const runner = createRunner({
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * Types for the Tiered Evaluation System
3
- *
3
+ *
4
4
  * Inspired by agent-eval's judge tiers for hierarchical evaluation.
5
5
  */
6
6
 
7
7
  /**
8
8
  * Evaluation tiers with increasing computational cost.
9
- *
9
+ *
10
10
  * - Tier 1: Deterministic, fast checks (file existence, parse errors)
11
11
  * - Tier 2: Pattern matching, structural checks (grep, regex)
12
12
  * - Tier 3: LLM-based evaluation for natural language checks