pi-crew 0.9.15 → 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 +145 -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 +193 -40
  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 +86 -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,26 +1,26 @@
1
+ import * as crypto from "node:crypto";
1
2
  import * as fs from "node:fs";
2
3
  import * as path from "node:path";
3
- import * as crypto from "node:crypto";
4
4
  import { projectCrewRoot } from "../utils/paths.ts";
5
- import type { TeamTaskState } from "./types.ts";
6
5
  import { atomicWriteFile } from "./atomic-write.ts";
7
6
  import { withFileLockSync } from "./locks.ts";
7
+ import type { TeamTaskState } from "./types.ts";
8
8
 
9
9
  const DEFAULT_CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour
10
10
 
11
11
  export interface CacheEntry {
12
- key: string;
13
- runId: string;
14
- status: string;
15
- tasks: TeamTaskState[];
16
- cachedAt: number;
17
- expiresAt: number;
18
- goal: string;
19
- team: string;
12
+ key: string;
13
+ runId: string;
14
+ status: string;
15
+ tasks: TeamTaskState[];
16
+ cachedAt: number;
17
+ expiresAt: number;
18
+ goal: string;
19
+ team: string;
20
20
  }
21
21
 
22
22
  interface CacheIndex {
23
- [cacheKey: string]: string;
23
+ [cacheKey: string]: string;
24
24
  }
25
25
 
26
26
  /**
@@ -28,21 +28,15 @@ interface CacheIndex {
28
28
  * Uses SHA-256 hash of normalized goal + team + workflow.
29
29
  */
30
30
  export function computeRunCacheKey(goal: string, team: string, workflow: string, _cwd: string): string {
31
- const normalized = goal.trim().toLowerCase().replace(/\s+/g, " ");
32
- return crypto.createHash("sha256")
33
- .update(normalized)
34
- .update(team)
35
- .update(workflow)
36
- .update(_cwd)
37
- .digest("hex")
38
- .slice(0, 16);
31
+ const normalized = goal.trim().toLowerCase().replace(/\s+/g, " ");
32
+ return crypto.createHash("sha256").update(normalized).update(team).update(workflow).update(_cwd).digest("hex").slice(0, 16);
39
33
  }
40
34
 
41
35
  /**
42
36
  * Get the cache directory path.
43
37
  */
44
38
  function cacheDir(cwd: string): string {
45
- return path.join(projectCrewRoot(cwd), "cache");
39
+ return path.join(projectCrewRoot(cwd), "cache");
46
40
  }
47
41
 
48
42
  /**
@@ -50,137 +44,150 @@ function cacheDir(cwd: string): string {
50
44
  * Returns null if cache miss or expired.
51
45
  */
52
46
  export function getCachedRun(cwd: string, cacheKey: string): CacheEntry | null {
53
- const dir = cacheDir(cwd);
54
- const indexPath = path.join(dir, "index.json");
55
-
56
- if (!fs.existsSync(indexPath)) return null;
57
-
58
- try {
59
- const index = JSON.parse(fs.readFileSync(indexPath, "utf-8")) as CacheIndex;
60
- const entryPath = index[cacheKey];
61
-
62
- if (!entryPath || !fs.existsSync(entryPath)) return null;
63
-
64
- const entry = JSON.parse(fs.readFileSync(entryPath, "utf-8")) as CacheEntry;
65
-
66
- if (Date.now() > entry.expiresAt) {
67
- // Remove expired entry — use lock + atomic write to prevent index corruption
68
- withFileLockSync(indexPath, () => {
69
- try {
70
- fs.unlinkSync(entryPath);
71
- } catch { /* ignore */ }
72
- const updatedIndex = JSON.parse(fs.readFileSync(indexPath, "utf-8")) as CacheIndex;
73
- delete updatedIndex[cacheKey];
74
- atomicWriteFile(indexPath, JSON.stringify(updatedIndex));
75
- });
76
- return null;
77
- }
78
-
79
- return entry;
80
- } catch {
81
- return null;
82
- }
47
+ const dir = cacheDir(cwd);
48
+ const indexPath = path.join(dir, "index.json");
49
+
50
+ if (!fs.existsSync(indexPath)) return null;
51
+
52
+ try {
53
+ const index = JSON.parse(fs.readFileSync(indexPath, "utf-8")) as CacheIndex;
54
+ const entryPath = index[cacheKey];
55
+
56
+ if (!entryPath || !fs.existsSync(entryPath)) return null;
57
+
58
+ const entry = JSON.parse(fs.readFileSync(entryPath, "utf-8")) as CacheEntry;
59
+
60
+ if (Date.now() > entry.expiresAt) {
61
+ // Remove expired entry — use lock + atomic write to prevent index corruption
62
+ withFileLockSync(indexPath, () => {
63
+ try {
64
+ fs.unlinkSync(entryPath);
65
+ } catch {
66
+ /* ignore */
67
+ }
68
+ const updatedIndex = JSON.parse(fs.readFileSync(indexPath, "utf-8")) as CacheIndex;
69
+ delete updatedIndex[cacheKey];
70
+ atomicWriteFile(indexPath, JSON.stringify(updatedIndex));
71
+ });
72
+ return null;
73
+ }
74
+
75
+ return entry;
76
+ } catch {
77
+ return null;
78
+ }
83
79
  }
