session-orchestrator 3.16.0

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 (762) hide show
  1. package/.claude-plugin/marketplace.json +29 -0
  2. package/.claude-plugin/plugin.json +18 -0
  3. package/.codex-plugin/agents/explorer.toml +14 -0
  4. package/.codex-plugin/agents/session-reviewer.toml +23 -0
  5. package/.codex-plugin/agents/wave-worker.toml +15 -0
  6. package/.codex-plugin/config.toml +20 -0
  7. package/.codex-plugin/plugin.json +37 -0
  8. package/.cursor/rules/000-session-orchestrator.mdc +73 -0
  9. package/.cursor/rules/010-session-workflow.mdc +170 -0
  10. package/.cursor/rules/020-quality-gates.mdc +128 -0
  11. package/.cursor/rules/030-wave-execution.mdc +216 -0
  12. package/.cursor/rules/040-discovery.mdc +242 -0
  13. package/.cursor/rules/050-plan.mdc +235 -0
  14. package/.cursor/rules/060-evolve.mdc +232 -0
  15. package/.cursor/rules/070-gitlab-ops.mdc +246 -0
  16. package/.cursor/rules/080-ecosystem-health.mdc +145 -0
  17. package/.mcp.json +8 -0
  18. package/CHANGELOG.md +1544 -0
  19. package/LICENSE +21 -0
  20. package/NOTICE +64 -0
  21. package/README.md +242 -0
  22. package/SECURITY.md +90 -0
  23. package/agents/AGENTS.md +136 -0
  24. package/agents/analyst.md +99 -0
  25. package/agents/architect-reviewer.md +93 -0
  26. package/agents/code-implementer.md +106 -0
  27. package/agents/db-specialist.md +104 -0
  28. package/agents/dialectic-deriver.md +139 -0
  29. package/agents/docs-writer.md +113 -0
  30. package/agents/eval-judge.md +146 -0
  31. package/agents/memory-proposal-collector.md +297 -0
  32. package/agents/qa-strategist.md +102 -0
  33. package/agents/schemas/analyst.schema.json +46 -0
  34. package/agents/schemas/architect-reviewer.schema.json +50 -0
  35. package/agents/schemas/code-implementer.schema.json +61 -0
  36. package/agents/schemas/db-specialist.schema.json +80 -0
  37. package/agents/schemas/docs-writer.schema.json +56 -0
  38. package/agents/schemas/persona-panel-sidecar.schema.json +245 -0
  39. package/agents/schemas/qa-strategist.schema.json +46 -0
  40. package/agents/schemas/security-reviewer.schema.json +86 -0
  41. package/agents/schemas/session-reviewer.schema.json +69 -0
  42. package/agents/schemas/test-writer.schema.json +69 -0
  43. package/agents/schemas/ui-developer.schema.json +90 -0
  44. package/agents/schemas/ux-evaluator.schema.json +51 -0
  45. package/agents/security-reviewer.md +236 -0
  46. package/agents/session-reviewer.md +201 -0
  47. package/agents/skill-applied-judge.md +122 -0
  48. package/agents/test-writer.md +123 -0
  49. package/agents/ui-developer.md +109 -0
  50. package/agents/ux-evaluator.md +161 -0
  51. package/assets/icon.svg +11 -0
  52. package/assets/og-card.png +0 -0
  53. package/assets/og-card.svg +47 -0
  54. package/commands/autopilot-multi.md +74 -0
  55. package/commands/autopilot.md +80 -0
  56. package/commands/bootstrap.md +56 -0
  57. package/commands/brainstorm.md +48 -0
  58. package/commands/close.md +24 -0
  59. package/commands/debug.md +36 -0
  60. package/commands/discovery.md +32 -0
  61. package/commands/dispatcher.md +59 -0
  62. package/commands/eval.md +28 -0
  63. package/commands/evolve.md +10 -0
  64. package/commands/go.md +41 -0
  65. package/commands/grill.md +45 -0
  66. package/commands/harness-audit.md +26 -0
  67. package/commands/memory-cleanup.md +25 -0
  68. package/commands/persona-panel.md +121 -0
  69. package/commands/plan.md +15 -0
  70. package/commands/portfolio.md +97 -0
  71. package/commands/reconcile.md +23 -0
  72. package/commands/repo-audit.md +24 -0
  73. package/commands/session.md +30 -0
  74. package/commands/spinout.md +15 -0
  75. package/commands/sunset-review.md +27 -0
  76. package/commands/templates-ack.md +96 -0
  77. package/commands/test.md +97 -0
  78. package/docs/README.md +105 -0
  79. package/docs/USER-GUIDE.md +1403 -0
  80. package/docs/ci-setup.md +81 -0
  81. package/docs/codex-setup.md +142 -0
  82. package/docs/components.md +74 -0
  83. package/docs/cursor-setup.md +104 -0
  84. package/docs/events-schema.md +81 -0
  85. package/docs/migration-v3.md +148 -0
  86. package/docs/owner-config-schema.md +154 -0
  87. package/docs/persona-panel.md +433 -0
  88. package/docs/pi-setup.md +115 -0
  89. package/docs/plugin-architecture-v3.md +296 -0
  90. package/docs/pm-skills-marketplace.md +114 -0
  91. package/docs/policy-cache-validation-2026-04-28.md +118 -0
  92. package/docs/rule-authoring.md +316 -0
  93. package/docs/session-config-reference.md +1439 -0
  94. package/docs/session-config-template.md +961 -0
  95. package/docs/vault-docs-architecture.md +297 -0
  96. package/hooks/_lib/lock-bootstrap.mjs +272 -0
  97. package/hooks/_lib/lock-reconcile.mjs +93 -0
  98. package/hooks/_lib/profile-gate.mjs +95 -0
  99. package/hooks/_lib/transcript-history.mjs +211 -0
  100. package/hooks/agent-teams-h3-test.sh +362 -0
  101. package/hooks/config-protection.mjs +0 -0
  102. package/hooks/cwd-change-restore.mjs +131 -0
  103. package/hooks/enforce-commands.mjs +179 -0
  104. package/hooks/enforce-scope.mjs +273 -0
  105. package/hooks/hooks-codex.json +60 -0
  106. package/hooks/hooks-cursor.json +15 -0
  107. package/hooks/hooks-pi.json +115 -0
  108. package/hooks/hooks.json +215 -0
  109. package/hooks/loop-guard.mjs +260 -0
  110. package/hooks/on-session-end.mjs +217 -0
  111. package/hooks/on-session-start.mjs +660 -0
  112. package/hooks/on-stop.mjs +294 -0
  113. package/hooks/operator-steer.mjs +64 -0
  114. package/hooks/post-edit-validate.mjs +225 -0
  115. package/hooks/post-subagent-discovery-validator.mjs +398 -0
  116. package/hooks/post-tool-batch-wave-signal.mjs +328 -0
  117. package/hooks/post-tool-failure-corrective-context.mjs +248 -0
  118. package/hooks/post-tooluse-frontend-slop.mjs +184 -0
  119. package/hooks/pre-bash-destructive-guard.mjs +515 -0
  120. package/hooks/pre-bash-memory-propose-audit.mjs +206 -0
  121. package/hooks/pre-bash-staging-fence.mjs +223 -0
  122. package/hooks/pre-bash-templates-first.mjs +404 -0
  123. package/hooks/run-node.sh +72 -0
  124. package/hooks/skill-invocation-telemetry.mjs +99 -0
  125. package/hooks/subagent-telemetry.mjs +249 -0
  126. package/hooks/wave-scope-commit-guard.mjs +191 -0
  127. package/monitors/monitors.json +14 -0
  128. package/output-styles/finding-report.md +48 -0
  129. package/output-styles/session-report.md +53 -0
  130. package/output-styles/wave-summary.md +38 -0
  131. package/package.json +94 -0
  132. package/pi/extensions/session-orchestrator.ts +25 -0
  133. package/pi/prompts/autopilot-multi.md +12 -0
  134. package/pi/prompts/autopilot.md +12 -0
  135. package/pi/prompts/bootstrap.md +12 -0
  136. package/pi/prompts/brainstorm.md +12 -0
  137. package/pi/prompts/close.md +11 -0
  138. package/pi/prompts/debug.md +12 -0
  139. package/pi/prompts/discovery.md +12 -0
  140. package/pi/prompts/dispatcher.md +12 -0
  141. package/pi/prompts/eval.md +12 -0
  142. package/pi/prompts/evolve.md +12 -0
  143. package/pi/prompts/go.md +12 -0
  144. package/pi/prompts/grill.md +12 -0
  145. package/pi/prompts/harness-audit.md +12 -0
  146. package/pi/prompts/memory-cleanup.md +12 -0
  147. package/pi/prompts/persona-panel.md +12 -0
  148. package/pi/prompts/plan.md +12 -0
  149. package/pi/prompts/portfolio.md +12 -0
  150. package/pi/prompts/reconcile.md +12 -0
  151. package/pi/prompts/repo-audit.md +12 -0
  152. package/pi/prompts/session.md +12 -0
  153. package/pi/prompts/spinout.md +12 -0
  154. package/pi/prompts/sunset-review.md +12 -0
  155. package/pi/prompts/templates-ack.md +12 -0
  156. package/pi/prompts/test.md +12 -0
  157. package/rules/_index.md +51 -0
  158. package/rules/always-on/commit-discipline.md +26 -0
  159. package/rules/always-on/npm-quality-gates.md +26 -0
  160. package/rules/always-on/parallel-sessions.md +43 -0
  161. package/rules/opt-in-domain/prompt-caching.md +270 -0
  162. package/rules/opt-in-stack/backend-data.md +188 -0
  163. package/rules/opt-in-stack/backend.md +390 -0
  164. package/rules/opt-in-stack/frontend.md +98 -0
  165. package/rules/opt-in-stack/security-web.md +194 -0
  166. package/rules/opt-in-stack/swift.md +65 -0
  167. package/scripts/archive-closed-prds.mjs +416 -0
  168. package/scripts/autopilot-multi.mjs +802 -0
  169. package/scripts/autopilot.mjs +383 -0
  170. package/scripts/backfill-abandoned-sessions.mjs +265 -0
  171. package/scripts/backfill-learnings-expires.mjs +196 -0
  172. package/scripts/backfill-learnings.mjs +203 -0
  173. package/scripts/backfill-sessions.mjs +282 -0
  174. package/scripts/check-doc-consistency.sh +279 -0
  175. package/scripts/check-package-manager.mjs +445 -0
  176. package/scripts/ci/assert-vitest-green.mjs +267 -0
  177. package/scripts/codex-install.mjs +435 -0
  178. package/scripts/compute-grounding-injection.sh +186 -0
  179. package/scripts/cursor-install.mjs +113 -0
  180. package/scripts/dialectic-deriver.mjs +573 -0
  181. package/scripts/emit-event.mjs +160 -0
  182. package/scripts/emit-session.mjs +212 -0
  183. package/scripts/eval-session.mjs +262 -0
  184. package/scripts/export-hw-learnings.mjs +437 -0
  185. package/scripts/gc-stale-worktrees.mjs +666 -0
  186. package/scripts/generate-pi-prompts.mjs +127 -0
  187. package/scripts/harness-audit.mjs +287 -0
  188. package/scripts/lib/agent-frontmatter.mjs +266 -0
  189. package/scripts/lib/agent-output-schema.mjs +166 -0
  190. package/scripts/lib/agent-status.mjs +303 -0
  191. package/scripts/lib/ajv-loader.mjs +34 -0
  192. package/scripts/lib/auto-dialectic.mjs +382 -0
  193. package/scripts/lib/auto-dream.mjs +471 -0
  194. package/scripts/lib/autonomy/suitability.mjs +212 -0
  195. package/scripts/lib/autopilot/dep-graph.mjs +417 -0
  196. package/scripts/lib/autopilot/durable-telemetry.mjs +121 -0
  197. package/scripts/lib/autopilot/flags.mjs +104 -0
  198. package/scripts/lib/autopilot/kill-switches.mjs +174 -0
  199. package/scripts/lib/autopilot/loop.mjs +320 -0
  200. package/scripts/lib/autopilot/mr-draft.mjs +520 -0
  201. package/scripts/lib/autopilot/multi-killswitch.mjs +184 -0
  202. package/scripts/lib/autopilot/recent-runs.mjs +106 -0
  203. package/scripts/lib/autopilot/stall-sampler.mjs +97 -0
  204. package/scripts/lib/autopilot/telemetry.mjs +224 -0
  205. package/scripts/lib/autopilot/worktree-pipeline.mjs +605 -0
  206. package/scripts/lib/autopilot-telemetry.mjs +11 -0
  207. package/scripts/lib/autopilot.mjs +39 -0
  208. package/scripts/lib/backlog-scan.mjs +179 -0
  209. package/scripts/lib/bootstrap-lock-freshness.mjs +260 -0
  210. package/scripts/lib/bootstrap-lock-refresh.mjs +186 -0
  211. package/scripts/lib/build-live-signals.mjs +150 -0
  212. package/scripts/lib/ci-status-banner.mjs +425 -0
  213. package/scripts/lib/claude-md-budget-lint.mjs +246 -0
  214. package/scripts/lib/cli-flags.mjs +158 -0
  215. package/scripts/lib/codex/plugin-contract.mjs +610 -0
  216. package/scripts/lib/cold-start-detector.mjs +240 -0
  217. package/scripts/lib/command-blocker.mjs +458 -0
  218. package/scripts/lib/common.mjs +333 -0
  219. package/scripts/lib/config/auto-dream.mjs +77 -0
  220. package/scripts/lib/config/block-header.mjs +94 -0
  221. package/scripts/lib/config/broken-window.mjs +114 -0
  222. package/scripts/lib/config/coercers.mjs +248 -0
  223. package/scripts/lib/config/cold-start.mjs +92 -0
  224. package/scripts/lib/config/config-protection.mjs +120 -0
  225. package/scripts/lib/config/cross-repo.mjs +104 -0
  226. package/scripts/lib/config/custom-phases.mjs +213 -0
  227. package/scripts/lib/config/dialectic.mjs +92 -0
  228. package/scripts/lib/config/discovery-validator.mjs +75 -0
  229. package/scripts/lib/config/dispatcher-autonomy-capture.mjs +240 -0
  230. package/scripts/lib/config/dispatcher-autonomy.mjs +152 -0
  231. package/scripts/lib/config/docs-orchestrator.mjs +90 -0
  232. package/scripts/lib/config/docs-staleness.mjs +96 -0
  233. package/scripts/lib/config/drift-check.mjs +155 -0
  234. package/scripts/lib/config/eval.mjs +130 -0
  235. package/scripts/lib/config/events-rotation.mjs +74 -0
  236. package/scripts/lib/config/evolve.mjs +308 -0
  237. package/scripts/lib/config/frontend-slop-hook.mjs +104 -0
  238. package/scripts/lib/config/gitlab-portfolio.mjs +150 -0
  239. package/scripts/lib/config/handover-gate.mjs +106 -0
  240. package/scripts/lib/config/host-paths.mjs +76 -0
  241. package/scripts/lib/config/io.mjs +54 -0
  242. package/scripts/lib/config/loop-guard.mjs +117 -0
  243. package/scripts/lib/config/memory.mjs +150 -0
  244. package/scripts/lib/config/persona-gate-wave.mjs +258 -0
  245. package/scripts/lib/config/reconcile.mjs +205 -0
  246. package/scripts/lib/config/section-extractor.mjs +100 -0
  247. package/scripts/lib/config/skill-evolution.mjs +112 -0
  248. package/scripts/lib/config/slopcheck.mjs +99 -0
  249. package/scripts/lib/config/state-md-lock.mjs +83 -0
  250. package/scripts/lib/config/templates-first.mjs +94 -0
  251. package/scripts/lib/config/test.mjs +113 -0
  252. package/scripts/lib/config/vault-integration.mjs +201 -0
  253. package/scripts/lib/config/vault-mirror-quality.mjs +99 -0
  254. package/scripts/lib/config/vault-staleness.mjs +84 -0
  255. package/scripts/lib/config/vault-sync.mjs +96 -0
  256. package/scripts/lib/config/verification-auto-fix.mjs +84 -0
  257. package/scripts/lib/config/wave-reviewers.mjs +133 -0
  258. package/scripts/lib/config-schema.mjs +345 -0
  259. package/scripts/lib/config.mjs +474 -0
  260. package/scripts/lib/convergence-monitor.mjs +389 -0
  261. package/scripts/lib/coordinator-snapshot.mjs +371 -0
  262. package/scripts/lib/crypto-digest-utils.mjs +91 -0
  263. package/scripts/lib/discovery/helpers.mjs +127 -0
  264. package/scripts/lib/discovery/triage-state.mjs +279 -0
  265. package/scripts/lib/dispatcher/cli.mjs +257 -0
  266. package/scripts/lib/dispatcher/enumerate.mjs +243 -0
  267. package/scripts/lib/dispatcher/rank.mjs +363 -0
  268. package/scripts/lib/ecosystem-health.mjs +224 -0
  269. package/scripts/lib/ecosystem-wizard/ci-detector.mjs +18 -0
  270. package/scripts/lib/ecosystem-wizard/config-parser.mjs +54 -0
  271. package/scripts/lib/ecosystem-wizard/config-writer.mjs +287 -0
  272. package/scripts/lib/ecosystem-wizard/package-manager-detector.mjs +42 -0
  273. package/scripts/lib/ecosystem-wizard/wizard-prompt.mjs +246 -0
  274. package/scripts/lib/ecosystem-wizard.mjs +48 -0
  275. package/scripts/lib/env-check.mjs +89 -0
  276. package/scripts/lib/eval/engine.mjs +605 -0
  277. package/scripts/lib/eval/judge.mjs +433 -0
  278. package/scripts/lib/eval/report.mjs +367 -0
  279. package/scripts/lib/eval/schema.mjs +618 -0
  280. package/scripts/lib/eval/session-resolve.mjs +137 -0
  281. package/scripts/lib/eval/sink.mjs +77 -0
  282. package/scripts/lib/events-rotation.mjs +86 -0
  283. package/scripts/lib/events-schema.mjs +81 -0
  284. package/scripts/lib/events.mjs +80 -0
  285. package/scripts/lib/evolve/autonomy-verdict.mjs +461 -0
  286. package/scripts/lib/evolve/autopilot-effectiveness.mjs +293 -0
  287. package/scripts/lib/exclusivity-matrix.mjs +68 -0
  288. package/scripts/lib/fetch-baseline.mjs +311 -0
  289. package/scripts/lib/file-lock.mjs +512 -0
  290. package/scripts/lib/frontend-detect/detect.mjs +138 -0
  291. package/scripts/lib/frontend-detect/rules.mjs +295 -0
  292. package/scripts/lib/frontmatter-guard.mjs +241 -0
  293. package/scripts/lib/gates/echo-stub-detect.mjs +39 -0
  294. package/scripts/lib/gates/gate-baseline.mjs +42 -0
  295. package/scripts/lib/gates/gate-full.mjs +85 -0
  296. package/scripts/lib/gates/gate-helpers.mjs +231 -0
  297. package/scripts/lib/gates/gate-incremental.mjs +76 -0
  298. package/scripts/lib/gates/gate-per-file.mjs +55 -0
  299. package/scripts/lib/gitlab-ops/stale-mr-sweep.mjs +447 -0
  300. package/scripts/lib/gitlab-portfolio/aggregator.mjs +383 -0
  301. package/scripts/lib/gitlab-portfolio/cli.mjs +428 -0
  302. package/scripts/lib/gitlab-portfolio/markdown-writer.mjs +289 -0
  303. package/scripts/lib/gitlab-portfolio/vcs-detect.mjs +182 -0
  304. package/scripts/lib/handover-gate.mjs +222 -0
  305. package/scripts/lib/hardening.mjs +43 -0
  306. package/scripts/lib/hardware-pattern-detector.mjs +238 -0
  307. package/scripts/lib/harness-audit/categories/category1.mjs +123 -0
  308. package/scripts/lib/harness-audit/categories/category2.mjs +145 -0
  309. package/scripts/lib/harness-audit/categories/category3.mjs +143 -0
  310. package/scripts/lib/harness-audit/categories/category4.mjs +202 -0
  311. package/scripts/lib/harness-audit/categories/category5.mjs +152 -0
  312. package/scripts/lib/harness-audit/categories/category6.mjs +211 -0
  313. package/scripts/lib/harness-audit/categories/category7.mjs +125 -0
  314. package/scripts/lib/harness-audit/categories/category8.mjs +328 -0
  315. package/scripts/lib/harness-audit/categories/category9.mjs +294 -0
  316. package/scripts/lib/harness-audit/categories/helpers.mjs +165 -0
  317. package/scripts/lib/harness-audit/categories.mjs +19 -0
  318. package/scripts/lib/historical-guard.mjs +15 -0
  319. package/scripts/lib/host-identity.mjs +262 -0
  320. package/scripts/lib/instruction-budget-guard.mjs +332 -0
  321. package/scripts/lib/io.mjs +304 -0
  322. package/scripts/lib/issue-close-strip-labels.mjs +161 -0
  323. package/scripts/lib/language-mappers/README.md +57 -0
  324. package/scripts/lib/language-mappers/index.mjs +165 -0
  325. package/scripts/lib/language-mappers/markdown.mjs +149 -0
  326. package/scripts/lib/language-mappers/python.mjs +249 -0
  327. package/scripts/lib/language-mappers/swift.mjs +201 -0
  328. package/scripts/lib/language-mappers/typescript.mjs +433 -0
  329. package/scripts/lib/learnings/expiry-sweep.mjs +164 -0
  330. package/scripts/lib/learnings/filters.mjs +43 -0
  331. package/scripts/lib/learnings/io.mjs +255 -0
  332. package/scripts/lib/learnings/schema.mjs +518 -0
  333. package/scripts/lib/learnings/surface.mjs +207 -0
  334. package/scripts/lib/learnings.mjs +42 -0
  335. package/scripts/lib/lock-reaper.mjs +648 -0
  336. package/scripts/lib/locks/index.mjs +31 -0
  337. package/scripts/lib/locks/lock-body.mjs +62 -0
  338. package/scripts/lib/locks/staging-fence-lock.mjs +267 -0
  339. package/scripts/lib/locks/state-md-lock.mjs +351 -0
  340. package/scripts/lib/loop-readiness-banner.mjs +144 -0
  341. package/scripts/lib/memory-banner.mjs +478 -0
  342. package/scripts/lib/memory-cleanup/worktree-sweep.mjs +108 -0
  343. package/scripts/lib/memory-cleanup-stamp.mjs +56 -0
  344. package/scripts/lib/memory-paths.mjs +31 -0
  345. package/scripts/lib/memory-proposals/collector.mjs +334 -0
  346. package/scripts/lib/memory-proposals/schema.mjs +289 -0
  347. package/scripts/lib/memory-proposals/sink.mjs +507 -0
  348. package/scripts/lib/memory-proposals/store.mjs +441 -0
  349. package/scripts/lib/mission-status-schema.mjs +114 -0
  350. package/scripts/lib/mode-selector/alternatives.mjs +64 -0
  351. package/scripts/lib/mode-selector/constants.mjs +29 -0
  352. package/scripts/lib/mode-selector/context-pressure.mjs +157 -0
  353. package/scripts/lib/mode-selector/rationale.mjs +55 -0
  354. package/scripts/lib/mode-selector/scoring.mjs +221 -0
  355. package/scripts/lib/mode-selector-accuracy.mjs +121 -0
  356. package/scripts/lib/mode-selector.mjs +160 -0
  357. package/scripts/lib/multi-provider-build/providers.mjs +64 -0
  358. package/scripts/lib/multi-provider-build/templating.mjs +130 -0
  359. package/scripts/lib/named-baseline-resolver.mjs +233 -0
  360. package/scripts/lib/named-vault-resolver.mjs +433 -0
  361. package/scripts/lib/owner-config/coerce.mjs +29 -0
  362. package/scripts/lib/owner-config/constants.mjs +21 -0
  363. package/scripts/lib/owner-config/defaults.mjs +50 -0
  364. package/scripts/lib/owner-config/error.mjs +19 -0
  365. package/scripts/lib/owner-config/index.mjs +13 -0
  366. package/scripts/lib/owner-config/merge.mjs +52 -0
  367. package/scripts/lib/owner-config/validate.mjs +259 -0
  368. package/scripts/lib/owner-config-banner.mjs +126 -0
  369. package/scripts/lib/owner-config-loader.mjs +159 -0
  370. package/scripts/lib/owner-config.example.yaml +72 -0
  371. package/scripts/lib/owner-config.mjs +28 -0
  372. package/scripts/lib/owner-interview.mjs +243 -0
  373. package/scripts/lib/owner-yaml.mjs +571 -0
  374. package/scripts/lib/package-manager.mjs +160 -0
  375. package/scripts/lib/path-utils.mjs +217 -0
  376. package/scripts/lib/peer-cards/merger.mjs +310 -0
  377. package/scripts/lib/peer-cards/reader.mjs +125 -0
  378. package/scripts/lib/peer-cards/schema.mjs +230 -0
  379. package/scripts/lib/peer-cards/staleness-banner.mjs +86 -0
  380. package/scripts/lib/peer-cards/writer.mjs +138 -0
  381. package/scripts/lib/peer-discovery.mjs +200 -0
  382. package/scripts/lib/persona-panel/catalog-loader.mjs +577 -0
  383. package/scripts/lib/persona-panel/consolidator.mjs +370 -0
  384. package/scripts/lib/persona-panel/persona-runner.mjs +375 -0
  385. package/scripts/lib/persona-panel/threshold.mjs +130 -0
  386. package/scripts/lib/pi-hook-bridge.mjs +328 -0
  387. package/scripts/lib/platform.mjs +266 -0
  388. package/scripts/lib/playwright-driver/runner.mjs +297 -0
  389. package/scripts/lib/plugin-root.mjs +210 -0
  390. package/scripts/lib/pre-dispatch-check.mjs +126 -0
  391. package/scripts/lib/product-repo-detect.mjs +121 -0
  392. package/scripts/lib/profiles/registry.mjs +176 -0
  393. package/scripts/lib/profiles/schema.mjs +209 -0
  394. package/scripts/lib/qg-command-drift-banner.mjs +88 -0
  395. package/scripts/lib/quality-gate/diagnostics.mjs +92 -0
  396. package/scripts/lib/quality-gate.mjs +536 -0
  397. package/scripts/lib/quality-gates-cache.mjs +228 -0
  398. package/scripts/lib/quality-gates-policy.mjs +95 -0
  399. package/scripts/lib/recommendations-v0.mjs +156 -0
  400. package/scripts/lib/reconcile/eligibility.mjs +203 -0
  401. package/scripts/lib/reconcile/emitter.mjs +244 -0
  402. package/scripts/lib/reconcile/engine.mjs +412 -0
  403. package/scripts/lib/reconcile/idempotency.mjs +239 -0
  404. package/scripts/lib/reconcile/renderer.mjs +211 -0
  405. package/scripts/lib/reconcile/writer.mjs +293 -0
  406. package/scripts/lib/reconcile-nudge-banner.mjs +284 -0
  407. package/scripts/lib/resource-probe/evaluate.mjs +190 -0
  408. package/scripts/lib/resource-probe/parsers.mjs +181 -0
  409. package/scripts/lib/resource-probe/probe-platform.mjs +300 -0
  410. package/scripts/lib/resource-probe.mjs +95 -0
  411. package/scripts/lib/rule-loader.mjs +552 -0
  412. package/scripts/lib/rules-sync.mjs +439 -0
  413. package/scripts/lib/scope-gate.mjs +496 -0
  414. package/scripts/lib/session-close-backfill.mjs +539 -0
  415. package/scripts/lib/session-discovery.mjs +256 -0
  416. package/scripts/lib/session-end/phase-skip.mjs +357 -0
  417. package/scripts/lib/session-end/worktree-cleanup.mjs +112 -0
  418. package/scripts/lib/session-id.mjs +362 -0
  419. package/scripts/lib/session-lock.mjs +703 -0
  420. package/scripts/lib/session-registry.mjs +355 -0
  421. package/scripts/lib/session-schema/aliases.mjs +71 -0
  422. package/scripts/lib/session-schema/constants.mjs +115 -0
  423. package/scripts/lib/session-schema/normalizer.mjs +66 -0
  424. package/scripts/lib/session-schema/timestamps.mjs +64 -0
  425. package/scripts/lib/session-schema/validator.mjs +453 -0
  426. package/scripts/lib/session-schema.mjs +71 -0
  427. package/scripts/lib/session-token-rollup.mjs +137 -0
  428. package/scripts/lib/sessions-staleness-banner.mjs +247 -0
  429. package/scripts/lib/skill-evolution/blast-radius-classifier.mjs +114 -0
  430. package/scripts/lib/skill-evolution/candidate-intake.mjs +270 -0
  431. package/scripts/lib/skill-evolution/config-validation-gate.mjs +279 -0
  432. package/scripts/lib/skill-evolution/engine.mjs +719 -0
  433. package/scripts/lib/skill-evolution/idempotency.mjs +279 -0
  434. package/scripts/lib/skill-evolution/mr-opener.mjs +507 -0
  435. package/scripts/lib/skill-health/join.mjs +181 -0
  436. package/scripts/lib/skill-health/score.mjs +123 -0
  437. package/scripts/lib/skill-invocations-schema.mjs +214 -0
  438. package/scripts/lib/skill-judge.mjs +348 -0
  439. package/scripts/lib/skill-judgments-schema.mjs +264 -0
  440. package/scripts/lib/slopcheck.mjs +501 -0
  441. package/scripts/lib/soul-resolve.mjs +118 -0
  442. package/scripts/lib/spiral-carryover.mjs +495 -0
  443. package/scripts/lib/state-md/body-sections.mjs +851 -0
  444. package/scripts/lib/state-md/frontmatter-mutators.mjs +453 -0
  445. package/scripts/lib/state-md/mission-status.mjs +247 -0
  446. package/scripts/lib/state-md/recommendations.mjs +57 -0
  447. package/scripts/lib/state-md/yaml-parser.mjs +234 -0
  448. package/scripts/lib/state-md-peer-guard.mjs +232 -0
  449. package/scripts/lib/state-md.mjs +53 -0
  450. package/scripts/lib/subagents-schema.mjs +309 -0
  451. package/scripts/lib/sunset/walker.mjs +1192 -0
  452. package/scripts/lib/test-runner/artifact-paths.mjs +94 -0
  453. package/scripts/lib/test-runner/fingerprint.mjs +33 -0
  454. package/scripts/lib/test-runner/issue-reconcile.mjs +770 -0
  455. package/scripts/lib/tmux-layout/layouts.mjs +224 -0
  456. package/scripts/lib/tmux-layout/telemetry-stats.mjs +100 -0
  457. package/scripts/lib/tmux-layout/telemetry.mjs +88 -0
  458. package/scripts/lib/tmux-layout/tmux-shell.mjs +82 -0
  459. package/scripts/lib/tmux-layout/vcs-detector.mjs +88 -0
  460. package/scripts/lib/validate/check-agents.mjs +457 -0
  461. package/scripts/lib/validate/check-codex-plugin.mjs +37 -0
  462. package/scripts/lib/validate/check-commands.mjs +148 -0
  463. package/scripts/lib/validate/check-component-paths.mjs +112 -0
  464. package/scripts/lib/validate/check-dead-bridge.mjs +180 -0
  465. package/scripts/lib/validate/check-hooks-symmetry.mjs +258 -0
  466. package/scripts/lib/validate/check-json-files.mjs +116 -0
  467. package/scripts/lib/validate/check-owner-leakage.mjs +1011 -0
  468. package/scripts/lib/validate/check-path-utils-canary.mjs +175 -0
  469. package/scripts/lib/validate/check-peekaboo-driver-canary.mjs +201 -0
  470. package/scripts/lib/validate/check-pi-package.mjs +110 -0
  471. package/scripts/lib/validate/check-pi-prompts.mjs +43 -0
  472. package/scripts/lib/validate/check-playwright-mcp-canary.mjs +154 -0
  473. package/scripts/lib/validate/check-plugin-json.mjs +96 -0
  474. package/scripts/lib/validate/check-plugin-monitors.mjs +206 -0
  475. package/scripts/lib/validate/check-plugin-schema.mjs +137 -0
  476. package/scripts/lib/validate/check-rules.mjs +143 -0
  477. package/scripts/lib/validate/check-session-plan-routing.mjs +154 -0
  478. package/scripts/lib/validate/check-test-fixture-shapes.mjs +280 -0
  479. package/scripts/lib/validate/check-unicode-safety.mjs +533 -0
  480. package/scripts/lib/validate/confidential-names.mjs +169 -0
  481. package/scripts/lib/validate/dead-bridge-corpus.mjs +141 -0
  482. package/scripts/lib/validate/dead-bridge-detectors.mjs +568 -0
  483. package/scripts/lib/validate/tier-inference.mjs +100 -0
  484. package/scripts/lib/validate-vendored-rules.mjs +519 -0
  485. package/scripts/lib/vault-archive.mjs +404 -0
  486. package/scripts/lib/vault-backfill/glab.mjs +164 -0
  487. package/scripts/lib/vault-backfill/manifest.mjs +75 -0
  488. package/scripts/lib/vault-backfill/template.mjs +130 -0
  489. package/scripts/lib/vault-consolidate-fs.mjs +331 -0
  490. package/scripts/lib/vault-migration-rules.mjs +155 -0
  491. package/scripts/lib/vault-mirror/auto-commit.mjs +203 -0
  492. package/scripts/lib/vault-mirror/namespace.mjs +152 -0
  493. package/scripts/lib/vault-mirror/process.mjs +567 -0
  494. package/scripts/lib/vault-mirror/pseudonym-map.mjs +164 -0
  495. package/scripts/lib/vault-mirror/render-learnings.mjs +201 -0
  496. package/scripts/lib/vault-mirror/render-sessions.mjs +367 -0
  497. package/scripts/lib/vault-mirror/render.mjs +8 -0
  498. package/scripts/lib/vault-mirror/utils.mjs +217 -0
  499. package/scripts/lib/vault-relocation-rules.mjs +555 -0
  500. package/scripts/lib/vault-repo-backfill.mjs +235 -0
  501. package/scripts/lib/vault-staleness-banner.mjs +142 -0
  502. package/scripts/lib/vault-status/board-writer.mjs +769 -0
  503. package/scripts/lib/vault-status/narrative-mirror.mjs +544 -0
  504. package/scripts/lib/vault-sync-baseline.mjs +152 -0
  505. package/scripts/lib/wave-context.mjs +29 -0
  506. package/scripts/lib/wave-executor/pool.mjs +248 -0
  507. package/scripts/lib/wave-resource-gate.mjs +204 -0
  508. package/scripts/lib/wave-sizing.mjs +75 -0
  509. package/scripts/lib/webhook-url.mjs +105 -0
  510. package/scripts/lib/workspace.mjs +198 -0
  511. package/scripts/lib/worktree/constants.mjs +35 -0
  512. package/scripts/lib/worktree/index.mjs +17 -0
  513. package/scripts/lib/worktree/lifecycle.mjs +287 -0
  514. package/scripts/lib/worktree/listing.mjs +118 -0
  515. package/scripts/lib/worktree/meta.mjs +64 -0
  516. package/scripts/lib/worktree-freshness.mjs +313 -0
  517. package/scripts/lib/worktree.mjs +15 -0
  518. package/scripts/lifecycle-sim-v6.mjs +347 -0
  519. package/scripts/lock-reaper.mjs +185 -0
  520. package/scripts/mcp-server.sh +241 -0
  521. package/scripts/measure-policy-cache-effectiveness.mjs +427 -0
  522. package/scripts/memory-propose.mjs +464 -0
  523. package/scripts/migrate-cold-start-seed.mjs +404 -0
  524. package/scripts/migrate-learnings-jsonl.mjs +189 -0
  525. package/scripts/migrate-legacy-learnings.sh +61 -0
  526. package/scripts/migrate-sessions-jsonl.mjs +448 -0
  527. package/scripts/migrate-subagents-jsonl.mjs +196 -0
  528. package/scripts/migrate-vault-paths.mjs +796 -0
  529. package/scripts/parse-config.mjs +149 -0
  530. package/scripts/pi-install.mjs +117 -0
  531. package/scripts/print-applicable-rules.mjs +247 -0
  532. package/scripts/promote-vault-strict.mjs +496 -0
  533. package/scripts/relocate-vault-corpus.mjs +1178 -0
  534. package/scripts/run-migrate-v2-cross-repo.mjs +385 -0
  535. package/scripts/run-quality-gate.mjs +216 -0
  536. package/scripts/spikes/h3-agent-teams/preflight.sh +53 -0
  537. package/scripts/spikes/h3-agent-teams/run-h3.sh +112 -0
  538. package/scripts/spikes/h3-agent-teams/setup.sh +137 -0
  539. package/scripts/spikes/h3-agent-teams/toggle.sh +38 -0
  540. package/scripts/sweep-expired-learnings.mjs +135 -0
  541. package/scripts/sync-vault-schema.mjs +376 -0
  542. package/scripts/tests/fixtures/fetch-baseline/sample-rule.md +8 -0
  543. package/scripts/tmux-layout.mjs +245 -0
  544. package/scripts/token-audit.sh +191 -0
  545. package/scripts/typecheck.mjs +42 -0
  546. package/scripts/upload-social-preview.mjs +316 -0
  547. package/scripts/validate-config.mjs +46 -0
  548. package/scripts/validate-plugin-manifests.mjs +163 -0
  549. package/scripts/validate-plugin.mjs +264 -0
  550. package/scripts/validate-wave-scope.mjs +289 -0
  551. package/scripts/vault-backfill.mjs +404 -0
  552. package/scripts/vault-consolidate.mjs +596 -0
  553. package/scripts/vault-integration-watcher.mjs +394 -0
  554. package/scripts/vault-mirror.mjs +430 -0
  555. package/skills/_shared/bootstrap-gate.md +111 -0
  556. package/skills/_shared/config-reading.md +226 -0
  557. package/skills/_shared/instruction-file-resolution.md +79 -0
  558. package/skills/_shared/model-selection.md +64 -0
  559. package/skills/_shared/monitor-patterns.md +300 -0
  560. package/skills/_shared/parallel-aware-auq.md +121 -0
  561. package/skills/_shared/parallel-aware-preamble.md +185 -0
  562. package/skills/_shared/platform-tools.md +96 -0
  563. package/skills/_shared/state-ownership.md +221 -0
  564. package/skills/architecture/DEEPENING.md +37 -0
  565. package/skills/architecture/INTERFACE-DESIGN.md +44 -0
  566. package/skills/architecture/LANGUAGE.md +53 -0
  567. package/skills/architecture/SKILL.md +92 -0
  568. package/skills/autopilot/SKILL.md +419 -0
  569. package/skills/bootstrap/SKILL.md +592 -0
  570. package/skills/bootstrap/STATE.md.template +24 -0
  571. package/skills/bootstrap/_shared-template.md +243 -0
  572. package/skills/bootstrap/deep-template.md +659 -0
  573. package/skills/bootstrap/fast-template.md +251 -0
  574. package/skills/bootstrap/intensity-heuristic.md +80 -0
  575. package/skills/bootstrap/public-fallback.md +342 -0
  576. package/skills/bootstrap/standard-template.md +736 -0
  577. package/skills/bootstrap/templates/agents/project-code-review.md +18 -0
  578. package/skills/bootstrap/templates/agents/project-discovery.md +18 -0
  579. package/skills/bootstrap/templates/agents/project-quality-gate.md +18 -0
  580. package/skills/brainstorm/SKILL.md +268 -0
  581. package/skills/brainstorm/soul.md +49 -0
  582. package/skills/claude-md-drift-check/SKILL.md +186 -0
  583. package/skills/claude-md-drift-check/checker.mjs +1380 -0
  584. package/skills/claude-md-drift-check/checker.sh +37 -0
  585. package/skills/claude-md-drift-check/package.json +16 -0
  586. package/skills/convergence-monitoring/README.md +39 -0
  587. package/skills/convergence-monitoring/SIGNALS.md +246 -0
  588. package/skills/convergence-monitoring/SKILL.md +285 -0
  589. package/skills/daily/SKILL.md +222 -0
  590. package/skills/daily/generate.sh +92 -0
  591. package/skills/daily/templates/daily.md.tpl +36 -0
  592. package/skills/debug/SKILL.md +188 -0
  593. package/skills/debug/soul.md +35 -0
  594. package/skills/discovery/SKILL.md +567 -0
  595. package/skills/discovery/issue-templates.md +237 -0
  596. package/skills/discovery/probes/docs-staleness.mjs +195 -0
  597. package/skills/discovery/probes/frontend-slop.mjs +186 -0
  598. package/skills/discovery/probes/ssot-code-diff.mjs +310 -0
  599. package/skills/discovery/probes/supply-chain-slopcheck.mjs +440 -0
  600. package/skills/discovery/probes/vault-narrative-staleness.mjs +355 -0
  601. package/skills/discovery/probes/vault-staleness.mjs +272 -0
  602. package/skills/discovery/probes-arch.md +252 -0
  603. package/skills/discovery/probes-audit.md +95 -0
  604. package/skills/discovery/probes-code.md +329 -0
  605. package/skills/discovery/probes-docs.md +76 -0
  606. package/skills/discovery/probes-feature.md +150 -0
  607. package/skills/discovery/probes-infra.md +138 -0
  608. package/skills/discovery/probes-intro.md +25 -0
  609. package/skills/discovery/probes-session.md +495 -0
  610. package/skills/discovery/probes-supply-chain.md +94 -0
  611. package/skills/discovery/probes-ui.md +147 -0
  612. package/skills/discovery/probes-vault.md +64 -0
  613. package/skills/discovery/slop-patterns.md +115 -0
  614. package/skills/dispatcher/SKILL.md +173 -0
  615. package/skills/docs-orchestrator/SKILL.md +362 -0
  616. package/skills/docs-orchestrator/audience-mapping.md +140 -0
  617. package/skills/domain-model/ADR-FORMAT.md +47 -0
  618. package/skills/domain-model/CONTEXT-FORMAT.md +77 -0
  619. package/skills/domain-model/SKILL.md +85 -0
  620. package/skills/ecosystem-health/SKILL.md +119 -0
  621. package/skills/ecosystem-health/wizard.md +193 -0
  622. package/skills/eval/SKILL.md +293 -0
  623. package/skills/eval/rubric-v1.md +218 -0
  624. package/skills/evolve/SKILL.md +546 -0
  625. package/skills/frontmatter-guard/SKILL.md +126 -0
  626. package/skills/gitlab-ops/SKILL.md +368 -0
  627. package/skills/gitlab-portfolio/SKILL.md +196 -0
  628. package/skills/grill/SKILL.md +185 -0
  629. package/skills/grill/soul.md +55 -0
  630. package/skills/hook-development/SKILL.md +413 -0
  631. package/skills/mcp-builder/SKILL.md +260 -0
  632. package/skills/memory-cleanup/SKILL.md +310 -0
  633. package/skills/mode-selector/SKILL.md +226 -0
  634. package/skills/peekaboo-driver/SKILL.md +237 -0
  635. package/skills/peekaboo-driver/soul.md +32 -0
  636. package/skills/persona-panel/SKILL.md +365 -0
  637. package/skills/persona-panel/persona-format.md +205 -0
  638. package/skills/persona-panel/presets/designer-lens.md +87 -0
  639. package/skills/persona-panel/presets/engineer-lens.md +88 -0
  640. package/skills/persona-panel/presets/pm-lens.md +86 -0
  641. package/skills/plan/SKILL.md +496 -0
  642. package/skills/plan/mode-feature.md +141 -0
  643. package/skills/plan/mode-new.md +297 -0
  644. package/skills/plan/mode-retro.md +271 -0
  645. package/skills/plan/prd-feature-template.md +132 -0
  646. package/skills/plan/prd-full-template.md +151 -0
  647. package/skills/plan/prd-reviewer-prompt.md +103 -0
  648. package/skills/plan/retro-template.md +75 -0
  649. package/skills/plan/soul.md +62 -0
  650. package/skills/playwright-driver/SKILL.md +226 -0
  651. package/skills/playwright-driver/soul.md +30 -0
  652. package/skills/quality-gates/SKILL.md +212 -0
  653. package/skills/reconcile/SKILL.md +324 -0
  654. package/skills/repo-audit/SKILL.md +272 -0
  655. package/skills/session-end/SKILL.md +1044 -0
  656. package/skills/session-end/discovery-scan.md +37 -0
  657. package/skills/session-end/drift-operations.md +97 -0
  658. package/skills/session-end/learning-patterns.md +78 -0
  659. package/skills/session-end/metrics-collection.md +175 -0
  660. package/skills/session-end/phase-3-2-docs-verification.md +148 -0
  661. package/skills/session-end/phase-3-6-tail.md +344 -0
  662. package/skills/session-end/phase-3-7a-recommendations.md +86 -0
  663. package/skills/session-end/plan-verification.md +288 -0
  664. package/skills/session-end/session-metrics-write.md +223 -0
  665. package/skills/session-end/vault-operations.md +50 -0
  666. package/skills/session-end/verification-checklist.md +20 -0
  667. package/skills/session-plan/SKILL.md +554 -0
  668. package/skills/session-plan/wave-template.md +37 -0
  669. package/skills/session-start/SKILL.md +1043 -0
  670. package/skills/session-start/phase-2-5-docs-planning.md +119 -0
  671. package/skills/session-start/phase-4-5-resource-health.md +49 -0
  672. package/skills/session-start/phase-7-1-premise-check.md +47 -0
  673. package/skills/session-start/phase-7-5-mode-selector.md +237 -0
  674. package/skills/session-start/phase-8-5-express-path.md +61 -0
  675. package/skills/session-start/presentation-format.md +81 -0
  676. package/skills/session-start/soul.md +57 -0
  677. package/skills/skill-creator/SKILL.md +168 -0
  678. package/skills/spinout/SKILL.md +76 -0
  679. package/skills/sunset-review/SKILL.md +96 -0
  680. package/skills/test-runner/SKILL.md +362 -0
  681. package/skills/test-runner/rubric-v1.md +388 -0
  682. package/skills/test-runner/soul.md +46 -0
  683. package/skills/tmux-layout/SKILL.md +104 -0
  684. package/skills/ubiquitous-language/SKILL.md +97 -0
  685. package/skills/using-orchestrator/SKILL.md +144 -0
  686. package/skills/vault-mirror/SKILL.md +234 -0
  687. package/skills/vault-sync/SKILL.md +319 -0
  688. package/skills/vault-sync/package-lock.json +40 -0
  689. package/skills/vault-sync/package.json +11 -0
  690. package/skills/vault-sync/tests/fixtures/archive-test-vault/90-archive/bad-archived.md +8 -0
  691. package/skills/vault-sync/tests/fixtures/archive-test-vault/_meta/.gitkeep +0 -0
  692. package/skills/vault-sync/tests/fixtures/archive-test-vault/live-note.md +8 -0
  693. package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/_meta/.gitkeep +0 -0
  694. package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/bad-type.md +8 -0
  695. package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/good-note.md +8 -0
  696. package/skills/vault-sync/tests/fixtures/clean-vault/.obsidian/config.md +8 -0
  697. package/skills/vault-sync/tests/fixtures/clean-vault/01-projects/foo/projects-baseline.md +10 -0
  698. package/skills/vault-sync/tests/fixtures/clean-vault/03-daily/daily-2026-04-13.md +8 -0
  699. package/skills/vault-sync/tests/fixtures/clean-vault/README.md +3 -0
  700. package/skills/vault-sync/tests/fixtures/clean-vault/hello-world.md +11 -0
  701. package/skills/vault-sync/tests/fixtures/dangling-link-vault/_meta/.gitkeep +0 -0
  702. package/skills/vault-sync/tests/fixtures/dangling-link-vault/has-dangling.md +9 -0
  703. package/skills/vault-sync/tests/fixtures/dangling-link-vault/real-target.md +8 -0
  704. package/skills/vault-sync/tests/fixtures/empty-vault/_meta/.gitkeep +0 -0
  705. package/skills/vault-sync/tests/fixtures/missing-field-vault/_meta/.gitkeep +0 -0
  706. package/skills/vault-sync/tests/fixtures/missing-field-vault/missing-id.md +7 -0
  707. package/skills/vault-sync/tests/fixtures/nested-tag-vault/03-daily/daily-2026-04-13.md +9 -0
  708. package/skills/vault-sync/tests/fixtures/nested-tag-vault/_meta/.gitkeep +0 -0
  709. package/skills/vault-sync/tests/fixtures/nested-tag-vault/nested-tags-note.md +11 -0
  710. package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/README.md +3 -0
  711. package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/_MOC.md +3 -0
  712. package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/_meta/.gitkeep +0 -0
  713. package/skills/vault-sync/tests/fixtures/with-moc-vault/_MOC.md +11 -0
  714. package/skills/vault-sync/tests/fixtures/with-moc-vault/_meta/.gitkeep +0 -0
  715. package/skills/vault-sync/tests/fixtures/with-moc-vault/hello-world.md +11 -0
  716. package/skills/vault-sync/tests/schema-drift.test.mjs +133 -0
  717. package/skills/vault-sync/validator.mjs +658 -0
  718. package/skills/vault-sync/validator.sh +55 -0
  719. package/skills/wave-executor/SKILL.md +496 -0
  720. package/skills/wave-executor/circuit-breaker.md +169 -0
  721. package/skills/wave-executor/wave-loop.md +1043 -0
  722. package/skills/write-executable-plan/SKILL.md +237 -0
  723. package/skills/write-executable-plan/plan-template.md +154 -0
  724. package/templates/_minimal/CLAUDE.md.tmpl +41 -0
  725. package/templates/_minimal/README.md.tmpl +15 -0
  726. package/templates/_minimal/gitignore.tmpl +47 -0
  727. package/templates/_shared/harte-regeln.md +16 -0
  728. package/templates/_shared/loop.md +90 -0
  729. package/templates/_shared/rules/parallel-sessions.md +77 -0
  730. package/templates/nextjs-minimal/README.md +30 -0
  731. package/templates/nextjs-minimal/app/layout.tsx +18 -0
  732. package/templates/nextjs-minimal/app/page.tsx +7 -0
  733. package/templates/nextjs-minimal/eslint.config.mjs +16 -0
  734. package/templates/nextjs-minimal/next.config.mjs +4 -0
  735. package/templates/nextjs-minimal/package.json +27 -0
  736. package/templates/nextjs-minimal/tsconfig.json +23 -0
  737. package/templates/node-minimal/README.md +33 -0
  738. package/templates/node-minimal/eslint.config.mjs +10 -0
  739. package/templates/node-minimal/package.json +21 -0
  740. package/templates/node-minimal/src/index.ts +1 -0
  741. package/templates/node-minimal/tests/sanity.test.ts +5 -0
  742. package/templates/node-minimal/tsconfig.json +17 -0
  743. package/templates/personas/README.md +150 -0
  744. package/templates/personas/accounting-compliance.v1.md +120 -0
  745. package/templates/personas/accounting-tax-advisor.v1.md +116 -0
  746. package/templates/personas/buyer-p1-cto.v1.md +125 -0
  747. package/templates/personas/buyer-p2-kanzlei.v1.md +134 -0
  748. package/templates/personas/buyer-p3-build.v1.md +130 -0
  749. package/templates/personas/buyer-p4-tech-veto.v1.md +130 -0
  750. package/templates/personas/buyer-p5-solo.v1.md +132 -0
  751. package/templates/personas/buyer-p6-ld.v1.md +130 -0
  752. package/templates/personas/klima-ai-expert.v1.md +114 -0
  753. package/templates/personas/klima-physicist.v1.md +117 -0
  754. package/templates/python-uv/README.md +28 -0
  755. package/templates/python-uv/pyproject.toml +32 -0
  756. package/templates/python-uv/src/__PROJECT_NAME__/__init__.py +0 -0
  757. package/templates/python-uv/src/__PROJECT_NAME__/main.py +6 -0
  758. package/templates/python-uv/tests/test_sanity.py +2 -0
  759. package/templates/static-html/README.md +19 -0
  760. package/templates/static-html/index.html +15 -0
  761. package/templates/static-html/script.js +1 -0
  762. package/templates/static-html/styles.css +26 -0
