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,175 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * check-path-utils-canary.mjs — Assert that validatePathInsideProject is exported
4
+ * from path-utils.mjs and is imported at all three canonical callsites.
5
+ *
6
+ * Rationale: validatePathInsideProject is the canonical two-phase path-traversal +
7
+ * symlink-escape guard (Phase 1 lexical isPathInside, Phase 2 realpathSync-when-exists).
8
+ * It was extracted in #402 from three inline guard sites to prevent duplication drift.
9
+ * Without this canary, a refactor that removes the import at any callsite silently
10
+ * reverts to no guard (or re-introduces an inline one), which is a CWE-23 regression
11
+ * the test suite will not catch directly.
12
+ *
13
+ * Regression class this prevents (not covered by existing 39 canaries):
14
+ * - Removal of `validatePathInsideProject` import from config/test.mjs,
15
+ * profiles/schema.mjs, or playwright-driver/runner.mjs without a test failing.
16
+ * - Removal of the export from path-utils.mjs while callsites still compile
17
+ * (the call would simply return undefined and silently skip validation).
18
+ *
19
+ * Checks:
20
+ * 1. path-utils.mjs exports validatePathInsideProject (export keyword present)
21
+ * 2. scripts/lib/config/test.mjs imports validatePathInsideProject from path-utils
22
+ * 3. scripts/lib/profiles/schema.mjs imports validatePathInsideProject from path-utils
23
+ * 4. scripts/lib/playwright-driver/runner.mjs imports validatePathInsideProject from path-utils
24
+ *
25
+ * MAINTAINER NOTE: This canary locks in WHICH production modules use the helper.
26
+ * If a callsite is intentionally removed (e.g. module deprecation), DELETE the matching
27
+ * Check N block from this file — this is not a "fix the canary to be passing" situation.
28
+ * Conversely, when a NEW callsite is added, append a corresponding Check N+1 block.
29
+ *
30
+ * Exit codes:
31
+ * 0 — all checks passed
32
+ * 1 — at least one check failed
33
+ *
34
+ * Usage:
35
+ * node scripts/lib/validate/check-path-utils-canary.mjs <plugin-root>
36
+ */
37
+
38
+ import { readFileSync, existsSync } from 'node:fs';
39
+ import { join } from 'node:path';
40
+
41
+ const pluginRoot = process.argv[2];
42
+ if (!pluginRoot) {
43
+ console.error('Usage: check-path-utils-canary.mjs <plugin-root>');
44
+ process.exit(1);
45
+ }
46
+
47
+ let passed = 0;
48
+ let failed = 0;
49
+
50
+ function pass(msg) { console.log(` PASS: ${msg}`); passed += 1; }
51
+ function fail(msg) { console.log(` FAIL: ${msg}`); failed += 1; }
52
+
53
+ function readFile(relPath) {
54
+ const abs = join(pluginRoot, relPath);
55
+ if (!existsSync(abs)) return null;
56
+ return readFileSync(abs, 'utf8');
57
+ }
58
+
59
+ // ---------------------------------------------------------------------------
60
+ // Check 1: path-utils.mjs exports validatePathInsideProject
61
+ // ---------------------------------------------------------------------------
62
+
63
+ console.log('--- Check 1: path-utils.mjs exports validatePathInsideProject ---');
64
+
65
+ const pathUtils = readFile('scripts/lib/path-utils.mjs');
66
+ if (pathUtils === null) {
67
+ fail('scripts/lib/path-utils.mjs does not exist');
68
+ } else if (/export function validatePathInsideProject/.test(pathUtils)) {
69
+ pass('path-utils.mjs exports validatePathInsideProject');
70
+ } else {
71
+ fail('path-utils.mjs does not export validatePathInsideProject — two-phase guard helper is missing');
72
+ }
73
+
74
+ // ---------------------------------------------------------------------------
75
+ // Check 2: config/test.mjs imports validatePathInsideProject
76
+ // ---------------------------------------------------------------------------
77
+
78
+ console.log('');
79
+ console.log('--- Check 2: scripts/lib/config/test.mjs imports validatePathInsideProject ---');
80
+
81
+ const configTest = readFile('scripts/lib/config/test.mjs');
82
+ if (configTest === null) {
83
+ fail('scripts/lib/config/test.mjs does not exist');
84
+ } else if (/import\s*\{[^}]*validatePathInsideProject[^}]*\}\s*from\s*['"][^'"]*path-utils/.test(configTest)) {
85
+ pass('config/test.mjs imports validatePathInsideProject from path-utils');
86
+ } else {
87
+ fail('config/test.mjs does not import validatePathInsideProject from path-utils — SEC-IR-LOW-2 profiles-path guard may be missing');
88
+ }
89
+
90
+ // ---------------------------------------------------------------------------
91
+ // Check 3: profiles/schema.mjs imports validatePathInsideProject
92
+ // ---------------------------------------------------------------------------
93
+
94
+ console.log('');
95
+ console.log('--- Check 3: scripts/lib/profiles/schema.mjs imports validatePathInsideProject ---');
96
+
97
+ const profilesSchema = readFile('scripts/lib/profiles/schema.mjs');
98
+ if (profilesSchema === null) {
99
+ fail('scripts/lib/profiles/schema.mjs does not exist');
100
+ } else if (/import\s*\{[^}]*validatePathInsideProject[^}]*\}\s*from\s*['"][^'"]*path-utils/.test(profilesSchema)) {
101
+ pass('profiles/schema.mjs imports validatePathInsideProject from path-utils');
102
+ } else {
103
+ fail('profiles/schema.mjs does not import validatePathInsideProject from path-utils — SEC-IR-LOW-3 rubric path guard may be missing');
104
+ }
105
+
106
+ // ---------------------------------------------------------------------------
107
+ // Check 4: playwright-driver/runner.mjs imports validatePathInsideProject
108
+ // ---------------------------------------------------------------------------
109
+
110
+ console.log('');
111
+ console.log('--- Check 4: scripts/lib/playwright-driver/runner.mjs imports validatePathInsideProject ---');
112
+
113
+ const runnerMjs = readFile('scripts/lib/playwright-driver/runner.mjs');
114
+ if (runnerMjs === null) {
115
+ fail('scripts/lib/playwright-driver/runner.mjs does not exist');
116
+ } else if (/import\s*\{[^}]*validatePathInsideProject[^}]*\}\s*from\s*['"][^'"]*path-utils/.test(runnerMjs)) {
117
+ pass('playwright-driver/runner.mjs imports validatePathInsideProject from path-utils');
118
+ } else {
119
+ fail('playwright-driver/runner.mjs does not import validatePathInsideProject from path-utils — #398 runDir traversal guard may be missing');
120
+ }
121
+
122
+ // ---------------------------------------------------------------------------
123
+ // Check 5: #477 cross-repo sink scripts import validatePathInsideProject
124
+ // ---------------------------------------------------------------------------
125
+
126
+ console.log('');
127
+ console.log('--- Check 5: #477 cross-repo sink scripts import validatePathInsideProject ---');
128
+
129
+ const sinkScripts = [
130
+ 'scripts/promote-vault-strict.mjs',
131
+ 'scripts/run-migrate-v2-cross-repo.mjs',
132
+ 'scripts/vault-integration-watcher.mjs',
133
+ ];
134
+
135
+ for (const relPath of sinkScripts) {
136
+ const src = readFile(relPath);
137
+ if (src === null) {
138
+ fail(`${relPath} does not exist`);
139
+ } else if (/import\s*\{[^}]*validatePathInsideProject[^}]*\}\s*from\s*['"][^'"]*path-utils/.test(src)) {
140
+ pass(`${relPath} imports validatePathInsideProject from path-utils (#477 confinement guard)`);
141
+ } else {
142
+ fail(`${relPath} does not import validatePathInsideProject from path-utils — #477 path-confinement guard is missing`);
143
+ }
144
+ }
145
+
146
+ // ---------------------------------------------------------------------------
147
+ // Check 6: #544 M3 memory-proposals modules import validatePathInsideProject
148
+ // ---------------------------------------------------------------------------
149
+
150
+ console.log('');
151
+ console.log('--- Check 6: #544 M3 memory-proposals modules import validatePathInsideProject ---');
152
+
153
+ const memoryProposalsModules = [
154
+ 'scripts/lib/memory-proposals/store.mjs',
155
+ 'scripts/lib/memory-proposals/sink.mjs',
156
+ ];
157
+
158
+ for (const relPath of memoryProposalsModules) {
159
+ const src = readFile(relPath);
160
+ if (src === null) {
161
+ fail(`${relPath} does not exist`);
162
+ } else if (/import\s*\{[^}]*validatePathInsideProject[^}]*\}\s*from\s*['"][^'"]*path-utils/.test(src)) {
163
+ pass(`${relPath} imports validatePathInsideProject from path-utils (#544 M3 canonicalization)`);
164
+ } else {
165
+ fail(`${relPath} does not import validatePathInsideProject from path-utils — #544 M3 path-canonicalization guard is missing`);
166
+ }
167
+ }
168
+
169
+ // ---------------------------------------------------------------------------
170
+ // Summary
171
+ // ---------------------------------------------------------------------------
172
+
173
+ console.log('');
174
+ console.log(`Results: ${passed} passed, ${failed} failed`);
175
+ process.exit(failed > 0 ? 1 : 0);
@@ -0,0 +1,201 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * check-peekaboo-driver-canary.mjs — Forbid peekaboo-mcp references in
4
+ * skills/peekaboo-driver/** and scripts/lib/test-runner/**.
5
+ *
6
+ * Rationale: The peekaboo-driver skill wraps the `peekaboo` binary (steipete,
7
+ * MIT, macOS-only) directly via the CLI. Introducing an MCP adapter layer
8
+ * (peekaboo-mcp) would add unnecessary token overhead and couples the driver
9
+ * to a specific MCP transport. All invocations MUST use the raw binary.
10
+ *
11
+ * Forbidden pattern:
12
+ * - peekaboo-mcp (the string; NOT bare "peekaboo" which is the valid binary name)
13
+ *
14
+ * Allowed patterns:
15
+ * - mentions inside lines that contain documentation markers explaining
16
+ * WHY the pattern is forbidden, not actual imports or usage.
17
+ *
18
+ * Detection strategy:
19
+ * - Scan all .md, .mjs, .js, .ts files under the two forbidden dirs
20
+ * - Flag any line containing the forbidden pattern
21
+ * - Skip lines that also contain a documentation marker
22
+ * (HARD-GATE, check-peekaboo-driver-canary, R5 grep-canary, canary-exempt)
23
+ *
24
+ * Exit codes:
25
+ * 0 — no violations
26
+ * 1 — at least one violation found
27
+ *
28
+ * Usage:
29
+ * node scripts/lib/validate/check-peekaboo-driver-canary.mjs <plugin-root>
30
+ *
31
+ * Test approach (for W4):
32
+ * - Verify exit 0 when scan roots are clean or absent
33
+ * - Verify exit 1 + FAIL line when a scanned file contains a bare forbidden pattern
34
+ * - Verify that lines containing HARD-GATE are skipped (no false positives on SKILL.md)
35
+ * - Verify non-scanned file extensions (e.g. .yaml) are not processed
36
+ */
37
+
38
+ import { readdirSync, readFileSync, statSync, existsSync } from 'node:fs';
39
+ import { join, relative } from 'node:path';
40
+
41
+ const pluginRoot = process.argv[2];
42
+ if (!pluginRoot) {
43
+ console.error('Usage: check-peekaboo-driver-canary.mjs <plugin-root>');
44
+ process.exit(1);
45
+ }
46
+
47
+ let passed = 0;
48
+ let failed = 0;
49
+
50
+ function pass(msg) { console.log(` PASS: ${msg}`); passed += 1; }
51
+ function fail(msg) { console.log(` FAIL: ${msg}`); failed += 1; }
52
+
53
+ console.log('--- Check 1: peekaboo-mcp canary (R5 — forbidden in peekaboo-driver + helpers) ---');
54
+
55
+ const FORBIDDEN_PATTERNS = [
56
+ /peekaboo-mcp/,
57
+ ];
58
+
59
+ // Lines that mention the forbidden pattern AS PART OF documenting the rule
60
+ // itself are skipped. Any of these markers on the same line indicates a
61
+ // documentation context, not an actual import or usage reference.
62
+ const DOCUMENTATION_MARKERS = [
63
+ /HARD-GATE/,
64
+ /check-peekaboo-driver-canary/,
65
+ /R5 grep-canary/,
66
+ /R5 hard-gate/,
67
+ // SEC-PD-LOW-2: canary-exempt was an unguarded bypass keyword (security_control_bypass).
68
+ // HARD-GATE remains for legitimate documenting-the-rule context.
69
+ // "Never peekaboo-mcp" — anti-pattern prohibition in soul.md / SKILL.md
70
+ /Never.*peekaboo-mcp/,
71
+ // "blocks peekaboo-mcp" — rule-enforcement documentation
72
+ /blocks.*peekaboo-mcp/,
73
+ // Markdown table rows listing peekaboo-mcp as a "DO NOT USE" item
74
+ /DO NOT USE.*peekaboo-mcp|peekaboo-mcp.*DO NOT USE/,
75
+ ];
76
+
77
+ const SCAN_ROOTS = [
78
+ 'skills/peekaboo-driver',
79
+ 'scripts/lib/test-runner',
80
+ 'scripts/lib/profiles',
81
+ ];
82
+
83
+ const SCAN_EXTENSIONS = ['.md', '.mjs', '.js', '.ts'];
84
+
85
+ /**
86
+ * Recursively walk a directory and return all file paths with the allowed extensions.
87
+ * @param {string} dir
88
+ * @returns {string[]}
89
+ */
90
+ function walk(dir) {
91
+ const results = [];
92
+ if (!existsSync(dir)) return results;
93
+ for (const name of readdirSync(dir)) {
94
+ const full = join(dir, name);
95
+ const st = statSync(full);
96
+ if (st.isDirectory()) {
97
+ results.push(...walk(full));
98
+ } else if (SCAN_EXTENSIONS.some((ext) => name.endsWith(ext))) {
99
+ results.push(full);
100
+ }
101
+ }
102
+ return results;
103
+ }
104
+
105
+ const violations = [];
106
+
107
+ for (const rel of SCAN_ROOTS) {
108
+ const absDir = join(pluginRoot, rel);
109
+ if (!existsSync(absDir)) {
110
+ pass(`${rel}/ does not exist yet (no scan needed)`);
111
+ continue;
112
+ }
113
+ const files = walk(absDir);
114
+ let fileViolations = 0;
115
+ for (const file of files) {
116
+ const text = readFileSync(file, 'utf8');
117
+ const lines = text.split('\n');
118
+ for (let i = 0; i < lines.length; i += 1) {
119
+ const line = lines[i];
120
+ const matchesForbidden = FORBIDDEN_PATTERNS.some((p) => p.test(line));
121
+ if (!matchesForbidden) continue;
122
+ const isDocumentation = DOCUMENTATION_MARKERS.some((p) => p.test(line));
123
+ if (isDocumentation) continue;
124
+ violations.push({
125
+ file: relative(pluginRoot, file),
126
+ line: i + 1,
127
+ text: line.trim().slice(0, 160),
128
+ });
129
+ fileViolations += 1;
130
+ }
131
+ }
132
+ if (fileViolations === 0) {
133
+ pass(`${rel}/ scanned (${files.length} files): no peekaboo-mcp references`);
134
+ }
135
+ }
136
+
137
+ if (violations.length === 0) {
138
+ pass(`peekaboo-mcp canary clean across all ${SCAN_ROOTS.length} scan roots`);
139
+ } else {
140
+ for (const v of violations) {
141
+ fail(
142
+ `${v.file}:${v.line} — '${v.text}' (matches forbidden pattern; ` +
143
+ `if intentional documentation, add a HARD-GATE marker on the line)`,
144
+ );
145
+ }
146
+ }
147
+
148
+ // ---------------------------------------------------------------------------
149
+ // Check 2–4: anchor canaries — required vocabulary in SKILL.md (#401 GAP-Q4-5)
150
+ // ---------------------------------------------------------------------------
151
+
152
+ console.log('');
153
+ console.log('--- Check 2: peekaboo SKILL.md anchor — "thin executor" (driver identity) ---');
154
+
155
+ const SKILL_MD = join(pluginRoot, 'skills/peekaboo-driver/SKILL.md');
156
+
157
+ if (!existsSync(SKILL_MD)) {
158
+ // SKILL.md absent in this plugin root — same graceful handling as absent scan roots in Check 1.
159
+ pass('skills/peekaboo-driver/SKILL.md does not exist yet (no anchor checks needed)');
160
+
161
+ console.log('');
162
+ console.log('--- Check 3: peekaboo SKILL.md anchor — "$MISSING" (permission-flow vocab) ---');
163
+ pass('skills/peekaboo-driver/SKILL.md does not exist yet (no anchor checks needed)');
164
+
165
+ console.log('');
166
+ console.log('--- Check 4: peekaboo SKILL.md anchor — "status: stub" (glass-modifiers v1 schema marker) ---');
167
+ pass('skills/peekaboo-driver/SKILL.md does not exist yet (no anchor checks needed)');
168
+ } else {
169
+ const skillText = readFileSync(SKILL_MD, 'utf8');
170
+
171
+ // Anchor 1: "thin executor" — driver identity vocabulary
172
+ if (/thin executor/.test(skillText)) {
173
+ pass('SKILL.md contains required anchor "thin executor" (driver identity)');
174
+ } else {
175
+ fail('SKILL.md missing required anchor "thin executor" — driver identity vocabulary must be present');
176
+ }
177
+
178
+ console.log('');
179
+ console.log('--- Check 3: peekaboo SKILL.md anchor — "$MISSING" (permission-flow vocab) ---');
180
+
181
+ // Anchor 2: "$MISSING" — permission-flow vocabulary
182
+ if (/\$MISSING/.test(skillText)) {
183
+ pass('SKILL.md contains required anchor "$MISSING" (permission-flow vocabulary)');
184
+ } else {
185
+ fail('SKILL.md missing required anchor "$MISSING" — permission-flow vocabulary must be present');
186
+ }
187
+
188
+ console.log('');
189
+ console.log('--- Check 4: peekaboo SKILL.md anchor — "status: stub" (glass-modifiers v1 schema marker) ---');
190
+
191
+ // Anchor 3: "status: stub" — glass-modifiers v1 schema marker
192
+ if (/"status":\s*"stub"/.test(skillText)) {
193
+ pass('SKILL.md contains required anchor "status: stub" (glass-modifiers v1 schema marker)');
194
+ } else {
195
+ fail('SKILL.md missing required anchor "status: stub" — glass-modifiers v1 schema marker must be present');
196
+ }
197
+ }
198
+
199
+ console.log('');
200
+ console.log(`Results: ${passed} passed, ${failed} failed`);
201
+ process.exit(failed > 0 ? 1 : 0);
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env node
2
+ // check-pi-package.mjs — Validate the Pi package manifest in package.json.
3
+ // Usage: check-pi-package.mjs <plugin-root>
4
+ // Exit 0 = all checks passed, 1 = at least one failure.
5
+
6
+ import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
7
+ import { join, dirname } from 'node:path';
8
+
9
+ const pluginRoot = process.argv[2];
10
+ if (!pluginRoot) {
11
+ console.error('Usage: check-pi-package.mjs <plugin-root>');
12
+ process.exit(1);
13
+ }
14
+
15
+ let passed = 0;
16
+ let failed = 0;
17
+
18
+ function pass(msg) { console.log(` PASS: ${msg}`); passed += 1; }
19
+ function fail(msg) { console.log(` FAIL: ${msg}`); failed += 1; }
20
+
21
+ function isDir(p) {
22
+ try { return statSync(p).isDirectory(); } catch { return false; }
23
+ }
24
+
25
+ function isFile(p) {
26
+ try { return statSync(p).isFile(); } catch { return false; }
27
+ }
28
+
29
+ function stripLeadingDotSlash(p) {
30
+ return p.replace(/^\.\//, '');
31
+ }
32
+
33
+ function matchesSimpleGlob(relPath) {
34
+ if (!relPath.includes('*')) {
35
+ return existsSync(join(pluginRoot, stripLeadingDotSlash(relPath)));
36
+ }
37
+
38
+ const clean = stripLeadingDotSlash(relPath);
39
+ const dir = dirname(clean);
40
+ const base = clean.slice(dir.length + 1);
41
+ const [prefix, suffix] = base.split('*');
42
+ const absDir = join(pluginRoot, dir);
43
+ if (!isDir(absDir)) return false;
44
+ return readdirSync(absDir).some((entry) => entry.startsWith(prefix) && entry.endsWith(suffix));
45
+ }
46
+
47
+ function validatePathArray(pkg, field) {
48
+ const values = pkg.pi?.[field];
49
+ if (!Array.isArray(values) || values.length === 0) {
50
+ fail(`pi.${field} must be a non-empty array`);
51
+ return;
52
+ }
53
+
54
+ for (const value of values) {
55
+ if (typeof value !== 'string' || value.length === 0) {
56
+ fail(`pi.${field} entry must be a non-empty string`);
57
+ continue;
58
+ }
59
+ if (!value.startsWith('./')) {
60
+ fail(`pi.${field} entry must be repo-relative and start with ./: ${value}`);
61
+ continue;
62
+ }
63
+ if (matchesSimpleGlob(value)) {
64
+ pass(`pi.${field} entry resolves: ${value}`);
65
+ } else {
66
+ fail(`pi.${field} entry does not resolve: ${value}`);
67
+ }
68
+ }
69
+ }
70
+
71
+ console.log('--- Check 1: package.json pi package manifest ---');
72
+
73
+ const packageJsonPath = join(pluginRoot, 'package.json');
74
+ let pkg;
75
+ try {
76
+ pkg = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
77
+ } catch (err) {
78
+ fail(`package.json not found or invalid JSON: ${err.message}`);
79
+ console.log('');
80
+ console.log(`Results: ${passed} passed, ${failed} failed`);
81
+ process.exit(1);
82
+ }
83
+
84
+ if (Array.isArray(pkg.keywords) && pkg.keywords.includes('pi-package')) {
85
+ pass('package.json keywords include pi-package');
86
+ } else {
87
+ fail('package.json keywords must include pi-package');
88
+ }
89
+
90
+ if (pkg.pi && typeof pkg.pi === 'object' && !Array.isArray(pkg.pi)) {
91
+ pass('package.json pi manifest is present');
92
+ } else {
93
+ fail('package.json pi manifest is missing');
94
+ }
95
+
96
+ validatePathArray(pkg, 'extensions');
97
+ validatePathArray(pkg, 'skills');
98
+ validatePathArray(pkg, 'prompts');
99
+
100
+ const extensionEntries = Array.isArray(pkg.pi?.extensions) ? pkg.pi.extensions : [];
101
+ const tsExtension = extensionEntries.find((entry) => entry.endsWith('.ts'));
102
+ if (tsExtension && isFile(join(pluginRoot, stripLeadingDotSlash(tsExtension)))) {
103
+ pass(`Pi extension TypeScript entry exists: ${tsExtension}`);
104
+ } else {
105
+ fail('pi.extensions must include an existing .ts extension entry');
106
+ }
107
+
108
+ console.log('');
109
+ console.log(`Results: ${passed} passed, ${failed} failed`);
110
+ process.exit(failed > 0 ? 1 : 0);
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env node
2
+ // check-pi-prompts.mjs — Ensure generated Pi prompt wrappers match commands/*.md.
3
+ // Usage: check-pi-prompts.mjs <plugin-root>
4
+ // Exit 0 = all checks passed, 1 = at least one failure.
5
+
6
+ import { spawnSync } from 'node:child_process';
7
+ import { existsSync } from 'node:fs';
8
+ import { join } from 'node:path';
9
+
10
+ const pluginRoot = process.argv[2];
11
+ if (!pluginRoot) {
12
+ console.error('Usage: check-pi-prompts.mjs <plugin-root>');
13
+ process.exit(1);
14
+ }
15
+
16
+ let passed = 0;
17
+ let failed = 0;
18
+
19
+ function pass(msg) { console.log(` PASS: ${msg}`); passed += 1; }
20
+ function fail(msg) { console.log(` FAIL: ${msg}`); failed += 1; }
21
+
22
+ console.log('--- Check 1: generated Pi prompt wrappers ---');
23
+
24
+ const generator = join(pluginRoot, 'scripts', 'generate-pi-prompts.mjs');
25
+ if (!existsSync(generator)) {
26
+ fail('scripts/generate-pi-prompts.mjs exists');
27
+ } else {
28
+ const result = spawnSync(process.execPath, [generator, '--check'], {
29
+ cwd: pluginRoot,
30
+ encoding: 'utf8',
31
+ stdio: ['ignore', 'pipe', 'pipe'],
32
+ });
33
+ if (result.status === 0) {
34
+ pass('pi/prompts/*.md are up to date with commands/*.md');
35
+ } else {
36
+ const detail = ((result.stdout ?? '') + (result.stderr ?? '')).trim();
37
+ fail(`pi prompt wrappers are stale${detail ? `: ${detail}` : ''}`);
38
+ }
39
+ }
40
+
41
+ console.log('');
42
+ console.log(`Results: ${passed} passed, ${failed} failed`);
43
+ process.exit(failed > 0 ? 1 : 0);
@@ -0,0 +1,154 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * check-playwright-mcp-canary.mjs — Forbid @playwright/mcp references in
4
+ * skills/playwright-driver/** and scripts/lib/test-runner/**.
5
+ *
6
+ * Rationale: Playwright MCP costs ~4× more tokens per test than the
7
+ * canonical playwright CLI (Microsoft's own benchmark: ~114K vs ~27K).
8
+ * The playwright-driver and test-runner stack MUST stay on the CLI.
9
+ *
10
+ * Forbidden patterns:
11
+ * - @playwright/mcp
12
+ * - playwright-mcp
13
+ *
14
+ * Allowed patterns:
15
+ * - mentions inside lines that contain HARD-GATE markers or other
16
+ * canary-exempt tokens — those are documentation blocks explaining
17
+ * WHY the pattern is forbidden, not actual imports or usage.
18
+ *
19
+ * Detection strategy:
20
+ * - Scan all .md, .mjs, .js, .ts files under the two forbidden dirs
21
+ * - Flag any line containing one of the forbidden patterns
22
+ * - Skip lines that also contain a documentation marker
23
+ * (HARD-GATE, check-playwright-mcp-canary, R5 grep-canary, canary-exempt)
24
+ *
25
+ * Exit codes:
26
+ * 0 — no violations
27
+ * 1 — at least one violation found
28
+ *
29
+ * Usage:
30
+ * node scripts/lib/validate/check-playwright-mcp-canary.mjs <plugin-root>
31
+ *
32
+ * Test approach (for W4):
33
+ * - Verify exit 0 when scan roots are clean or absent
34
+ * - Verify exit 1 + FAIL line when a scanned file contains a bare forbidden pattern
35
+ * - Verify that lines containing HARD-GATE are skipped (no false positives on SKILL.md)
36
+ * - Verify non-scanned file extensions (e.g. .yaml) are not processed
37
+ */
38
+
39
+ import { readdirSync, readFileSync, statSync, existsSync } from 'node:fs';
40
+ import { join, relative } from 'node:path';
41
+
42
+ const pluginRoot = process.argv[2];
43
+ if (!pluginRoot) {
44
+ console.error('Usage: check-playwright-mcp-canary.mjs <plugin-root>');
45
+ process.exit(1);
46
+ }
47
+
48
+ let passed = 0;
49
+ let failed = 0;
50
+
51
+ function pass(msg) { console.log(` PASS: ${msg}`); passed += 1; }
52
+ function fail(msg) { console.log(` FAIL: ${msg}`); failed += 1; }
53
+
54
+ console.log('--- Check 1: playwright-mcp canary (R5 — forbidden in driver + helpers) ---');
55
+
56
+ const FORBIDDEN_PATTERNS = [
57
+ /@playwright\/mcp/,
58
+ /playwright-mcp/,
59
+ ];
60
+
61
+ // Lines that mention the forbidden pattern AS PART OF documenting the rule
62
+ // itself are skipped. Any of these markers on the same line indicates a
63
+ // documentation context, not an actual import or usage reference.
64
+ const DOCUMENTATION_MARKERS = [
65
+ /HARD-GATE/,
66
+ /check-playwright-mcp-canary/,
67
+ /R5 grep-canary/,
68
+ /R5 hard-gate/,
69
+ /canary-exempt/,
70
+ // "Never @playwright/mcp" — anti-pattern prohibition in soul.md / SKILL.md
71
+ /Never.*@playwright\/mcp/,
72
+ /Never.*playwright-mcp/,
73
+ // "blocks @playwright/mcp" — rule-enforcement documentation
74
+ /blocks.*@playwright\/mcp/,
75
+ /blocks.*playwright-mcp/,
76
+ // Markdown table rows listing @playwright/mcp as a "DO NOT USE" item
77
+ /DO NOT USE.*@playwright\/mcp|@playwright\/mcp.*DO NOT USE/,
78
+ /DO NOT USE.*playwright-mcp|playwright-mcp.*DO NOT USE/,
79
+ ];
80
+
81
+ const SCAN_ROOTS = [
82
+ 'skills/playwright-driver',
83
+ 'scripts/lib/test-runner',
84
+ 'scripts/lib/profiles',
85
+ ];
86
+
87
+ const SCAN_EXTENSIONS = ['.md', '.mjs', '.js', '.ts'];
88
+
89
+ /**
90
+ * Recursively walk a directory and return all file paths with the allowed extensions.
91
+ * @param {string} dir
92
+ * @returns {string[]}
93
+ */
94
+ function walk(dir) {
95
+ const results = [];
96
+ if (!existsSync(dir)) return results;
97
+ for (const name of readdirSync(dir)) {
98
+ const full = join(dir, name);
99
+ const st = statSync(full);
100
+ if (st.isDirectory()) {
101
+ results.push(...walk(full));
102
+ } else if (SCAN_EXTENSIONS.some((ext) => name.endsWith(ext))) {
103
+ results.push(full);
104
+ }
105
+ }
106
+ return results;
107
+ }
108
+
109
+ const violations = [];
110
+
111
+ for (const rel of SCAN_ROOTS) {
112
+ const absDir = join(pluginRoot, rel);
113
+ if (!existsSync(absDir)) {
114
+ pass(`${rel}/ does not exist yet (no scan needed)`);
115
+ continue;
116
+ }
117
+ const files = walk(absDir);
118
+ let fileViolations = 0;
119
+ for (const file of files) {
120
+ const text = readFileSync(file, 'utf8');
121
+ const lines = text.split('\n');
122
+ for (let i = 0; i < lines.length; i += 1) {
123
+ const line = lines[i];
124
+ const matchesForbidden = FORBIDDEN_PATTERNS.some((p) => p.test(line));
125
+ if (!matchesForbidden) continue;
126
+ const isDocumentation = DOCUMENTATION_MARKERS.some((p) => p.test(line));
127
+ if (isDocumentation) continue;
128
+ violations.push({
129
+ file: relative(pluginRoot, file),
130
+ line: i + 1,
131
+ text: line.trim().slice(0, 160),
132
+ });
133
+ fileViolations += 1;
134
+ }
135
+ }
136
+ if (fileViolations === 0) {
137
+ pass(`${rel}/ scanned (${files.length} files): no playwright-mcp references`);
138
+ }
139
+ }
140
+
141
+ if (violations.length === 0) {
142
+ pass(`playwright-mcp canary clean across all ${SCAN_ROOTS.length} scan roots`);
143
+ } else {
144
+ for (const v of violations) {
145
+ fail(
146
+ `${v.file}:${v.line} — '${v.text}' (matches forbidden pattern; ` +
147
+ `if intentional documentation, add a HARD-GATE marker on the line)`,
148
+ );
149
+ }
150
+ }
151
+
152
+ console.log('');
153
+ console.log(`Results: ${passed} passed, ${failed} failed`);
154
+ process.exit(failed > 0 ? 1 : 0);