84
80
 
85
81
  /**
86
82
  * Save run result to cache.
87
83
  */
88
84
  export function saveRunToCache(
89
- cwd: string,
90
- cacheKey: string,
91
- runId: string,
92
- status: string,
93
- tasks: TeamTaskState[],
94
- goal: string,
95
- team: string,
96
- ttlMs: number = DEFAULT_CACHE_TTL_MS,
85
+ cwd: string,
86
+ cacheKey: string,
87
+ runId: string,
88
+ status: string,
89
+ tasks: TeamTaskState[],
90
+ goal: string,
91
+ team: string,
92
+ ttlMs: number = DEFAULT_CACHE_TTL_MS,
97
93
  ): void {
98
- const dir = cacheDir(cwd);
99
-
100
- if (!fs.existsSync(dir)) {
101
- fs.mkdirSync(dir, { recursive: true });
102
- }
103
-
104
- const entry: CacheEntry = {
105
- key: cacheKey,
106
- runId,
107
- status,
108
- tasks,
109
- cachedAt: Date.now(),
110
- expiresAt: Date.now() + ttlMs,
111
- goal,
112
- team,
113
- };
114
-
115
- const entryPath = path.join(dir, `${cacheKey}.json`);
116
- fs.writeFileSync(entryPath, JSON.stringify(entry), "utf-8");
117
-
118
- // Update index with atomic write: write to temp file then rename
119
- const indexPath = path.join(dir, "index.json");
120
- const index: CacheIndex = fs.existsSync(indexPath)
121
- ? JSON.parse(fs.readFileSync(indexPath, "utf-8"))
122
- : {};
123
-
124
- index[cacheKey] = entryPath;
125
-
126
- // Atomic write: write to temp file first, then rename
127
- const tempPath = path.join(dir, "index.json.tmp");
128
- fs.writeFileSync(tempPath, JSON.stringify(index), "utf-8");
129
- fs.renameSync(tempPath, indexPath);
94
+ const dir = cacheDir(cwd);
95
+
96
+ if (!fs.existsSync(dir)) {
97
+ fs.mkdirSync(dir, { recursive: true });
98
+ }
99
+
100
+ const entry: CacheEntry = {
101
+ key: cacheKey,
102
+ runId,
103
+ status,
104
+ tasks,
105
+ cachedAt: Date.now(),
106
+ expiresAt: Date.now() + ttlMs,
107
+ goal,
108
+ team,
109
+ };
110
+
111
+ const entryPath = path.join(dir, `${cacheKey}.json`);
112
+ fs.writeFileSync(entryPath, JSON.stringify(entry), "utf-8");
113
+
114
+ // Update index with atomic write: write to temp file then rename
115
+ const indexPath = path.join(dir, "index.json");
116
+ const index: CacheIndex = fs.existsSync(indexPath) ? JSON.parse(fs.readFileSync(indexPath, "utf-8")) : {};
117
+
118
+ index[cacheKey] = entryPath;
119
+
120
+ // Atomic write: write to temp file first, then rename
121
+ const tempPath = path.join(dir, "index.json.tmp");
122
+ fs.writeFileSync(tempPath, JSON.stringify(index), "utf-8");
123
+ fs.renameSync(tempPath, indexPath);
130
124
  }
