pi-crew 0.9.16 → 0.9.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (432) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/README.md +19 -0
  3. package/dist/build-meta.json +21790 -0
  4. package/dist/index.mjs +83070 -0
  5. package/dist/index.mjs.map +7 -0
  6. package/docs/A +358 -0
  7. package/docs/M-A +357 -0
  8. package/docs/REVIEW-FINDINGS-2026-06 +357 -0
  9. package/docs/Y +357 -0
  10. package/docs/a +357 -0
  11. package/docs/aA +358 -0
  12. package/docs/archive/README.md +91 -0
  13. package/docs/patterns/command-agent-skill.md +1 -1
  14. package/docs/skills/REFERENCE.md +0 -17
  15. package/docs//303/242mmaAAA/303/242 +357 -0
  16. package/index.bundle.ts +25 -0
  17. package/index.ts +95 -4
  18. package/package.json +15 -4
  19. package/skills/iterative-audit/SKILL.md +0 -1
  20. package/skills/widget-rendering/SKILL.md +17 -0
  21. package/src/adapters/claude-adapter.ts +1 -3
  22. package/src/adapters/export-util.ts +16 -16
  23. package/src/adapters/index.ts +5 -5
  24. package/src/agents/agent-config.ts +20 -14
  25. package/src/agents/agent-serializer.ts +1 -1
  26. package/src/agents/discover-agents.ts +83 -39
  27. package/src/benchmark/benchmark-runner.ts +51 -51
  28. package/src/benchmark/feedback-loop.ts +1 -1
  29. package/src/config/config.ts +166 -590
  30. package/src/config/defaults.ts +28 -2
  31. package/src/config/drift-detector.ts +11 -14
  32. package/src/config/markers.ts +201 -203
  33. package/src/config/resilient-parser.ts +14 -6
  34. package/src/config/role-tools.ts +3 -3
  35. package/src/config/suggestions.ts +5 -12
  36. package/src/config/types.ts +9 -25
  37. package/src/errors.ts +151 -157
  38. package/src/extension/action-suggestions.ts +54 -9
  39. package/src/extension/async-notifier.ts +43 -13
  40. package/src/extension/autonomous-policy.ts +77 -37
  41. package/src/extension/command-completions.ts +9 -8
  42. package/src/extension/context-status-injection.ts +14 -12
  43. package/src/extension/crew-autocomplete.ts +8 -16
  44. package/src/extension/crew-cleanup.ts +2 -1
  45. package/src/extension/crew-shortcuts.ts +9 -6
  46. package/src/extension/cross-extension-rpc.ts +136 -42
  47. package/src/extension/help.ts +1 -1
  48. package/src/extension/import-index.ts +10 -5
  49. package/src/extension/knowledge-injection.ts +88 -15
  50. package/src/extension/management.ts +89 -349
  51. package/src/extension/message-renderers.ts +3 -4
  52. package/src/extension/notification-router.ts +22 -5
  53. package/src/extension/notification-sink.ts +6 -3
  54. package/src/extension/pi-api.ts +17 -8
  55. package/src/extension/plan-orchestrate.ts +8 -27
  56. package/src/extension/project-init.ts +21 -6
  57. package/src/extension/register.ts +329 -975
  58. package/src/extension/registration/artifact-cleanup.ts +9 -4
  59. package/src/extension/registration/command-utils.ts +5 -1
  60. package/src/extension/registration/commands.ts +806 -314
  61. package/src/extension/registration/compaction-guard.ts +15 -15
  62. package/src/extension/registration/lifecycle.ts +259 -0
  63. package/src/extension/registration/observability.ts +293 -0
  64. package/src/extension/registration/subagent-helpers.ts +29 -7
  65. package/src/extension/registration/subagent-tools.ts +253 -44
  66. package/src/extension/registration/team-tool.ts +19 -84
  67. package/src/extension/registration/ui.ts +168 -0
  68. package/src/extension/registration/viewers.ts +64 -24
  69. package/src/extension/result-watcher.ts +18 -7
  70. package/src/extension/run-bundle-schema.ts +21 -6
  71. package/src/extension/run-export.ts +15 -6
  72. package/src/extension/run-import.ts +64 -29
  73. package/src/extension/run-index.ts +28 -9
  74. package/src/extension/run-maintenance.ts +32 -12
  75. package/src/extension/session-summary.ts +1 -1
  76. package/src/extension/team-manager-command.ts +64 -7
  77. package/src/extension/team-onboard.ts +151 -150
  78. package/src/extension/team-recommendation.ts +121 -21
  79. package/src/extension/team-tool/anchor.ts +31 -64
  80. package/src/extension/team-tool/api.ts +929 -141
  81. package/src/extension/team-tool/auto-summarize.ts +14 -26
  82. package/src/extension/team-tool/cache-control.ts +1 -5
  83. package/src/extension/team-tool/cancel.ts +138 -38
  84. package/src/extension/team-tool/chain-dispatch.ts +5 -13
  85. package/src/extension/team-tool/chain-executor.ts +29 -51
  86. package/src/extension/team-tool/config-patch.ts +1 -1
  87. package/src/extension/team-tool/context.ts +40 -20
  88. package/src/extension/team-tool/destructive-gate.ts +10 -5
  89. package/src/extension/team-tool/doctor.ts +170 -51
  90. package/src/extension/team-tool/explain.ts +228 -214
  91. package/src/extension/team-tool/failure-patterns.ts +3 -9
  92. package/src/extension/team-tool/goal-wrap.ts +71 -29
  93. package/src/extension/team-tool/goal.ts +185 -35
  94. package/src/extension/team-tool/handle-schedule.ts +34 -15
  95. package/src/extension/team-tool/handle-settings.ts +94 -56
  96. package/src/extension/team-tool/health-monitor.ts +27 -108
  97. package/src/extension/team-tool/inspect.ts +42 -9
  98. package/src/extension/team-tool/intent-policy.ts +4 -1
  99. package/src/extension/team-tool/lifecycle-actions.ts +244 -48
  100. package/src/extension/team-tool/orchestrate.ts +7 -18
  101. package/src/extension/team-tool/parallel-dispatch.ts +51 -29
  102. package/src/extension/team-tool/plan.ts +29 -5
  103. package/src/extension/team-tool/respond.ts +49 -16
  104. package/src/extension/team-tool/run-not-found.ts +3 -8
  105. package/src/extension/team-tool/run.ts +80 -317
  106. package/src/extension/team-tool/status.ts +135 -43
  107. package/src/extension/team-tool/workflow-manage.ts +92 -25
  108. package/src/extension/team-tool-types.ts +8 -1
  109. package/src/extension/team-tool.ts +142 -551
  110. package/src/extension/validate-resources.ts +39 -8
  111. package/src/hooks/registry.ts +66 -17
  112. package/src/hooks/types.ts +1 -1
  113. package/src/i18n.ts +25 -11
  114. package/src/observability/correlation.ts +17 -3
  115. package/src/observability/event-bus.ts +51 -56
  116. package/src/observability/event-to-metric.ts +117 -15
  117. package/src/observability/exporters/otlp-exporter.ts +56 -17
  118. package/src/observability/exporters/prometheus-exporter.ts +1 -1
  119. package/src/observability/metric-registry.ts +16 -4
  120. package/src/observability/metric-retention.ts +8 -2
  121. package/src/observability/metric-sink.ts +11 -3
  122. package/src/observability/metrics-primitives.ts +42 -9
  123. package/src/plugins/plugin-define.ts +2 -2
  124. package/src/plugins/plugin-registry.ts +25 -25
  125. package/src/plugins/plugins/index.ts +1 -1
  126. package/src/plugins/plugins/nextjs.ts +16 -16
  127. package/src/plugins/plugins/vite.ts +7 -11
  128. package/src/plugins/plugins/vitest.ts +6 -11
  129. package/src/runtime/adaptive-plan.ts +225 -40
  130. package/src/runtime/agent-control.ts +58 -15
  131. package/src/runtime/agent-memory.ts +15 -9
  132. package/src/runtime/agent-observability.ts +10 -2
  133. package/src/runtime/anchor-manager.ts +27 -25
  134. package/src/runtime/async-marker.ts +7 -1
  135. package/src/runtime/async-runner.ts +27 -23
  136. package/src/runtime/auto-summarize.ts +7 -13
  137. package/src/runtime/background-runner.ts +189 -251
  138. package/src/runtime/batch-barrier.ts +18 -16
  139. package/src/runtime/cancellation-token.ts +16 -6
  140. package/src/runtime/cancellation.ts +46 -8
  141. package/src/runtime/capability-inventory.ts +6 -4
  142. package/src/runtime/chain-parser.ts +44 -11
  143. package/src/runtime/chain-runner.ts +63 -69
  144. package/src/runtime/checkpoint.ts +12 -56
  145. package/src/runtime/child-pi.ts +343 -78
  146. package/src/runtime/coalesce-tasks.ts +268 -0
  147. package/src/runtime/code-summary.ts +71 -26
  148. package/src/runtime/compact-stages/index.ts +15 -5
  149. package/src/runtime/compact-stages/tail-capture-stage.ts +7 -2
  150. package/src/runtime/compact-stages/truncation-stage.ts +4 -1
  151. package/src/runtime/compaction-summary.ts +17 -10
  152. package/src/runtime/completion-guard.ts +33 -16
  153. package/src/runtime/crash-classification.ts +28 -7
  154. package/src/runtime/crash-recovery.ts +177 -37
  155. package/src/runtime/crew-agent-records.ts +145 -47
  156. package/src/runtime/crew-hooks.ts +9 -24
  157. package/src/runtime/cross-extension-rpc.ts +25 -23
  158. package/src/runtime/custom-tools/irc-tool.ts +43 -15
  159. package/src/runtime/custom-tools/submit-result-tool.ts +16 -5
  160. package/src/runtime/delivery-coordinator.ts +34 -7
  161. package/src/runtime/delta-conflict.ts +9 -21
  162. package/src/runtime/deterministic-ast.ts +1 -1
  163. package/src/runtime/diagnostic-export.ts +53 -20
  164. package/src/runtime/direct-run.ts +12 -2
  165. package/src/runtime/dwf-state-store.ts +1 -1
  166. package/src/runtime/dynamic-workflow-context.ts +186 -58
  167. package/src/runtime/dynamic-workflow-runner.ts +42 -20
  168. package/src/runtime/effectiveness.ts +16 -8
  169. package/src/runtime/errors/crew-errors.ts +7 -11
  170. package/src/runtime/event-stream-bridge.ts +9 -3
  171. package/src/runtime/foreground-control.ts +54 -14
  172. package/src/runtime/foreground-watchdog.ts +9 -6
  173. package/src/runtime/goal-achievement.ts +27 -10
  174. package/src/runtime/goal-evaluator.ts +54 -19
  175. package/src/runtime/goal-loop-runner.ts +280 -99
  176. package/src/runtime/goal-state-store.ts +27 -17
  177. package/src/runtime/green-contract.ts +11 -2
  178. package/src/runtime/group-join.ts +64 -31
  179. package/src/runtime/handoff-manager.ts +37 -42
  180. package/src/runtime/heartbeat-gradient.ts +10 -2
  181. package/src/runtime/heartbeat-watcher.ts +32 -6
  182. package/src/runtime/hidden-handoff.ts +12 -30
  183. package/src/runtime/important-line-classifier.ts +12 -2
  184. package/src/runtime/iteration-hooks.ts +25 -15
  185. package/src/runtime/live-agent-control.ts +55 -7
  186. package/src/runtime/live-agent-manager.ts +130 -27
  187. package/src/runtime/live-control-realtime.ts +23 -3
  188. package/src/runtime/live-irc.ts +4 -1
  189. package/src/runtime/live-session-health.ts +12 -4
  190. package/src/runtime/live-session-runtime.ts +379 -117
  191. package/src/runtime/manifest-cache.ts +28 -12
  192. package/src/runtime/mcp-proxy.ts +8 -16
  193. package/src/runtime/metric-parser.ts +1 -5
  194. package/src/runtime/model-fallback.ts +55 -18
  195. package/src/runtime/model-resolver.ts +2 -6
  196. package/src/runtime/model-scope.ts +19 -3
  197. package/src/runtime/notebook-helpers.ts +60 -62
  198. package/src/runtime/orphan-worker-registry.ts +37 -26
  199. package/src/runtime/output-validator.ts +18 -3
  200. package/src/runtime/overflow-recovery.ts +5 -4
  201. package/src/runtime/parallel-research.ts +29 -5
  202. package/src/runtime/parallel-utils.ts +9 -11
  203. package/src/runtime/path-overlap.ts +150 -0
  204. package/src/runtime/peer-dep.ts +12 -17
  205. package/src/runtime/per-write-validator.ts +1 -3
  206. package/src/runtime/phase-tracker.ts +342 -330
  207. package/src/runtime/pi-args.ts +26 -8
  208. package/src/runtime/pi-json-output.ts +1 -1
  209. package/src/runtime/pi-spawn.ts +30 -19
  210. package/src/runtime/pipeline-runner.ts +56 -55
  211. package/src/runtime/plan-templates.ts +5 -6
  212. package/src/runtime/policy-engine.ts +43 -7
  213. package/src/runtime/post-checks.ts +12 -4
  214. package/src/runtime/post-exit-stdio-guard.ts +2 -2
  215. package/src/runtime/process-lifecycle.ts +20 -10
  216. package/src/runtime/process-status.ts +16 -5
  217. package/src/runtime/progress-event-coalescer.ts +2 -1
  218. package/src/runtime/progress-tracker.ts +103 -103
  219. package/src/runtime/prose-compressor.ts +9 -11
  220. package/src/runtime/recovery-recipes.ts +118 -24
  221. package/src/runtime/replace.ts +25 -10
  222. package/src/runtime/resilient-edit.ts +10 -25
  223. package/src/runtime/result-extractor.ts +1 -2
  224. package/src/runtime/retry-executor.ts +20 -4
  225. package/src/runtime/retry-runner.ts +26 -50
  226. package/src/runtime/role-permission.ts +6 -1
  227. package/src/runtime/run-coalesced-task-group.ts +256 -0
  228. package/src/runtime/run-drift.ts +14 -15
  229. package/src/runtime/run-tracker.ts +6 -28
  230. package/src/runtime/runtime-policy.ts +1 -6
  231. package/src/runtime/runtime-resolver.ts +80 -15
  232. package/src/runtime/scheduler.ts +47 -18
  233. package/src/runtime/semaphore.ts +5 -7
  234. package/src/runtime/sensitive-paths.ts +2 -1
  235. package/src/runtime/session-usage.ts +1 -1
  236. package/src/runtime/settings-store.ts +16 -12
  237. package/src/runtime/sidechain-output.ts +6 -2
  238. package/src/runtime/single-agent-compose.ts +1 -4
  239. package/src/runtime/skill-effectiveness.ts +29 -97
  240. package/src/runtime/skill-instructions.ts +40 -83
  241. package/src/runtime/stale-reconciler.ts +73 -197
  242. package/src/runtime/stream-preview.ts +1 -1
  243. package/src/runtime/streaming-output.ts +1 -1
  244. package/src/runtime/subagent-manager.ts +44 -169
  245. package/src/runtime/subprocess-tool-registry.ts +4 -1
  246. package/src/runtime/supervisor-contact.ts +10 -5
  247. package/src/runtime/task-display.ts +19 -5
  248. package/src/runtime/task-graph-scheduler.ts +95 -21
  249. package/src/runtime/task-graph.ts +5 -11
  250. package/src/runtime/task-health.ts +54 -47
  251. package/src/runtime/task-id.ts +11 -18
  252. package/src/runtime/task-output-context.ts +265 -81
  253. package/src/runtime/task-packet.ts +12 -20
  254. package/src/runtime/task-quality.ts +6 -14
  255. package/src/runtime/task-runner/context-retrieval.ts +4 -13
  256. package/src/runtime/task-runner/live-executor.ts +114 -36
  257. package/src/runtime/task-runner/output-splitter.ts +152 -0
  258. package/src/runtime/task-runner/progress.ts +50 -12
  259. package/src/runtime/task-runner/prompt-builder.ts +31 -7
  260. package/src/runtime/task-runner/prompt-pipeline.ts +31 -7
  261. package/src/runtime/task-runner/result-utils.ts +3 -1
  262. package/src/runtime/task-runner/retrieval-orchestrator.ts +310 -0
  263. package/src/runtime/task-runner/run-projection.ts +27 -8
  264. package/src/runtime/task-runner/state-helpers.ts +29 -8
  265. package/src/runtime/task-runner/tail-read.ts +2 -6
  266. package/src/runtime/task-runner.ts +180 -326
  267. package/src/runtime/team-runner-artifacts.ts +13 -0
  268. package/src/runtime/team-runner.ts +456 -974
  269. package/src/runtime/tool-output-pruner.ts +6 -9
  270. package/src/runtime/tool-progress.ts +11 -21
  271. package/src/runtime/verification-gates.ts +33 -24
  272. package/src/runtime/verification-integrity.ts +1 -4
  273. package/src/runtime/verification-worktree.ts +62 -12
  274. package/src/runtime/worker-heartbeat.ts +5 -1
  275. package/src/runtime/worker-startup.ts +29 -5
  276. package/src/runtime/workflow-state.ts +17 -9
  277. package/src/runtime/workspace-lock.ts +30 -35
  278. package/src/runtime/workspace-tree.ts +20 -32
  279. package/src/runtime/yield-handler.ts +43 -9
  280. package/src/runtime/zombie-scanner.ts +5 -4
  281. package/src/schema/config-schema.ts +266 -172
  282. package/src/schema/team-tool-schema.ts +29 -74
  283. package/src/schema/validation-types.ts +25 -17
  284. package/src/skills/discover-skills.ts +35 -10
  285. package/src/skills/skill-templates.ts +109 -27
  286. package/src/skills/validate.ts +26 -8
  287. package/src/state/active-run-registry.ts +87 -28
  288. package/src/state/artifact-store.ts +9 -5
  289. package/src/state/atomic-write-v2.ts +85 -63
  290. package/src/state/atomic-write.ts +105 -26
  291. package/src/state/blob-store.ts +47 -20
  292. package/src/state/contracts.ts +20 -5
  293. package/src/state/crew-init.ts +5 -22
  294. package/src/state/decision-ledger.ts +19 -73
  295. package/src/state/event-log-rotation.ts +41 -15
  296. package/src/state/event-log.ts +168 -53
  297. package/src/state/event-reconstructor.ts +11 -1
  298. package/src/state/gitignore-manager.ts +2 -8
  299. package/src/state/health-store.ts +57 -57
  300. package/src/state/hook-instinct-bridge.ts +1 -1
  301. package/src/state/hook-integrations.ts +1 -1
  302. package/src/state/instinct-store.ts +17 -5
  303. package/src/state/jsonl-writer.ts +1 -1
  304. package/src/state/locks.ts +23 -9
  305. package/src/state/mailbox.ts +151 -28
  306. package/src/state/observation-store.ts +20 -14
  307. package/src/state/run-cache.ts +142 -135
  308. package/src/state/run-graph.ts +6 -15
  309. package/src/state/run-metrics.ts +5 -18
  310. package/src/state/schedule.ts +15 -9
  311. package/src/state/state-store.ts +129 -45
  312. package/src/state/task-claims.ts +12 -2
  313. package/src/state/tiered-eval.ts +52 -43
  314. package/src/state/types-eval.ts +2 -2
  315. package/src/state/types.ts +24 -20
  316. package/src/state/usage.ts +20 -4
  317. package/src/state/worker-atomic-writer.ts +6 -3
  318. package/src/subagents/index.ts +2 -2
  319. package/src/teams/discover-teams.ts +21 -6
  320. package/src/tools/safe-bash-extension.ts +5 -6
  321. package/src/tools/safe-bash.ts +10 -11
  322. package/src/types/new-api-types.ts +6 -10
  323. package/src/ui/agent-management-overlay.ts +52 -40
  324. package/src/ui/card-colors.ts +13 -4
  325. package/src/ui/crew-footer.ts +8 -7
  326. package/src/ui/crew-select-list.ts +1 -1
  327. package/src/ui/dashboard-panes/agents-pane.ts +41 -25
  328. package/src/ui/dashboard-panes/cancellation-pane.ts +1 -1
  329. package/src/ui/dashboard-panes/capability-pane.ts +32 -15
  330. package/src/ui/dashboard-panes/health-pane.ts +2 -1
  331. package/src/ui/dashboard-panes/metrics-pane.ts +4 -1
  332. package/src/ui/dashboard-panes/progress-pane.ts +12 -9
  333. package/src/ui/heartbeat-aggregator.ts +15 -4
  334. package/src/ui/keybinding-map.ts +40 -7
  335. package/src/ui/live-conversation-overlay.ts +36 -20
  336. package/src/ui/live-duration.ts +1 -4
  337. package/src/ui/live-run-sidebar.ts +88 -25
  338. package/src/ui/loaders.ts +2 -8
  339. package/src/ui/mascot.ts +20 -36
  340. package/src/ui/overlays/agent-picker-overlay.ts +11 -3
  341. package/src/ui/overlays/confirm-overlay.ts +4 -2
  342. package/src/ui/overlays/help-overlay.ts +25 -14
  343. package/src/ui/overlays/mailbox-compose-overlay.ts +48 -11
  344. package/src/ui/overlays/mailbox-compose-preview.ts +20 -5
  345. package/src/ui/overlays/mailbox-detail-overlay.ts +27 -6
  346. package/src/ui/pi-ui-compat.ts +7 -7
  347. package/src/ui/powerbar-publisher.ts +120 -42
  348. package/src/ui/render-diff.ts +10 -3
  349. package/src/ui/render-scheduler.ts +12 -4
  350. package/src/ui/run-action-dispatcher.ts +81 -18
  351. package/src/ui/run-dashboard.ts +172 -76
  352. package/src/ui/run-event-bus.ts +59 -37
  353. package/src/ui/run-snapshot-cache.ts +276 -86
  354. package/src/ui/settings-overlay.ts +361 -74
  355. package/src/ui/status-colors.ts +12 -1
  356. package/src/ui/syntax-highlight.ts +1 -1
  357. package/src/ui/theme-adapter.ts +16 -14
  358. package/src/ui/theme-discovery.ts +13 -2
  359. package/src/ui/tool-progress-formatter.ts +7 -7
  360. package/src/ui/tool-render.ts +128 -56
  361. package/src/ui/tool-renderers/brief-mode.ts +45 -27
  362. package/src/ui/tool-renderers/index.ts +109 -43
  363. package/src/ui/transcript-cache.ts +32 -6
  364. package/src/ui/transcript-entries.ts +25 -23
  365. package/src/ui/transcript-viewer.ts +78 -29
  366. package/src/ui/widget/index.ts +99 -40
  367. package/src/ui/widget/widget-formatters.ts +13 -6
  368. package/src/ui/widget/widget-model.ts +19 -8
  369. package/src/ui/widget/widget-renderer.ts +23 -13
  370. package/src/ui/widget/widget-types.ts +1 -1
  371. package/src/utils/bm25-search.ts +199 -199
  372. package/src/utils/conflict-detect.ts +22 -21
  373. package/src/utils/env-filter.ts +14 -7
  374. package/src/utils/file-coalescer.ts +5 -1
  375. package/src/utils/fingerprint.ts +3 -6
  376. package/src/utils/frontmatter.ts +3 -1
  377. package/src/utils/fs-watch.ts +2 -6
  378. package/src/utils/gh-protocol.ts +119 -44
  379. package/src/utils/git.ts +13 -15
  380. package/src/utils/guards.ts +2 -5
  381. package/src/utils/ids.ts +9 -2
  382. package/src/utils/incremental-reader.ts +14 -3
  383. package/src/utils/internal-error.ts +2 -1
  384. package/src/utils/names.ts +12 -3
  385. package/src/utils/paths.ts +49 -5
  386. package/src/utils/project-detector.ts +2 -2
  387. package/src/utils/redaction.ts +29 -19
  388. package/src/utils/resolve-shell.ts +9 -7
  389. package/src/utils/run-watcher-registry.ts +19 -31
  390. package/src/utils/safe-paths.ts +45 -24
  391. package/src/utils/scan-cache.ts +9 -2
  392. package/src/utils/session-utils.ts +2 -4
  393. package/src/utils/sleep.ts +12 -5
  394. package/src/utils/sse-parser.ts +5 -17
  395. package/src/utils/visual.ts +52 -32
  396. package/src/workflows/discover-workflows.ts +41 -109
  397. package/src/workflows/intermediate-store.ts +5 -21
  398. package/src/workflows/preflight-validator.ts +6 -33
  399. package/src/workflows/topology-analyzer.ts +5 -21
  400. package/src/workflows/workflow-config.ts +7 -6
  401. package/src/worktree/branch-freshness.ts +66 -8
  402. package/src/worktree/cleanup.ts +130 -20
  403. package/src/worktree/worktree-manager.ts +212 -69
  404. package/skills/artifact-analysis-loop/SKILL.md +0 -303
  405. package/skills/detection-pipeline-design/SKILL.md +0 -286
  406. package/skills/hunting-investigation-loop/SKILL.md +0 -402
  407. package/skills/incident-playbook-construction/SKILL.md +0 -384
  408. package/skills/security-review/SKILL.md +0 -561
  409. package/skills/threat-hypothesis-framework/SKILL.md +0 -176
  410. package/skills/ui-render-performance/SKILL.md +0 -58
  411. /package/docs/{followup-review-round3-2026-05-12.md → archive/followup-review-round3-2026-05-12.md} +0 -0
  412. /package/docs/{followup-review-round4-2026-05-13.md → archive/followup-review-round4-2026-05-13.md} +0 -0
  413. /package/docs/{pi-crew-bugs.md → archive/pi-crew-bugs.md} +0 -0
  414. /package/docs/{pi-crew-test-final.md → archive/pi-crew-test-final.md} +0 -0
  415. /package/docs/{pi-crew-test-results.md → archive/pi-crew-test-results.md} +0 -0
  416. /package/docs/{pi-crew-test-round2.md → archive/pi-crew-test-round2.md} +0 -0
  417. /package/docs/{pi-crew-test-round4.md → archive/pi-crew-test-round4.md} +0 -0
  418. /package/docs/{pi-crew-test-round5.md → archive/pi-crew-test-round5.md} +0 -0
  419. /package/docs/{pi-crew-test-round6.md → archive/pi-crew-test-round6.md} +0 -0
  420. /package/docs/{pi-crew-v0.5.10-audit-fix-plan.md → archive/pi-crew-v0.5.10-audit-fix-plan.md} +0 -0
  421. /package/docs/{pi-crew-v0.5.11-audit-fix-plan.md → archive/pi-crew-v0.5.11-audit-fix-plan.md} +0 -0
  422. /package/docs/{pi-crew-v0.5.12-audit-fix-plan.md → archive/pi-crew-v0.5.12-audit-fix-plan.md} +0 -0
  423. /package/docs/{pi-crew-v0.5.13-audit-fix-plan.md → archive/pi-crew-v0.5.13-audit-fix-plan.md} +0 -0
  424. /package/docs/{pi-crew-v0.5.14-audit-fix-plan.md → archive/pi-crew-v0.5.14-audit-fix-plan.md} +0 -0
  425. /package/docs/{pi-crew-v0.5.16-audit-fix-plan.md → archive/pi-crew-v0.5.16-audit-fix-plan.md} +0 -0
  426. /package/docs/{pi-crew-v0.5.17-audit-fix-plan.md → archive/pi-crew-v0.5.17-audit-fix-plan.md} +0 -0
  427. /package/docs/{pi-crew-v0.5.5-audit-fix-plan.md → archive/pi-crew-v0.5.5-audit-fix-plan.md} +0 -0
  428. /package/docs/{pi-crew-v0.5.9-audit-fix-plan.md → archive/pi-crew-v0.5.9-audit-fix-plan.md} +0 -0
  429. /package/docs/{pi-mono-opportunities.md → archive/pi-mono-opportunities.md} +0 -0
  430. /package/docs/{pi-mono-review.md → archive/pi-mono-review.md} +0 -0
  431. /package/docs/{pi-subagent4-comparison.md → archive/pi-subagent4-comparison.md} +0 -0
  432. /package/docs/{pi-subagents3-deep-analysis.md → archive/pi-subagents3-deep-analysis.md} +0 -0
