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,496 @@
1
+ /**
2
+ * scope-gate.mjs — scope / pattern primitives.
3
+ *
4
+ * Split out of scripts/lib/hardening.mjs (concern B). Used by Wave 3 hooks on
5
+ * hot-paths — all sync. Re-exported by hardening.mjs as a barrel so existing
6
+ * importers keep working unchanged.
7
+ *
8
+ * Layering: hook-safe — pure functions only; no I/O at import time;
9
+ * ESM-pure for fast hook hot-paths. Hooks (under `hooks/`) import from
10
+ * this lib; this lib MUST NOT reverse-import from `hooks/`. Cross-cutting
11
+ * invariant for all exports below — see #554 A2.
12
+ */
13
+
14
+ import { existsSync, readFileSync } from 'node:fs';
15
+ import path from 'node:path';
16
+
17
+ /**
18
+ * Find the wave-scope.json file for the given project root.
19
+ *
20
+ * Precedence (mirrors find_scope_file in hardening.sh):
21
+ * <root>/.pi/wave-scope.json
22
+ * <root>/.cursor/wave-scope.json
23
+ * <root>/.codex/wave-scope.json
24
+ * <root>/.claude/wave-scope.json
25
+ *
26
+ * Returns the absolute path string, or null if none exist.
27
+ * Sync (uses fs.existsSync).
28
+ *
29
+ * @param {string} projectRoot — absolute path to project root
30
+ * @returns {string|null}
31
+ */
32
+ export function findScopeFile(projectRoot) {
33
+ for (const dir of ['.pi', '.cursor', '.codex', '.claude']) {
34
+ const candidate = path.join(projectRoot, dir, 'wave-scope.json');
35
+ if (existsSync(candidate)) {
36
+ return candidate;
37
+ }
38
+ }
39
+ return null;
40
+ }
41
+
42
+ /**
43
+ * Read the enforcement level from a scope file.
44
+ * Defaults to "strict" (fail-closed) on parse error or missing field.
45
+ * Sync. Never throws.
46
+ *
47
+ * @param {string} scopeFilePath — absolute path to wave-scope.json
48
+ * @returns {string}
49
+ */
50
+ export function getEnforcementLevel(scopeFilePath) {
51
+ try {
52
+ const data = JSON.parse(readFileSync(scopeFilePath, 'utf8'));
53
+ return data.enforcement ?? 'strict';
54
+ } catch {
55
+ return 'strict';
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Check whether a named gate is enabled in the scope file.
61
+ * Returns true if the field is missing or true, false only if explicitly false.
62
+ * Sync. Never throws.
63
+ *
64
+ * @param {string} scopeFilePath — absolute path to wave-scope.json
65
+ * @param {string} gateName — key within .gates
66
+ * @returns {boolean}
67
+ */
68
+ export function gateEnabled(scopeFilePath, gateName) {
69
+ try {
70
+ const data = JSON.parse(readFileSync(scopeFilePath, 'utf8'));
71
+ const gates = data.gates;
72
+ if (gates === undefined || gates === null) return true;
73
+ const value = gates[gateName];
74
+ if (value === undefined || value === null) return true;
75
+ return value !== false;
76
+ } catch {
77
+ return true;
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Test whether a relative file path matches a single glob-style pattern.
83
+ *
84
+ * Supported patterns:
85
+ * - `prefix/` — directory prefix: any file under prefix/ (including nested)
86
+ * - `src/**\/*.ts` — recursive glob: `**` = any depth (including zero dirs)
87
+ * - `src/*.ts` — single-segment glob: `*` = one segment (no slashes)
88
+ * - `path/to/file` — exact match
89
+ *
90
+ * Conversion order:
91
+ * 1. Escape all regex special chars EXCEPT `*` and `/`.
92
+ * 2. Replace `**` with `<<DBL>>` placeholder.
93
+ * 3. Replace remaining `*` with `[^/]*` (single segment).
94
+ * 4. Replace `<<DBL>>` with `.*` (any depth).
95
+ * 5. Anchor: `^...$`.
96
+ *
97
+ * Case-sensitive. Empty pattern returns false.
98
+ *
99
+ * Hook-safe: pure, deterministic, no I/O. Current importers (grep-verified
100
+ * #554 A2): hooks/wave-scope-commit-guard.mjs, hooks/enforce-scope.mjs,
101
+ * scripts/lib/worktree-freshness.mjs, scripts/lib/pre-dispatch-check.mjs.
102
+ *
103
+ * @param {string} relPath
104
+ * @param {string} pattern
105
+ * @returns {boolean}
106
+ */
107
+ export function pathMatchesPattern(relPath, pattern) {
108
+ if (!pattern) return false;
109
+
110
+ // Directory prefix shortcut: pattern ends with '/'
111
+ if (pattern.endsWith('/')) {
112
+ return relPath.startsWith(pattern);
113
+ }
114
+
115
+ // Build a regex from the glob pattern.
116
+ // Step 1: Escape regex special chars (everything except * and /)
117
+ const specialChars = /[.+?|[\](){}\\^$]/g;
118
+ let regex = pattern.replace(specialChars, (ch) => `\\${ch}`);
119
+
120
+ // Step 2: Replace `**/` with placeholder (matches zero-or-more dir segments WITH trailing slash)
121
+ // `src/**/foo` must match `src/foo` (zero dirs) and `src/a/b/foo` (two dirs).
122
+ // Replacing `**/` → `(.*\/)?` captures "any number of segments + slash, or nothing".
123
+ regex = regex.replace(/\*\*\//g, '<<DBLS>>');
124
+
125
+ // Replace remaining `**` (not followed by /) with a second placeholder.
126
+ // MUST use a placeholder (not `.*` directly) — the single-* pass below would otherwise
127
+ // re-process the `*` quantifier in `.*`, yielding `.[^/]*` which blocks nested paths
128
+ // under `tests/**` etc. (issue #220).
129
+ regex = regex.replace(/\*\*/g, '<<DBLG>>');
130
+
131
+ // Step 3: Single * → one path segment (no slashes)
132
+ regex = regex.replace(/\*/g, '[^/]*');
133
+
134
+ // Step 4: Expand placeholders
135
+ regex = regex.replace(/<<DBLS>>/g, '(.*\\/)?');
136
+ regex = regex.replace(/<<DBLG>>/g, '.*');
137
+
138
+ // Step 5: Anchor
139
+ regex = `^${regex}$`;
140
+
141
+ return new RegExp(regex).test(relPath);
142
+ }
143
+
144
+ /**
145
+ * Is this fileScope entry a glob/prefix pattern (vs. a concrete file path)?
146
+ * A `*` metachar OR a trailing `/` (directory prefix) marks it as a glob.
147
+ * @param {string} entry
148
+ * @returns {boolean}
149
+ */
150
+ function isGlobScopeEntry(entry) {
151
+ return entry.includes('*') || entry.endsWith('/');
152
+ }
153
+
154
+ /**
155
+ * Literal prefix of a glob entry — the segment before the first `*`
156
+ * metachar (or the whole entry when it has none). `src/**` → `src/`,
157
+ * `src/lib/*.mjs` → `src/lib/`, `tests/` → `tests/`.
158
+ * @param {string} entry
159
+ * @returns {string}
160
+ */
161
+ function literalScopePrefix(entry) {
162
+ const star = entry.indexOf('*');
163
+ return star === -1 ? entry : entry.slice(0, star);
164
+ }
165
+
166
+ /**
167
+ * Assert that every entry of an agent's declared file scope is covered by the
168
+ * wave's `allowedPaths` union — the mechanical form of the "allowedPaths is the
169
+ * UNION of all agent file scopes" contract (wave-loop.md § Scope Manifest #3).
170
+ *
171
+ * Motivation (#796): `.claude/wave-scope.json` is GLOBAL per wave — one
172
+ * allowedPaths union gates every agent in the wave (hooks/enforce-scope.mjs
173
+ * Gate 7). A coordinator that (re)writes the union for only ONE agent of a
174
+ * multi-agent batch silently denies its siblings' legitimate writes (observed
175
+ * fix-pass incident). Running this assertion for EVERY agent before dispatch
176
+ * catches that class before an agent is blocked mid-run.
177
+ *
178
+ * Semantics:
179
+ * - CONCRETE fileScope entry (no `*`, not a `dir/` prefix): covered iff it
180
+ * matches ≥1 allowedPaths pattern via `pathMatchesPattern` (the same matcher
181
+ * the enforcement hook uses at check time). `src/a.ts` ⊆ `src/**` → covered.
182
+ * - GLOB fileScope entry (`*` present, or a `dir/` prefix): covered iff it is
183
+ * present verbatim in allowedPaths, OR its literal prefix (the segment
184
+ * before the first glob metachar) matches an allowedPaths pattern.
185
+ *
186
+ * GLOB-vs-GLOB LIMITATION (deliberate design boundary): this is NOT a full
187
+ * glob-⊆-glob subset calculus. For a glob fileScope entry the check reduces to
188
+ * verbatim presence + literal-prefix coverage; it does not prove that e.g.
189
+ * `src/**\/*.ts` ⊆ `src/**\/*.js` is false. The concrete-path branch above is
190
+ * exact and carries the incident-relevant load (the union the coordinator
191
+ * actually writes is verbatim, deduplicated agent scopes). Erring toward
192
+ * over-approximating coverage keeps a legitimate union from being rejected on a
193
+ * glob technicality rather than pretending to a precision this matcher lacks.
194
+ *
195
+ * Fail-closed & no-throw (module convention): a non-array `fileScope` or
196
+ * `allowedPaths` returns `{ ok: false, missing: [] }` — "cannot assert → treat
197
+ * as failure". An empty `fileScope` is a trivial subset → `{ ok: true }`.
198
+ * Non-string / empty-string entries are skipped (the CLI caller validates the
199
+ * array-of-strings shape upstream). Never throws.
200
+ *
201
+ * @param {string[]} fileScope — one agent's declared file scope entries
202
+ * @param {string[]} allowedPaths — the wave's allowedPaths union
203
+ * @returns {{ ok: boolean, missing: string[] }} missing = uncovered fileScope entries
204
+ */
205
+ export function assertFileScopeSubset(fileScope, allowedPaths) {
206
+ if (!Array.isArray(fileScope) || !Array.isArray(allowedPaths)) {
207
+ return { ok: false, missing: [] };
208
+ }
209
+ const missing = [];
210
+ for (const entry of fileScope) {
211
+ if (typeof entry !== 'string' || entry.length === 0) continue;
212
+ let covered;
213
+ if (isGlobScopeEntry(entry)) {
214
+ // GLOB entry: verbatim presence OR literal-prefix coverage.
215
+ const prefix = literalScopePrefix(entry);
216
+ covered = allowedPaths.some((p) => p === entry || pathMatchesPattern(prefix, p));
217
+ } else {
218
+ // CONCRETE entry: must match ≥1 allowedPaths pattern.
219
+ covered = allowedPaths.some((p) => pathMatchesPattern(entry, p));
220
+ }
221
+ if (!covered) missing.push(entry);
222
+ }
223
+ return { ok: missing.length === 0, missing };
224
+ }
225
+
226
+ /**
227
+ * Extract likely file-write TARGETS from a Bash command string (#800).
228
+ *
229
+ * Motivation: `hooks/enforce-scope.mjs` Gate 1 only gates the Edit/Write/MultiEdit
230
+ * tools — Bash write channels (heredocs, `>`/`>>` redirects, `tee`, `sed -i`,
231
+ * `dd of=`) bypass the wave-scope gate structurally. This function is the parsing
232
+ * half of the opt-in, WARN-ONLY `bash-write-guard` (wired in enforce-commands.mjs).
233
+ *
234
+ * DESIGN POSTURE — conservative, under- rather than over-match (v1 is warn-only):
235
+ * a false NEGATIVE (missed write) is a silent no-warn; a false POSITIVE (spurious
236
+ * warn on a benign command) is operator noise that erodes trust in the guard. When
237
+ * in doubt we DROP the candidate. This is deliberately NOT a full shell parser.
238
+ *
239
+ * MATCHED write channels:
240
+ * (a) redirects `> p`, `>> p`, `2> p`, `2>> p`, `&> p`, `&>> p` (fd/`&` prefix ok)
241
+ * (b) `tee [-a] p [p2 …]` (all non-flag file args of a `tee` command-head)
242
+ * (c) `sed -i[.bak] … p` (the LAST non-flag argument of a `sed` command-head
243
+ * carrying an in-place `-i*` flag; the `sed` SCRIPT arg is not the target)
244
+ * (d) `dd of=p` (the `of=` argument of a `dd` command-head)
245
+ * (e) heredocs `cat > p <<EOF` — covered by the redirect part `(a)`; the `<<`
246
+ * delimiter itself is an INPUT redirect, never a write target.
247
+ *
248
+ * Deliberately NOT matched (documented skip rules — each is a false-positive trap):
249
+ * - targets beginning with `$` or `~`, or containing ANY `$` (variable /
250
+ * expansion — the concrete path is unknowable at parse time; e.g. `> $LOG`,
251
+ * `>> ${TMPDIR}/x`)
252
+ * - `/dev/…`, `/tmp/…`, `/private/tmp/…` (device + temp sinks — never wave scope)
253
+ * - process substitution `>(…)` (an operator, not a file; the `(` breaks it)
254
+ * - fd duplication `>&`, `2>&1` (dup, not a file target)
255
+ * - input redirects `<`, `<<` (reads, not writes)
256
+ * - quoted targets containing a space (best-effort — a spaced path is far more
257
+ * likely a quoting artefact than a real wave-scoped file)
258
+ * - a `>` / `tee` / `sed` / `dd` that appears INSIDE quotes (e.g. `echo '>' x`)
259
+ * — the tokenizer tracks quote state, so a quoted `>` is a word, not an op.
260
+ *
261
+ * Targets are returned VERBATIM (repo-relative where the command wrote them
262
+ * relatively, absolute where the command used an absolute path) and de-duplicated
263
+ * in first-seen order. The caller relativises + matches against allowedPaths.
264
+ *
265
+ * Hook-safe: pure, deterministic, no I/O. Never throws — a non-string / empty
266
+ * input returns `[]`.
267
+ *
268
+ * @param {string} command — the raw Bash command string
269
+ * @returns {string[]} de-duplicated list of likely write targets (may be empty)
270
+ */
271
+ export function extractBashWriteTargets(command) {
272
+ if (typeof command !== 'string' || command.length === 0) return [];
273
+
274
+ const tokens = tokenizeShellForWrites(command);
275
+
276
+ const out = [];
277
+ const seen = new Set();
278
+ const add = (value, hadSpace) => {
279
+ if (shouldSkipWriteTarget(value, hadSpace)) return;
280
+ const v = value.replace(/^\.\//, '');
281
+ if (!v || seen.has(v)) return;
282
+ seen.add(v);
283
+ out.push(v);
284
+ };
285
+
286
+ // Second pass: interpret the token stream. `mode` tracks a command-head that
287
+ // owns following args (tee/sed/dd); `pendingRedirect` marks that the NEXT word
288
+ // token is a redirect target.
289
+ let mode = null; // null | 'tee' | 'sed' | 'dd'
290
+ let pendingRedirect = false;
291
+ let expectCommand = true; // next word is the command head of this segment
292
+ let sedArgs = []; // { value } collected for a `sed` head
293
+ let sedInPlace = false;
294
+
295
+ const flushSed = () => {
296
+ if (mode === 'sed' && sedInPlace) {
297
+ for (let i = sedArgs.length - 1; i >= 0; i--) {
298
+ if (!isShellFlag(sedArgs[i].value)) {
299
+ add(sedArgs[i].value, sedArgs[i].hadSpace);
300
+ break;
301
+ }
302
+ }
303
+ }
304
+ sedArgs = [];
305
+ sedInPlace = false;
306
+ };
307
+
308
+ for (const tk of tokens) {
309
+ if (tk.type === 'redirect') {
310
+ pendingRedirect = true;
311
+ continue;
312
+ }
313
+ if (tk.type === 'in') {
314
+ // input redirect / heredoc delimiter — not a write target
315
+ pendingRedirect = false;
316
+ continue;
317
+ }
318
+ if (tk.type === 'sep') {
319
+ flushSed();
320
+ mode = null;
321
+ pendingRedirect = false;
322
+ expectCommand = true;
323
+ continue;
324
+ }
325
+ // word token
326
+ if (pendingRedirect) {
327
+ add(tk.value, tk.hadSpace);
328
+ pendingRedirect = false;
329
+ continue;
330
+ }
331
+ if (expectCommand) {
332
+ expectCommand = false;
333
+ flushSed(); // flush any prior sed segment defensively
334
+ if (tk.value === 'tee') { mode = 'tee'; continue; }
335
+ if (tk.value === 'sed') { mode = 'sed'; continue; }
336
+ if (tk.value === 'dd') { mode = 'dd'; continue; }
337
+ mode = null;
338
+ continue;
339
+ }
340
+ // subsequent argument words, interpreted per active command-head mode
341
+ if (mode === 'tee') {
342
+ if (!isShellFlag(tk.value)) add(tk.value, tk.hadSpace);
343
+ } else if (mode === 'sed') {
344
+ if (/^-i/.test(tk.value)) sedInPlace = true;
345
+ sedArgs.push(tk);
346
+ } else if (mode === 'dd') {
347
+ if (tk.value.startsWith('of=')) add(tk.value.slice(3), tk.hadSpace);
348
+ }
349
+ }
350
+ flushSed();
351
+
352
+ return out;
353
+ }
354
+
355
+ /**
356
+ * Is this token a CLI flag (starts with `-`)? Used to skip flags when picking
357
+ * file arguments for tee/sed. `-` alone (stdin) also counts as a flag.
358
+ * @param {string} v
359
+ * @returns {boolean}
360
+ */
361
+ function isShellFlag(v) {
362
+ return typeof v === 'string' && v.startsWith('-');
363
+ }
364
+
365
+ /**
366
+ * Skip-rule gate for a candidate write target — see the documented skip list on
367
+ * {@link extractBashWriteTargets}. Returns true when the candidate must be dropped.
368
+ * @param {string} value — unquoted target text
369
+ * @param {boolean} hadSpace — true if the source token was quoted AND contained a space
370
+ * @returns {boolean}
371
+ */
372
+ function shouldSkipWriteTarget(value, hadSpace) {
373
+ if (typeof value !== 'string' || value.length === 0) return true;
374
+ if (hadSpace || value.includes(' ')) return true; // quoted-with-space (best-effort)
375
+ if (value.startsWith('$') || value.startsWith('~')) return true; // variable / expansion
376
+ if (value.includes('$')) return true; // any embedded expansion (covers ${TMPDIR})
377
+ if (value.includes('(') || value.includes(')')) return true; // process-sub remnants
378
+ if (value.startsWith('/dev/')) return true; // device sink
379
+ if (value.startsWith('/tmp/') || value.startsWith('/private/tmp/')) return true; // temp sink
380
+ return false;
381
+ }
382
+
383
+ /**
384
+ * Minimal quote-aware tokenizer for write-target extraction. Walks the command
385
+ * left-to-right tracking single/double quote state; recognises redirect / input /
386
+ * separator operators ONLY outside quotes, and emits everything else as `word`
387
+ * tokens with the quotes stripped. Not a general shell tokenizer — it captures
388
+ * exactly what {@link extractBashWriteTargets} needs.
389
+ *
390
+ * Token shapes: { type: 'redirect' } | { type: 'in' } | { type: 'sep' }
391
+ * | { type: 'word', value: string, hadSpace: boolean }
392
+ *
393
+ * @param {string} command
394
+ * @returns {Array<{type:string, value?:string, hadSpace?:boolean}>}
395
+ */
396
+ function tokenizeShellForWrites(command) {
397
+ const tokens = [];
398
+ const n = command.length;
399
+ let i = 0;
400
+ const isWs = (c) => c === ' ' || c === '\t' || c === '\n' || c === '\r';
401
+
402
+ while (i < n) {
403
+ const c = command[i];
404
+ const next = command[i + 1];
405
+
406
+ if (isWs(c)) { i++; continue; }
407
+
408
+ // `&>` / `&>>` — redirect stdout+stderr to a file (write target follows)
409
+ if (c === '&' && next === '>') {
410
+ i += 2;
411
+ if (command[i] === '>') i++;
412
+ tokens.push({ type: 'redirect' });
413
+ continue;
414
+ }
415
+ // `&&` / `&` — command separators
416
+ if (c === '&') {
417
+ i += next === '&' ? 2 : 1;
418
+ tokens.push({ type: 'sep' });
419
+ continue;
420
+ }
421
+ // `>&` — fd duplication (NOT a file target); consume the dup + trailing fd/`-`
422
+ if (c === '>' && next === '&') {
423
+ i += 2;
424
+ while (i < n && (/[0-9]/.test(command[i]) || command[i] === '-')) i++;
425
+ continue; // no token — dup carries no write target
426
+ }
427
+ // `>(` — process substitution: leave the `>` inert; `(` is emitted as a sep
428
+ if (c === '>' && next === '(') { i++; continue; }
429
+ // `>>` / `>` — write redirects
430
+ if (c === '>') {
431
+ i += next === '>' ? 2 : 1;
432
+ tokens.push({ type: 'redirect' });
433
+ continue;
434
+ }
435
+ // `<<` / `<` — input redirects / heredoc delimiters (never a write target)
436
+ if (c === '<') {
437
+ i += next === '<' ? 2 : 1;
438
+ tokens.push({ type: 'in' });
439
+ continue;
440
+ }
441
+ // `||` / `|` / `;` / `(` / `)` — separators (break the current command)
442
+ if (c === '|') { i += next === '|' ? 2 : 1; tokens.push({ type: 'sep' }); continue; }
443
+ if (c === ';') { i++; tokens.push({ type: 'sep' }); continue; }
444
+ if (c === '(' || c === ')') { i++; tokens.push({ type: 'sep' }); continue; }
445
+
446
+ // Otherwise: read a WORD, honouring single/double quotes (quotes stripped).
447
+ let value = '';
448
+ let quoted = false;
449
+ let hadSpace = false;
450
+ while (i < n) {
451
+ const ch = command[i];
452
+ if (ch === "'") {
453
+ quoted = true;
454
+ i++;
455
+ while (i < n && command[i] !== "'") { if (command[i] === ' ') hadSpace = true; value += command[i]; i++; }
456
+ i++; // closing quote (or EOF)
457
+ continue;
458
+ }
459
+ if (ch === '"') {
460
+ quoted = true;
461
+ i++;
462
+ while (i < n && command[i] !== '"') { if (command[i] === ' ') hadSpace = true; value += command[i]; i++; }
463
+ i++; // closing quote (or EOF)
464
+ continue;
465
+ }
466
+ if (isWs(ch)) break;
467
+ // unquoted operator chars end the word
468
+ if (ch === '>' || ch === '<' || ch === '|' || ch === ';' || ch === '&' || ch === '(' || ch === ')') break;
469
+ value += ch;
470
+ i++;
471
+ }
472
+ tokens.push({ type: 'word', value, hadSpace, quoted });
473
+ }
474
+
475
+ return tokens;
476
+ }
477
+
478
+ /**
479
+ * Build an actionable suggestion string for a scope violation.
480
+ *
481
+ * @param {string} relPath — the relative path that was blocked
482
+ * @param {string} allowedCsv — comma-separated list of allowed paths (may be empty)
483
+ * @returns {string}
484
+ */
485
+ export function suggestForScopeViolation(relPath, allowedCsv) {
486
+ if (!allowedCsv) {
487
+ return (
488
+ `No paths are currently allowed for this wave. ` +
489
+ `If '${relPath}' is in-scope, update the session plan and restart the wave.`
490
+ );
491
+ }
492
+ return (
493
+ `Allowed paths: [${allowedCsv}]. ` +
494
+ `If '${relPath}' belongs to this wave, add its directory to the plan's wave scope and restart.`
495
+ );
496
+ }