131
125
 
132
126
  /**
133
127
  * Clear all cache entries.
134
128
  */
135
129
  export function clearCache(cwd: string): void {
136
- const dir = cacheDir(cwd);
137
- if (!fs.existsSync(dir)) return;
138
-
139
- const indexPath = path.join(dir, "index.json");
140
- if (fs.existsSync(indexPath)) {
141
- try {
142
- const index = JSON.parse(fs.readFileSync(indexPath, "utf-8")) as CacheIndex;
143
- for (const entryPath of Object.values(index)) {
144
- try {
145
- fs.unlinkSync(entryPath);
146
- } catch { /* ignore */ }
147
- }
148
- fs.unlinkSync(indexPath);
149
- } catch { /* ignore */ }
150
- }
151
-
152
- // Remove entry files not in index
153
- const entries = fs.readdirSync(dir).filter((f) => f.endsWith(".json"));
154
- for (const entry of entries) {
155
- try {
156
- fs.unlinkSync(path.join(dir, entry));
157
- } catch { /* ignore */ }
158
- }
130
+ const dir = cacheDir(cwd);
131
+ if (!fs.existsSync(dir)) return;
132
+
133
+ const indexPath = path.join(dir, "index.json");
134
+ if (fs.existsSync(indexPath)) {
135
+ try {
136
+ const index = JSON.parse(fs.readFileSync(indexPath, "utf-8")) as CacheIndex;
137
+ for (const entryPath of Object.values(index)) {
138
+ try {
139
+ fs.unlinkSync(entryPath);
140
+ } catch {
141
+ /* ignore */
142
+ }
143
+ }
144
+ fs.unlinkSync(indexPath);
145
+ } catch {
146
+ /* ignore */
147
+ }
148
+ }
149
+
150
+ // Remove entry files not in index
151
+ const entries = fs.readdirSync(dir).filter((f) => f.endsWith(".json"));
152
+ for (const entry of entries) {
153
+ try {
154
+ fs.unlinkSync(path.join(dir, entry));
155
+ } catch {
156
+ /* ignore */
157
+ }
158
+ }
159
159
  }
160
160
 
161
161
  /**
162
162
  * Get cache stats.
163
163
  */