@@ -1,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
  });
@@ -401,14 +428,22 @@ export function saveRunTasks(manifest: TeamRunManifest, tasks: TeamTaskState[]):
401
428
  function saveRunTasksCoalesced(manifest: TeamRunManifest, tasks: TeamTaskState[]): void {
402
429
  // FIX: Invalidate cache BEFORE atomic write to prevent stale cache serving.
403
430
  invalidateRunCache(manifest.stateRoot);
404
- try { fs.statSync(manifest.stateRoot); } catch { return; }
431
+ try {
432
+ fs.statSync(manifest.stateRoot);
433
+ } catch {
434
+ return;
435
+ }
405
436
  atomicWriteJsonCoalesced(manifest.tasksPath, tasks);
406
437
  }
407
438
 
408
439
  export async function saveRunTasksAsync(manifest: TeamRunManifest, tasks: TeamTaskState[]): Promise<void> {
409
440
  // FIX: Invalidate cache BEFORE atomic write to prevent stale cache serving.
410
441
  invalidateRunCache(manifest.stateRoot);
411
- try { fs.statSync(manifest.stateRoot); } catch { return; }
442
+ try {
443
+ fs.statSync(manifest.stateRoot);
444
+ } catch {
445
+ return;
446
+ }
412
447
  await atomicWriteJsonAsync(manifest.tasksPath, tasks);
413
448
  }