@@ -0,0 +1,448 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * migrate-sessions-jsonl.mjs — migrate old sessions.jsonl entries to the
4
+ * canonical schema_version=2 shape (bumped 1 -> 2 via #372; validateSession
5
+ * stamps whatever CURRENT_SESSION_SCHEMA_VERSION currently resolves to).
6
+ *
7
+ * Issue #304: 73% of sessions.jsonl records were mirror-invalid because two
8
+ * incompatible writer formats coexisted:
9
+ *
10
+ * OLD (pre-v3): agents_dispatched / agents_complete / agents_partial /
11
+ * agents_failed scalars + waves_completed scalar (no waves[])
12
+ * NEW (v3+): agent_summary object + waves[] array + total_agents +
13
+ * total_files_changed
14
+ *
15
+ * This script is the TARGETED migration path (single-shape → canonical).
16
+ * For full-file backfill including deprecation tagging, use
17
+ * `scripts/backfill-sessions.mjs` instead.
18
+ *
19
+ * Usage:
20
+ * node scripts/migrate-sessions-jsonl.mjs [--file PATH]
21
+ * node scripts/migrate-sessions-jsonl.mjs [--file PATH] --apply
22
+ *
23
+ * Modes:
24
+ * (default) --dry-run: print a JSON report; do not write any file
25
+ * --apply : write the migrated file atomically (tmp + rename)
26
+ * with a .bak-<ISO> backup of the original
27
+ *
28
+ * Exit codes:
29
+ * 0 — success (dry-run report or apply completed)
30
+ * 1 — I/O error or file not found
31
+ * 2 — usage error
32
+ *
33
+ * Idempotency: already-canonical (schema_version=2) records are left byte-
34
+ * identical. Running --apply twice produces the same result.
35
+ *
36
+ * Output (stdout, one JSON line):
37
+ * {"mode":"dry-run|apply","file":"...","total":N,"migrated":N,
38
+ * "already_canonical":N,"unmappable":N,"parse_errors":N,"backup":"<path>|null"}
39
+ */
40
+
41
+ import { readFileSync, writeFileSync, renameSync, copyFileSync, existsSync } from 'node:fs';
42
+ import { join, dirname, basename } from 'node:path';
43
+ import { validateSession, normalizeSession, ValidationError } from './lib/session-schema.mjs';
44
+
45
+ const DEFAULT_FILE = '.orchestrator/metrics/sessions.jsonl';
46
+
47
+ // ---------------------------------------------------------------------------
48
+ // Migration logic: old → new shape
49
+ // ---------------------------------------------------------------------------
50
+
51
+ /**
52
+ * Determine if an entry uses the old scalar-fields shape:
53
+ * - Has flat agent scalar fields (agents_dispatched / agents_complete / etc.)
54
+ * but lacks agent_summary object
55
+ * - Has waves_completed or waves_total scalar but lacks waves array
56
+ */
57
+ export function isOldShape(entry) {
58
+ if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) return false;
59
+ const hasOldAgentScalars =
60
+ !('agent_summary' in entry) &&
61
+ (typeof entry.agents_dispatched === 'number' ||
62
+ typeof entry.agents_complete === 'number' ||
63
+ typeof entry.agents_partial === 'number' ||
64
+ typeof entry.agents_failed === 'number');
65
+ const hasOldWaveScalar =
66
+ !Array.isArray(entry.waves) &&
67
+ (typeof entry.waves_completed === 'number' || typeof entry.waves_total === 'number');
68
+ return hasOldAgentScalars || hasOldWaveScalar;
69
+ }
70
+
71
+ /**
72
+ * Map an old-shape entry to the canonical schema_version=2 shape.
73
+ *
74
+ * Mapping rules:
75
+ * total_agents = agents_complete + agents_partial + agents_failed
76
+ * (falls back to agents_dispatched, then 0)
77
+ * agent_summary = { complete, partial, failed, spiral }
78
+ * (agents_spiral → spiral; defaults to 0 if absent)
79
+ * waves = [] (empty — scalar counts are not reconstructible
80
+ * into individual wave objects without additional data)
81
+ * total_waves = waves_completed ?? waves_total ?? total_waves ?? 0
82
+ * total_files_changed= files_changed ?? total_files_changed ?? 0
83
+ * duration_seconds = duration_min * 60 if duration_min present and
84
+ * duration_seconds absent
85
+ *
86
+ * All original fields are PRESERVED alongside the new canonical fields so
87
+ * no information is lost (additive migration). schema_version is stamped to 2.
88
+ *
89
+ * @param {object} entry — raw old-shape entry
90
+ * @returns {object} migrated entry (new object; input not mutated)
91
+ */
92
+ export function migrateEntry(entry) {
93
+ if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) {
94
+ throw new TypeError('migrateEntry: entry must be a plain object');
95
+ }
96
+
97
+ const next = { ...entry };
98
+
99
+ // Normalize safe key aliases (head_ref → branch, type → session_type, etc.)
100
+ const normalized = normalizeSession(next);
101
+ // normalizeSession may stamp schema_version:0 for legacy records — remove so
102
+ // validateSession can stamp the canonical 1.
103
+ const merged = { ...normalized };
104
+ if (merged.schema_version === 0 && !('schema_version' in entry)) {
105
+ delete merged.schema_version;
106
+ }
107
+
108
+ // duration_min / duration_minutes → duration_seconds
109
+ if (!('duration_seconds' in merged)) {
110
+ if (typeof merged.duration_min === 'number' && merged.duration_min >= 0) {
111
+ merged.duration_seconds = merged.duration_min * 60;
112
+ } else if (typeof merged.duration_minutes === 'number' && merged.duration_minutes >= 0) {
113
+ merged.duration_seconds = merged.duration_minutes * 60;
114
+ }
115
+ }
116
+
117
+ // waves — must be an array; scalars cannot be reconstructed into wave objects.
118
+ // Normalize early so wave-based derivations below can use merged.waves safely.
119
+ if (!Array.isArray(merged.waves)) {
120
+ merged.waves = [];
121
+ }
122
+
123
+ // Normalize waves[].wave field: if missing, assign index+1.
124
+ // Also alias legacy waves[].name -> role when role is absent/empty (#745):
125
+ // no producer writes `name` today, but hand-authored/legacy records did.
126
+ // ONLY fills role when it's missing — never overwrites a present canonical
127
+ // role. `name` is kept alongside (harmless, no consumer reads it) rather
128
+ // than deleted, keeping this migration additive like the rest of the file.
129
+ merged.waves = merged.waves.map((w, i) => {
130
+ if (typeof w !== 'object' || w === null) return w;
131
+ let next = w;
132
+ const hasRole = typeof next.role === 'string' && next.role.length > 0;
133
+ if (!hasRole && typeof next.name === 'string' && next.name.length > 0) {
134
+ next = { ...next, role: next.name };
135
+ }
136
+ if (typeof next.wave !== 'number' || next.wave < 1) {
137
+ next = { ...next, wave: i + 1 };
138
+ }
139
+ return next;
140
+ });
141
+
142
+ // Helper: resolve wave agent count from varied types
143
+ // null → 0, number → that, array → array.length
144
+ function waveAgentCount(agents) {
145
+ if (agents === null || agents === undefined) return 0;
146
+ if (typeof agents === 'number') return agents;
147
+ if (Array.isArray(agents)) return agents.length;
148
+ return 0;
149
+ }
150
+
151
+ // Helper: classify wave status into complete/partial/failed
152
+ function waveStatus(status) {
153
+ if (status === 'done' || status === 'complete' || status === 'complete_needs_polish') {
154
+ return 'complete';
155
+ }
156
+ if (status === 'partial') return 'partial';
157
+ if (status === 'fail' || status === 'failed') return 'failed';
158
+ return null; // unrecognized
159
+ }
160
+
161
+ // agent_summary — reconstruct when absent or fill missing fields when partial.
162
+ if (!('agent_summary' in merged)) {
163
+ // v3 shape: synthesize from waves[].agents + waves[].status
164
+ let complete = 0;
165
+ let partial = 0;
166
+ let failed = 0;
167
+ for (const w of merged.waves) {
168
+ if (typeof w !== 'object' || w === null) continue;
169
+ const count = waveAgentCount(w.agents);
170
+ const cls = waveStatus(w.status);
171
+ if (cls === 'complete') complete += count;
172
+ else if (cls === 'partial') partial += count;
173
+ else if (cls === 'failed') failed += count;
174
+ }
175
+ // Fall back to old scalar fields if waves yielded nothing
176
+ if (complete === 0 && partial === 0 && failed === 0) {
177
+ complete = typeof merged.agents_complete === 'number' ? merged.agents_complete : 0;
178
+ partial = typeof merged.agents_partial === 'number' ? merged.agents_partial : 0;
179
+ failed = typeof merged.agents_failed === 'number' ? merged.agents_failed : 0;
180
+ }
181
+ const spiral = typeof merged.agents_spiral === 'number' ? merged.agents_spiral : 0;
182
+ merged.agent_summary = { complete, partial, failed, spiral };
183
+ } else if (typeof merged.agent_summary === 'object' && merged.agent_summary !== null) {
184
+ // Partial agent_summary (e.g., only {complete}) — fill missing keys with 0
185
+ const s = merged.agent_summary;
186
+ merged.agent_summary = {
187
+ complete: typeof s.complete === 'number' ? s.complete : 0,
188
+ partial: typeof s.partial === 'number' ? s.partial : 0,
189
+ failed: typeof s.failed === 'number' ? s.failed : 0,
190
+ spiral: typeof s.spiral === 'number' ? s.spiral : 0,
191
+ };
192
+ }
193
+
194
+ // total_agents — derive from sum of wave agent counts (v3) or old scalar fields
195
+ if (!('total_agents' in merged)) {
196
+ if (typeof merged.agents_dispatched === 'number') {
197
+ merged.total_agents = merged.agents_dispatched;
198
+ } else if (merged.waves.length > 0) {
199
+ // Sum wave agent counts
200
+ merged.total_agents = merged.waves.reduce((sum, w) => {
201
+ if (typeof w !== 'object' || w === null) return sum;
202
+ return sum + waveAgentCount(w.agents);
203
+ }, 0);
204
+ } else {
205
+ const s = merged.agent_summary;
206
+ merged.total_agents = (s.complete ?? 0) + (s.partial ?? 0) + (s.failed ?? 0) + (s.spiral ?? 0);
207
+ }
208
+ }
209
+
210
+ // total_files_changed — derive from waves[].files arrays (unique paths) or scalar
211
+ if (!('total_files_changed' in merged)) {
212
+ // Check if any wave has files as an array
213
+ const hasFileArrays = merged.waves.some(
214
+ (w) => typeof w === 'object' && w !== null && Array.isArray(w.files)
215
+ );
216
+ if (hasFileArrays) {
217
+ const uniquePaths = new Set();
218
+ for (const w of merged.waves) {
219
+ if (typeof w !== 'object' || w === null || !Array.isArray(w.files)) continue;
220
+ for (const f of w.files) uniquePaths.add(f);
221
+ }
222
+ merged.total_files_changed = uniquePaths.size;
223
+ } else if (typeof merged.files_changed === 'number') {
224
+ merged.total_files_changed = merged.files_changed;
225
+ } else {
226
+ merged.total_files_changed = 0;
227
+ }
228
+ }
229
+
230
+ // total_waves — prefer: total_waves > actual_waves > planned_waves > waves.length > 0
231
+ if (!('total_waves' in merged)) {
232
+ if (typeof merged.actual_waves === 'number') {
233
+ merged.total_waves = merged.actual_waves;
234
+ } else if (typeof merged.planned_waves === 'number') {
235
+ merged.total_waves = merged.planned_waves;
236
+ } else if (merged.waves.length > 0) {
237
+ merged.total_waves = merged.waves.length;
238
+ } else if (typeof merged.waves_completed === 'number') {
239
+ merged.total_waves = merged.waves_completed;
240
+ } else if (typeof merged.waves_total === 'number') {
241
+ merged.total_waves = merged.waves_total;
242
+ } else {
243
+ merged.total_waves = 0;
244
+ }
245
+ }
246
+
247
+ return merged;
248
+ }
249
+
250
+ // ---------------------------------------------------------------------------
251
+ // v1 → v2 migration skeleton (gated on #372)
252
+ // ---------------------------------------------------------------------------
253
+
254
+ /**
255
+ * v1 → v2 migration skeleton. Gated on #372 schema-version v2 bump.
256
+ * Currently identity (returns entry unchanged). When the v2 bump lands,
257
+ * this function will normalize Phase D fields (blocked_by_issue,
258
+ * aborted_by_cohort, spiral_recovery_count) into the canonical shape.
259
+ *
260
+ * Eligible after 3 historical-entries CI runs green, currently 3/3 post
261
+ * pipeline 3839.
262
+ *
263
+ * @param {object} entry — a session record
264
+ * @returns {object} the same entry, unmodified for now
265
+ */
266
+ export function migrateV1ToV2(entry) {
267
+ // SKELETON: identity migration. Real logic deferred to follow-up after #372.
268
+ return entry;
269
+ }
270
+
271
+ // ---------------------------------------------------------------------------
272
+ // Outcome classification per line
273
+ // ---------------------------------------------------------------------------
274
+
275
+ /**
276
+ * @typedef {'already_canonical'|'migrated'|'unmappable'|'parse_error'} LineOutcome
277
+ */
278
+
279
+ /**
280
+ * Process one parsed line. Returns the outcome and the (possibly transformed)
281
+ * entry ready to serialize back to disk.
282
+ *
283
+ * @param {object} raw — parsed JSON object
284
+ * @returns {{ outcome: LineOutcome, entry: object, reason?: string }}
285
+ */
286
+ function processEntry(raw) {
287
+ // Already canonical: validateSession passes on the raw entry as-is.
288
+ try {
289
+ const validated = validateSession(raw);
290
+ // Double check: only truly already-canonical if serialized form matches
291
+ if (JSON.stringify(validated) === JSON.stringify(raw)) {
292
+ return { outcome: 'already_canonical', entry: raw };
293
+ }
294
+ // schema_version stamp added — still valid, mark as migrated.
295
+ return { outcome: 'migrated', entry: validated };
296
+ } catch {
297
+ // Falls through to migration attempt.
298
+ }
299
+
300
+ // Attempt migration
301
+ let migrated;
302
+ try {
303
+ migrated = migrateEntry(raw);
304
+ } catch (err) {
305
+ return { outcome: 'unmappable', entry: raw, reason: `migrateEntry threw: ${err.message}` };
306
+ }
307
+
308
+ // Validate the migrated result
309
+ try {
310
+ const validated = validateSession(migrated);
311
+ return { outcome: 'migrated', entry: validated };
312
+ } catch (err) {
313
+ if (err instanceof ValidationError) {
314
+ return {
315
+ outcome: 'unmappable',
316
+ entry: { ...raw, _migration_failed: true, _migration_reason: err.message },
317
+ reason: err.message,
318
+ };
319
+ }
320
+ throw err;
321
+ }
322
+ }
323
+
324
+ // ---------------------------------------------------------------------------
325
+ // CLI
326
+ // ---------------------------------------------------------------------------
327
+
328
+ function parseArgs(argv) {
329
+ const args = { file: DEFAULT_FILE, apply: false };
330
+ for (let i = 0; i < argv.length; i++) {
331
+ const a = argv[i];
332
+ if (a === '--file') {
333
+ args.file = argv[++i];
334
+ } else if (a === '--apply') {
335
+ args.apply = true;
336
+ } else if (a === '--dry-run') {
337
+ args.apply = false;
338
+ } else if (a === '--help' || a === '-h') {
339
+ process.stdout.write(
340
+ 'Usage: node scripts/migrate-sessions-jsonl.mjs [--file PATH] [--apply]\n' +
341
+ '\n' +
342
+ 'Migrate old sessions.jsonl entries (agents_dispatched/waves_completed shape)\n' +
343
+ 'to the canonical schema_version=2 shape (agent_summary/waves[]/total_agents).\n' +
344
+ '\n' +
345
+ 'Options:\n' +
346
+ ' --file PATH target JSONL file (default: .orchestrator/metrics/sessions.jsonl)\n' +
347
+ ' --apply write migrated file atomically (creates .bak-<ISO> backup)\n' +
348
+ ' --dry-run report only, do not write (default)\n' +
349
+ '\n' +
350
+ 'Exit codes:\n' +
351
+ ' 0 — success\n' +
352
+ ' 1 — I/O error\n' +
353
+ ' 2 — usage error\n'
354
+ );
355
+ process.exit(0);
356
+ } else {
357
+ process.stderr.write(`migrate-sessions-jsonl: unknown argument: ${a}\n`);
358
+ process.exit(2);
359
+ }
360
+ }
361
+ return args;
362
+ }
363
+
364
+ async function main() {
365
+ const args = parseArgs(process.argv.slice(2));
366
+
367
+ if (!existsSync(args.file)) {
368
+ process.stderr.write(`migrate-sessions-jsonl: file not found: ${args.file}\n`);
369
+ process.exit(1);
370
+ }
371
+
372
+ let rawLines;
373
+ try {
374
+ rawLines = readFileSync(args.file, 'utf8')
375
+ .split('\n')
376
+ .filter((l) => l.trim().length > 0);
377
+ } catch (err) {
378
+ process.stderr.write(`migrate-sessions-jsonl: read failed: ${err.message}\n`);
379
+ process.exit(1);
380
+ }
381
+
382
+ const counts = { already_canonical: 0, migrated: 0, unmappable: 0, parse_errors: 0 };
383
+ const outputLines = [];
384
+ const detail = [];
385
+
386
+ for (let i = 0; i < rawLines.length; i++) {
387
+ const lineNum = i + 1;
388
+ let raw;
389
+ try {
390
+ raw = JSON.parse(rawLines[i]);
391
+ } catch (err) {
392
+ counts.parse_errors++;
393
+ detail.push({ line: lineNum, outcome: 'parse_error', reason: err.message });
394
+ outputLines.push(rawLines[i]); // preserve unparseable lines verbatim
395
+ continue;
396
+ }
397
+
398
+ const { outcome, entry, reason } = processEntry(raw);
399
+ counts[outcome]++;
400
+ detail.push({ line: lineNum, outcome, session_id: raw.session_id ?? null, reason });
401
+ outputLines.push(JSON.stringify(entry));
402
+ }
403
+
404
+ const summary = {
405
+ mode: args.apply ? 'apply' : 'dry-run',
406
+ file: args.file,
407
+ total: rawLines.length,
408
+ already_canonical: counts.already_canonical,
409
+ migrated: counts.migrated,
410
+ unmappable: counts.unmappable,
411
+ parse_errors: counts.parse_errors,
412
+ backup: null,
413
+ };
414
+
415
+ if (!args.apply) {
416
+ process.stdout.write(JSON.stringify(summary) + '\n');
417
+ process.stdout.write(JSON.stringify({ detail }) + '\n');
418
+ return;
419
+ }
420
+
421
+ // Atomic write: backup → tmp → rename
422
+ const iso = new Date().toISOString().replace(/[:.]/g, '-');
423
+ const backupPath = `${args.file}.bak-${iso}`;
424
+ const tmpPath = join(dirname(args.file), `.${basename(args.file)}.migrate-tmp-${process.pid}`);
425
+ try {
426
+ copyFileSync(args.file, backupPath);
427
+ writeFileSync(tmpPath, outputLines.join('\n') + '\n', 'utf8');
428
+ renameSync(tmpPath, args.file);
429
+ summary.backup = backupPath;
430
+ } catch (err) {
431
+ const hint = existsSync(backupPath)
432
+ ? `Canonical file intact; backup at ${backupPath}.`
433
+ : 'Backup not created.';
434
+ process.stderr.write(`migrate-sessions-jsonl: write failed: ${err.message}. ${hint}\n`);
435
+ process.exit(1);
436
+ }
437
+
438
+ process.stdout.write(JSON.stringify(summary) + '\n');
439
+ }
440
+
441
+ // Run main() only when this file is invoked directly as a CLI, not when imported.
442
+ // Prevents process.exit during test-time imports (#368).
443
+ if (import.meta.url === `file://${process.argv[1]}`) {
444
+ main().catch((err) => {
445
+ process.stderr.write(`migrate-sessions-jsonl: unexpected error: ${err?.stack ?? err}\n`);
446
+ process.exit(2);
447
+ });
448
+ }
@@ -0,0 +1,196 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * migrate-subagents-jsonl.mjs — one-shot migration helper for subagents.jsonl.
4
+ *
5
+ * Mirrors migrate-learnings-jsonl.mjs structure. Applies the migrate /
6
+ * normalize / validate pipeline from subagents-schema.mjs to every record.
7
+ *
8
+ * For schema_version 1 (current), migrateLegacySubagent() is a no-op that
9
+ * only stamps a missing schema_version. The script is structurally complete
10
+ * and produces a 1:1 pass-through — ready for future schema bumps without
11
+ * code changes.
12
+ *
13
+ * Usage:
14
+ * node scripts/migrate-subagents-jsonl.mjs [--source <path>] [--dry-run] [--apply]
15
+ *
16
+ * Flags:
17
+ * --source <path> Path to subagents.jsonl
18
+ * (default: .orchestrator/metrics/subagents.jsonl)
19
+ * --dry-run Preview changes without writing (DEFAULT)
20
+ * --apply Write migrated records back to the file
21
+ *
22
+ * Exit codes:
23
+ * 0 Success (including no-op if everything is already canonical)
24
+ * 1 Input/validation error (or --apply had failed-validation records)
25
+ * 2 I/O error
26
+ *
27
+ * Idempotent: running --apply a second time produces no further changes.
28
+ *
29
+ * Output (stdout — one JSON object per line):
30
+ * {"action":"migrated"|"already-canonical"|"failed-validation","id":"...","changes":[...]}
31
+ *
32
+ * Summary line (stderr):
33
+ * migrate-subagents: N migrated, M already-canonical, K failed-validation [dry-run|applied]
34
+ */
35
+
36
+ import { existsSync, readFileSync, writeFileSync, renameSync, mkdirSync } from 'node:fs';
37
+ import { dirname } from 'node:path';
38
+ import {
39
+ migrateLegacySubagent,
40
+ normalizeSubagent,
41
+ validateSubagent,
42
+ ValidationError,
43
+ } from './lib/subagents-schema.mjs';
44
+
45
+ // ---------------------------------------------------------------------------
46
+ // Arg parsing
47
+ // ---------------------------------------------------------------------------
48
+
49
+ const args = process.argv.slice(2);
50
+ const helpFlag = args.includes('--help') || args.includes('-h');
51
+ if (helpFlag) {
52
+ process.stdout.write(`Usage: migrate-subagents-jsonl.mjs [--source <path>] [--dry-run] [--apply]
53
+
54
+ Options:
55
+ --source <path> Path to subagents.jsonl
56
+ (default: .orchestrator/metrics/subagents.jsonl)
57
+ --dry-run Preview changes without writing (DEFAULT)
58
+ --apply Write migrated records back to the file
59
+
60
+ Output (stdout — one JSON object per line):
61
+ {"action":"migrated"|"already-canonical"|"failed-validation","id":"...","changes":[...]}
62
+
63
+ Exit codes: 0 success 1 input/validation error 2 I/O error
64
+ `);
65
+ process.exit(0);
66
+ }
67
+
68
+ const applyFlag = args.includes('--apply');
69
+ const dryRun = !applyFlag; // default is --dry-run
70
+
71
+ const sourceIdx = args.indexOf('--source');
72
+ const sourcePath =
73
+ sourceIdx !== -1 && args[sourceIdx + 1]
74
+ ? args[sourceIdx + 1]
75
+ : '.orchestrator/metrics/subagents.jsonl';
76
+
77
+ // ---------------------------------------------------------------------------
78
+ // Load
79
+ // ---------------------------------------------------------------------------
80
+
81
+ if (!existsSync(sourcePath)) {
82
+ process.stderr.write(`migrate-subagents: source file not found: ${sourcePath}\n`);
83
+ process.exit(1);
84
+ }
85
+
86
+ let raw;
87
+ try {
88
+ raw = readFileSync(sourcePath, 'utf8');
89
+ } catch (err) {
90
+ process.stderr.write(`migrate-subagents: failed to read ${sourcePath}: ${err.message}\n`);
91
+ process.exit(2);
92
+ }
93
+
94
+ const lines = raw.split('\n').filter((l) => l.trim().length > 0);
95
+
96
+ // ---------------------------------------------------------------------------
97
+ // Migrate
98
+ // ---------------------------------------------------------------------------
99
+
100
+ let countMigrated = 0;
101
+ let countCanonical = 0;
102
+ let countFailedValidation = 0;
103
+ let countMalformed = 0;
104
+
105
+ const outputLines = [];
106
+
107
+ for (const line of lines) {
108
+ let parsed;
109
+ try {
110
+ parsed = JSON.parse(line);
111
+ } catch {
112
+ countMalformed++;
113
+ process.stderr.write(
114
+ `migrate-subagents: WARN skipping malformed JSON line: ${line.slice(0, 80)}\n`
115
+ );
116
+ // Preserve the original malformed line as-is (do not discard data).
117
+ outputLines.push(line);
118
+ continue;
119
+ }
120
+
121
+ // Detect which fields would be stamped by migrateLegacySubagent.
122
+ const changes = [];
123
+ if (parsed.schema_version === undefined || parsed.schema_version === null) {
124
+ changes.push('schema_version:1');
125
+ }
126
+
127
+ const migrated = migrateLegacySubagent(parsed);
128
+ const normalized = normalizeSubagent(migrated);
129
+
130
+ let validated;
131
+ try {
132
+ validated = validateSubagent(normalized);
133
+ } catch (err) {
134
+ countFailedValidation++;
135
+ const reason = err instanceof ValidationError ? err.message : String(err);
136
+ const id = parsed.agent_id ?? null;
137
+ process.stderr.write(
138
+ `migrate-subagents: WARN record agent_id=${id ?? '<no agent_id>'} still fails validation` +
139
+ ` after migration: ${reason}\n`
140
+ );
141
+ // Preserve original line — do not destroy unmigratable records.
142
+ outputLines.push(line);
143
+ process.stdout.write(
144
+ JSON.stringify({ action: 'failed-validation', id, reason, changes }) + '\n'
145
+ );
146
+ continue;
147
+ }
148
+
149
+ if (changes.length === 0) {
150
+ countCanonical++;
151
+ outputLines.push(JSON.stringify(validated));
152
+ process.stdout.write(
153
+ JSON.stringify({ action: 'already-canonical', id: validated.agent_id }) + '\n'
154
+ );
155
+ } else {
156
+ countMigrated++;
157
+ outputLines.push(JSON.stringify(validated));
158
+ process.stdout.write(
159
+ JSON.stringify({ action: 'migrated', id: validated.agent_id, changes }) + '\n'
160
+ );
161
+ }
162
+ }
163
+
164
+ // ---------------------------------------------------------------------------
165
+ // Write (--apply only)
166
+ // ---------------------------------------------------------------------------
167
+
168
+ const modeLabel = dryRun ? 'dry-run' : 'applied';
169
+
170
+ if (!dryRun) {
171
+ const body = outputLines.join('\n') + '\n';
172
+ const tmp = `${sourcePath}.migrate-tmp-${process.pid}-${Date.now()}`;
173
+ try {
174
+ mkdirSync(dirname(sourcePath), { recursive: true });
175
+ writeFileSync(tmp, body, 'utf8');
176
+ renameSync(tmp, sourcePath);
177
+ } catch (err) {
178
+ process.stderr.write(
179
+ `migrate-subagents: ERROR failed to write ${sourcePath}: ${err.message}\n`
180
+ );
181
+ // Attempt cleanup of tmp.
182
+ try { if (existsSync(tmp)) renameSync(tmp, tmp + '.failed'); } catch { /* ignore */ }
183
+ process.exit(2);
184
+ }
185
+ }
186
+
187
+ // ---------------------------------------------------------------------------
188
+ // Summary
189
+ // ---------------------------------------------------------------------------
190
+
191
+ process.stderr.write(
192
+ `migrate-subagents: ${countMigrated} migrated, ${countCanonical} already-canonical, ` +
193
+ `${countFailedValidation} failed-validation, ${countMalformed} malformed [${modeLabel}]\n`
194
+ );
195
+
196
+ process.exit(countFailedValidation > 0 ? 1 : 0);