164
- export function getCacheStats(cwd: string): { entries: number; sizeBytes: number } {
165
- const dir = cacheDir(cwd);
166
- if (!fs.existsSync(dir)) return { entries: 0, sizeBytes: 0 };
167
-
168
- let sizeBytes = 0;
169
- let entries = 0;
170
- const indexPath = path.join(dir, "index.json");
171
-
172
- if (fs.existsSync(indexPath)) {
173
- try {
174
- const index = JSON.parse(fs.readFileSync(indexPath, "utf-8")) as CacheIndex;
175
- entries = Object.keys(index).length;
176
- for (const entryPath of Object.values(index)) {
177
- try {
178
- const stat = fs.statSync(entryPath);
179
- sizeBytes += stat.size;
180
- } catch { /* ignore */ }
181
- }
182
- } catch { /* ignore */ }
183
- }
184
-
185
- return { entries, sizeBytes };
164
+ export function getCacheStats(cwd: string): {
165
+ entries: number;
166
+ sizeBytes: number;
167
+ } {
168
+ const dir = cacheDir(cwd);
169
+ if (!fs.existsSync(dir)) return { entries: 0, sizeBytes: 0 };
170
+
171
+ let sizeBytes = 0;
172
+ let entries = 0;
173
+ const indexPath = path.join(dir, "index.json");
174
+
175
+ if (fs.existsSync(indexPath)) {
176
+ try {
177
+ const index = JSON.parse(fs.readFileSync(indexPath, "utf-8")) as CacheIndex;
178
+ entries = Object.keys(index).length;
179
+ for (const entryPath of Object.values(index)) {
180
+ try {
181
+ const stat = fs.statSync(entryPath);
182
+ sizeBytes += stat.size;
183
+ } catch {
184
+ /* ignore */
185
+ }
186
+ }
187
+ } catch {
188
+ /* ignore */
189
+ }
190
+ }
191
+
192
+ return { entries, sizeBytes };
186
193
  }
@@ -40,10 +40,7 @@ export interface RunGraph {
40
40
  * Build a unified run graph from manifest + tasks.
41
41
  * Consolidates state into a single graph JSON for dashboard/API use.
42
42
  */
43
- export function buildRunGraph(
44
- manifest: TeamRunManifest,
45
- tasks: TeamTaskState[],
46
- ): RunGraph {
43
+ export function buildRunGraph(manifest: TeamRunManifest, tasks: TeamTaskState[]): RunGraph {
47
44
  const nodes: RunGraphNode[] = [];
48
45
  const edges: RunGraphEdge[] = [];
49
46
  const nodeIds = new Set<string>();
@@ -106,12 +103,10 @@ export function buildRunGraph(
106
103
  layerMap.get(layerName)!.push(`task:${task.id}`);
107
104
  }
108
105
 
109
- const layers: RunGraphLayer[] = [...layerMap.entries()].map(
110
- ([name, nodeIdList]) => ({
111
- name,
112
- nodeIds: nodeIdList,
113
- }),
114
- );
106
+ const layers: RunGraphLayer[] = [...layerMap.entries()].map(([name, nodeIdList]) => ({
107
+ name,
108
+ nodeIds: nodeIdList,
109
+ }));
115
110
 
116
111
  return {
117
112
  version: "1.0.0",
@@ -181,11 +176,7 @@ export function listRunGraphs(cwd: string): string[] {
181
176
  /**
182
177
  * Build and save run graph from manifest + tasks.
183
178
  */
184
- export function buildAndSaveRunGraph(
185
- manifest: TeamRunManifest,
186
- tasks: TeamTaskState[],
187
- cwd: string,
188
- ): string {
179
+ export function buildAndSaveRunGraph(manifest: TeamRunManifest, tasks: TeamTaskState[], cwd: string): string {
189
180
  const graph = buildRunGraph(manifest, tasks);
190
181
  return saveRunGraph(graph, cwd);
191
182
  }
@@ -37,10 +37,7 @@ function metricsFilePath(cwd: string, runId: string): string {
37
37
  * Collect metrics for a run by reading its manifest, tasks, and event log.
38
38
  * Returns undefined if the run cannot be loaded.
39
39
  */
40
- export function collectRunMetrics(
41
- cwd: string,
42
- runId: string,
43
- ): RunMetrics | undefined {
40
+ export function collectRunMetrics(cwd: string, runId: string): RunMetrics | undefined {
44
41
  assertSafePathId("runId", runId);
45
42
  const result = loadRunManifestById(cwd, runId); // NOTE: no withRunLock - best-effort only; concurrent writes may cause inconsistency;
46
43
  if (!result) return undefined;
@@ -69,17 +66,11 @@ export function collectRunMetrics(
69
66
  // Duration: from run createdAt to updatedAt (manifest timestamps), or 0 if unavailable.
70
67
  const createdAt = new Date(manifest.createdAt).getTime();
71
68
  const updatedAt = new Date(manifest.updatedAt).getTime();
72
- const durationMs =
73
- isNaN(createdAt) || isNaN(updatedAt)
74
- ? 0
75
- : Math.max(0, updatedAt - createdAt);
69
+ const durationMs = isNaN(createdAt) || isNaN(updatedAt) ? 0 : Math.max(0, updatedAt - createdAt);
76
70
 
77
71
  // Consistency score: proportion of tasks that completed successfully among all non-skipped tasks.
78
72
  const nonSkippedTasks = tasks.filter((t) => t.status !== "skipped");
79
- const consistencyScore =
80
- nonSkippedTasks.length > 0
81
- ? completedCount / nonSkippedTasks.length
82
- : 1.0;
73
+ const consistencyScore = nonSkippedTasks.length > 0 ? completedCount / nonSkippedTasks.length : 1.0;
83
74
 
84
75
  return {
85
76
  runId,
@@ -108,10 +99,7 @@ export function saveRunMetrics(cwd: string, metrics: RunMetrics): void {
108
99
  * Load a previously saved metrics snapshot.
109
100
  * Returns undefined if the file does not exist or cannot be parsed.
110
101
  */
111
- export function loadRunMetrics(
112
- cwd: string,
113
- runId: string,
114
- ): RunMetrics | undefined {
102
+ export function loadRunMetrics(cwd: string, runId: string): RunMetrics | undefined {
115
103
  return readJsonFile<RunMetrics>(metricsFilePath(cwd, runId));
116
104
  }
117
105
 
@@ -140,8 +128,7 @@ export function getRunMetricsSummary(cwd: string, limit = 25): RunMetrics[] {
140
128
 
141
129
  // Sort newest first (by timestamp, then runId as tiebreaker).
142
130
  metrics.sort((a, b) => {
143
- const diff =
144
- new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime();
131
+ const diff = new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime();
145
132
  if (diff !== 0) return diff;
146
133
  return b.runId.localeCompare(a.runId);
147
134
  });
@@ -11,7 +11,7 @@ import * as fs from "node:fs";
11
11
  import * as path from "node:path";
12
12
  import { logInternalError } from "../utils/internal-error.ts";
13
13
 
14
- import type { ScheduleStoreData, ScheduledTask } from "./types.ts";
14
+ import type { ScheduledTask, ScheduleStoreData } from "./types.ts";
15
15
 
16
16
  export type DetectedSchedule =
17
17
  | { type: "cron"; normalized: string }
@@ -34,7 +34,10 @@ export function parseInterval(s: string): number | null {
34
34
  }
35
35
 
36
36
  /** 6-field cron validation ("second minute hour dom month dow"). */
37
- export function validateCronExpression(expr: string): { valid: boolean; error?: string } {
37
+ export function validateCronExpression(expr: string): {
38
+ valid: boolean;
39
+ error?: string;
40
+ } {
38
41
  const fields = expr.trim().split(/\s+/);
39
42
  if (fields.length !== 6) {
40
43
  return {
@@ -43,8 +46,11 @@ export function validateCronExpression(expr: string): { valid: boolean; error?:
43
46
  };
44
47
  }
45
48
  // Basic format check: all fields must be non-empty
46
- if (!fields.every(f => f.length > 0)) {
47
- return { valid: false, error: "Cron expression contains empty fields." };
49
+ if (!fields.every((f) => f.length > 0)) {
50
+ return {
51
+ valid: false,
52
+ error: "Cron expression contains empty fields.",
53
+ };
48
54
  }
49
55
  // Accept any cron pattern — fail silently for malformed expressions
50
56
  // (the croner library will reject at execution time)
@@ -122,11 +128,11 @@ export class ScheduleStore {
122
128
  }
123
129
 
124
130
  hasName(name: string): boolean {
125
- return this.data.jobs.some(j => j.name === name);
131
+ return this.data.jobs.some((j) => j.name === name);
126
132
  }
127
133
 
128
134
  get(id: string): ScheduledTask | undefined {
129
- return this.data.jobs.find(j => j.id === id);
135
+ return this.data.jobs.find((j) => j.id === id);
130
136
  }
131
137
 
132
138
  add(job: ScheduledTask): void {
@@ -135,7 +141,7 @@ export class ScheduleStore {
135
141
  }
136
142
 
137
143
  update(id: string, patch: Partial<ScheduledTask>): ScheduledTask | undefined {
138
- const idx = this.data.jobs.findIndex(j => j.id === id);
144
+ const idx = this.data.jobs.findIndex((j) => j.id === id);
139
145
  if (idx === -1) return undefined;
140
146
  this.data.jobs[idx] = { ...this.data.jobs[idx], ...patch };
141
147
  this.save();
@@ -144,11 +150,11 @@ export class ScheduleStore {
144
150
 
145
151
  remove(id: string): boolean {
146
152
  const before = this.data.jobs.length;
147
- this.data.jobs = this.data.jobs.filter(j => j.id !== id);
153
+ this.data.jobs = this.data.jobs.filter((j) => j.id !== id);
148
154
  if (this.data.jobs.length !== before) {
149
155
  this.save();
150
156
  return true;
151
157
  }
152
158
  return false;
153
159
  }
154
- }
160
+ }