414
449
 
@@ -490,18 +525,32 @@ export interface UpdateRunStatusOptions {
490
525
  metadata?: Parameters<typeof appendEvent>[1]["metadata"];
491
526
  }
492
527
 
493
- export function updateRunStatus(manifest: TeamRunManifest, status: TeamRunManifest["status"], summary?: string, options: UpdateRunStatusOptions = {}): TeamRunManifest {
528
+ export function updateRunStatus(
529
+ manifest: TeamRunManifest,
530
+ status: TeamRunManifest["status"],
531
+ summary?: string,
532
+ options: UpdateRunStatusOptions = {},
533
+ ): TeamRunManifest {
494
534
  if (!canTransitionRunStatus(manifest.status, status)) {
495
535
  throw errors.invalidStatusTransition(manifest.status, status);
496
536
  }
497
- const updated: TeamRunManifest = { ...manifest, status, updatedAt: new Date().toISOString(), summary: summary ?? manifest.summary };
537
+ const updated: TeamRunManifest = {
538
+ ...manifest,
539
+ status,
540
+ updatedAt: new Date().toISOString(),
541
+ summary: summary ?? manifest.summary,
542
+ };
498
543
  saveRunManifest(updated);
499
544
  // Unregister from active-run-index when run reaches a terminal status.
500
545
  // Without this, stale entries accumulate (e.g. integration tests in /tmp) and
501
546
  // Pi UI shows ghost "queued" runs that are actually completed/failed/cancelled.
502
547
  // Note: "blocked" is excluded because blocked runs can be unblocked later.
503
548
  if (status === "completed" || status === "failed" || status === "cancelled") {
504
- try { unregisterActiveRun(updated.runId); } catch { /* non-critical */ }
549
+ try {
550
+ unregisterActiveRun(updated.runId);
551
+ } catch {
552
+ /* non-critical */
553
+ }
505
554
  }
506
555
  appendEvent(updated.eventsPath, {
507
556
  type: `run.${status}`,
@@ -510,8 +559,16 @@ export function updateRunStatus(manifest: TeamRunManifest, status: TeamRunManife
510
559
  ...(options.data ? { data: options.data } : {}),
511
560
  metadata: {
512
561
  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" },
562
+ sessionIdentity: {
563
+ title: updated.team,
564
+ workspace: updated.cwd,
565
+ purpose: updated.goal,
566
+ },
567
+ ownership: {
568
+ owner: updated.team,
569
+ workflowScope: updated.workflow ?? "manual",
570
+ watcherAction: "act",
571
+ },
515
572
  confidence: "high",
516
573
  ...options.metadata,
517
574
  },
@@ -574,12 +631,12 @@ export function loadRunManifestById(cwd: string, runId: string): { manifest: Tea
574
631
  }
575
632
  const tasksMtimeMs = tasksStat?.mtimeMs ?? 0;
576
633
  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
634
+ cached &&
635
+ cached.manifestMtimeMs === manifestStat.mtimeMs &&
636
+ cached.manifestSize === manifestStat.size &&
637
+ cached.tasksMtimeMs === tasksMtimeMs &&
638
+ cached.tasksSize === (tasksStat?.size ?? 0) &&
639
+ cached.generation === manifestCacheGeneration
583
640
  ) {
584
641
  // TTL eviction: expire stale entries even if mtime matches
585
642
  // FIX: Also evict entries where cachedAt is undefined — such entries are
@@ -592,7 +649,7 @@ export function loadRunManifestById(cwd: string, runId: string): { manifest: Tea
592
649
  } else if (!validateRunManifestPaths(cwd, runId, cached.manifest, stateRoot, tasksPath)) {
593
650
  manifestCache.delete(stateRoot);
594
651
  return undefined;
595
- } else if (!fs.existsSync(tasksPath)) {
652
+ } else if (!fs.existsSync(tasksPath)) {
596
653
  // Tasks file was deleted after cache was populated — this is a cache miss,
597
654
  // not a manifest inconsistency. The cache check passes because
598
655
  // tasksMtimeMs=0 and tasksSize=0 match a cache entry written when tasks.json
@@ -621,8 +678,11 @@ export function loadRunManifestById(cwd: string, runId: string): { manifest: Tea
621
678
  const freshTasksStat = fs.existsSync(tasksPath) ? fs.statSync(tasksPath) : undefined;
622
679
  tasks = readJsonFile<TeamTaskState[]>(tasksPath) ?? [];
623
680
  // 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))) {
681
+ if (
682
+ freshStat.mtimeMs === manifestStat.mtimeMs &&
683
+ freshStat.size === manifestStat.size &&
684
+ (!freshTasksStat || (freshTasksStat.mtimeMs === tasksStat?.mtimeMs && freshTasksStat.size === tasksStat?.size))
685
+ ) {
626
686
  break;
627
687
  }
628
688
  attempts += 1;
@@ -637,7 +697,9 @@ export function loadRunManifestById(cwd: string, runId: string): { manifest: Tea
637
697
  // Round 19: downgrade to debug — retry-loop instability is expected under
638
698
  // concurrent writes (live team runs constantly append to tasks.json).
639
699
  // 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`);
700
+ console.debug(
701
+ `[state-store] loadRunManifestById: retry loop detected instability for run ${runId} after ${attempts} attempt(s) — best-effort only, use withRunLock() for strict consistency`,
702
+ );
641
703
  }
642
704
  // NOTE: manifest mtime may legitimately be >= tasks mtime because
643
705
  // saveManifestAndTasksAtomicSync writes manifest before tasks. However,
@@ -659,7 +721,10 @@ export function loadRunManifestById(cwd: string, runId: string): { manifest: Tea
659
721
  return { manifest, tasks: tasks ?? [] };
660
722
  }
661
723
 
662
- export async function loadRunManifestByIdAsync(cwd: string, runId: string): Promise<{ manifest: TeamRunManifest; tasks: TeamTaskState[] } | undefined> {
724
+ export async function loadRunManifestByIdAsync(
725
+ cwd: string,
726
+ runId: string,
727
+ ): Promise<{ manifest: TeamRunManifest; tasks: TeamTaskState[] } | undefined> {
663
728
  const stateRoot = resolveRunStateRoot(cwd, runId);
664
729
  if (!stateRoot) return undefined;
665
730
  const manifestPath = path.join(stateRoot, "manifest.json");
@@ -681,7 +746,14 @@ export async function loadRunManifestByIdAsync(cwd: string, runId: string): Prom
681
746
  tasksStat = undefined;
682
747
  }
683
748
  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) {
749
+ if (
750
+ cached &&
751
+ cached.manifestMtimeMs === manifestStat.mtimeMs &&
752
+ cached.manifestSize === manifestStat.size &&
753
+ cached.tasksMtimeMs === tasksMtimeMs &&
754
+ cached.tasksSize === (tasksStat?.size ?? 0) &&
755
+ cached.generation === manifestCacheGeneration
756
+ ) {
685
757
  // TTL eviction: expire stale entries even if mtime matches
686
758
  // FIX: Also evict entries where cachedAt is undefined — such entries are
687
759
  // effectively immortal otherwise (the `cached.cachedAt &&` check would skip
@@ -693,10 +765,10 @@ export async function loadRunManifestByIdAsync(cwd: string, runId: string): Prom
693
765
  } else if (!validateRunManifestPaths(cwd, runId, cached.manifest, stateRoot, tasksPath)) {
694
766
  manifestCache.delete(stateRoot);
695
767
  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;
768
+ } else if (!fs.existsSync(tasksPath)) {
769
+ // Tasks file was deleted after cache was populated — do not serve stale cache.
770
+ manifestCache.delete(stateRoot);
771
+ return undefined;
700
772
  } else {
701
773
  return { manifest: cached.manifest, tasks: cached.tasks ?? [] };
702
774
  }
@@ -714,8 +786,11 @@ export async function loadRunManifestByIdAsync(cwd: string, runId: string): Prom
714
786
  const freshTasksStat = await fs.promises.stat(tasksPath).catch(() => undefined);
715
787
  tasks = (await readJsonFileAsync<TeamTaskState[]>(tasksPath)) ?? [];
716
788
  // 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))) {
789
+ if (
790
+ freshStat.mtimeMs === manifestStat.mtimeMs &&
791
+ freshStat.size === manifestStat.size &&
792
+ (!freshTasksStat || (freshTasksStat.mtimeMs === tasksStat?.mtimeMs && freshTasksStat.size === tasksStat?.size))
793
+ ) {
719
794
  break;
720
795
  }
721
796
  attempts += 1;
@@ -730,7 +805,9 @@ export async function loadRunManifestByIdAsync(cwd: string, runId: string): Prom
730
805
  // Round 19: downgrade to debug — retry-loop instability is expected under
731
806
  // concurrent writes (live team runs constantly append to tasks.json).
732
807
  // 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`);
808
+ console.debug(
809
+ `[state-store] loadRunManifestByIdAsync: retry loop detected instability for run ${runId} after ${attempts} attempt(s) — best-effort only, use withRunLock() for strict consistency`,
810
+ );
734
811
  }
735
812
  // NOTE: manifest mtime may legitimately be >= tasks mtime because
736
813
  // saveManifestAndTasksAtomicSync writes manifest before tasks. However,
@@ -742,6 +819,13 @@ export async function loadRunManifestByIdAsync(cwd: string, runId: string): Prom
742
819
  // It does not indicate corruption on its own.
743
820
 
744
821
  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 });
822
+ setManifestCache(stateRoot, {
823
+ manifest,
824
+ tasks: tasks ?? [],
825
+ manifestMtimeMs: manifestStat.mtimeMs,
826
+ manifestSize: manifestStat.size,
827
+ tasksMtimeMs,
828
+ tasksSize: tasksStat?.size ?? 0,
829
+ });
746
830
  return { manifest, tasks: tasks ?? [] };
747
831
  }
@@ -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