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,404 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * pre-bash-templates-first.mjs — PreToolUse hook: blocks `gh|glab pr|mr|issue
4
+ * create|new` invocations when no matching template was Read earlier in the
5
+ * session.
6
+ *
7
+ * Implements Pattern 3 of "gsd Pattern Adoption Quick-Wins" (#519; archived in
8
+ * the private Meta-Vault). Companion to pre-bash-destructive-guard.mjs (issue
9
+ * #155); both share the PreToolUse Bash matcher and run sequentially.
10
+ *
11
+ * Decision flow:
12
+ * G1 tool filter — only Bash is gated; other tools pass through.
13
+ * G2 command is a non-empty string.
14
+ * G3 regex match against /^\s*(gh|glab)\s+(pr|mr|issue)\s+(create|new)\b/.
15
+ * No match → exit 0 (the call is not a create/new operation).
16
+ * G4 policy load: .orchestrator/policy/templates-policy.json.
17
+ * Missing → exit 0 + stderr warning. Malformed → exit 0 + stderr warning.
18
+ * G5 bypass-pattern check: any entry in policy.bypass_patterns that the
19
+ * command starts with → exit 0.
20
+ * G6 acknowledgement-file check: if the file under the resolved acknowledgement
21
+ * path contains an entry for the current session_id, exit 0.
22
+ * G7 transcript inspection via hooks/_lib/transcript-history.mjs.
23
+ * If any prior Read tool call matches one of the host-specific template
24
+ * paths from the policy, exit 0.
25
+ * G8 fall-through: emit deny via stdout JSON + structured stderr listing the
26
+ * template paths, and exit 2.
27
+ *
28
+ * Fail-safe posture: any internal exception is swallowed in main().catch and
29
+ * the hook exits 0 (allow). Rationale matches pre-bash-destructive-guard.mjs:
30
+ * a templates-first hook that crashes should not block legitimate work; the
31
+ * worst case is a missed enforcement, not a wedged session.
32
+ *
33
+ * Exit codes:
34
+ * 0 — pass-through (G1-G3 short-circuits, bypass match, acknowledgement, Read found, error)
35
+ * 2 — deny + structured JSON on stdout (PRD § 3 Gherkin Pattern 3)
36
+ */
37
+
38
+ import { readStdin, emitAllow } from '../scripts/lib/io.mjs';
39
+ import { resolveProjectDir, resolvePluginRoot } from '../scripts/lib/platform.mjs';
40
+ import { readJson } from '../scripts/lib/common.mjs';
41
+ import { hasReadInSession } from './_lib/transcript-history.mjs';
42
+
43
+ import { shouldRunHook } from './_lib/profile-gate.mjs';
44
+ import { existsSync, readdirSync, lstatSync } from 'node:fs';
45
+ import path from 'node:path';
46
+
47
+ // #519: opt-in via profile/env. Default profile "full" enables this hook;
48
+ // minimal/off disable. SO_DISABLED_HOOKS=pre-bash-templates-first opts out
49
+ // per session.
50
+ if (!shouldRunHook('pre-bash-templates-first')) process.exit(0);
51
+
52
+ // ---------------------------------------------------------------------------
53
+ // Constants
54
+ // ---------------------------------------------------------------------------
55
+
56
+ /**
57
+ * Matches the canonical `gh` / `glab` issue/PR/MR creation invocations.
58
+ * Anchored at start (^) with optional leading whitespace to catch indented
59
+ * shell snippets. Word-boundary at the end avoids false positives on tokens
60
+ * like `created` or `news`. Edit operations (`gh pr edit`, `glab mr edit`)
61
+ * are deliberately out of scope per PRD § 2 Out-of-Scope.
62
+ */
63
+ const CREATE_REGEX = /^\s*(gh|glab)\s+(pr|mr|issue)\s+(create|new)\b/;
64
+
65
+ /**
66
+ * Default acknowledgement path, relative to project root. Used when the
67
+ * policy omits the `acknowledgement_file` key.
68
+ */
69
+ const DEFAULT_ACK_PATH = '.orchestrator/runtime/templates-acknowledged.json';
70
+
71
+ // ---------------------------------------------------------------------------
72
+ // Helpers
73
+ // ---------------------------------------------------------------------------
74
+
75
+ /**
76
+ * Block the create command: write structured deny JSON to stdout + exit 2.
77
+ * Mirrors the exact format from pre-bash-destructive-guard.mjs blockCommand()
78
+ * so downstream Claude Code rendering is consistent.
79
+ *
80
+ * @param {{ host: string, command: string, templatePaths: string[],
81
+ * ackFile: string }} ctx
82
+ * @returns {never}
83
+ */
84
+ function blockCreate(ctx) {
85
+ const { host, command, templatePaths, ackFile } = ctx;
86
+ const pathList = templatePaths.length > 0
87
+ ? templatePaths.map((p) => ` - ${p}`).join('\n')
88
+ : ' (none configured)';
89
+ const reason = [
90
+ `pre-bash-templates-first: ${host} create call detected without prior template Read.`,
91
+ `Command: ${command}`,
92
+ `Found templates:`,
93
+ pathList,
94
+ `Read one of these first, OR run \`/templates-ack\` (writes ${ackFile}) to bypass for this session.`,
95
+ `See: issue #519, "gsd Pattern Adoption Quick-Wins" (archived in the private Meta-Vault) (Pattern 3)`,
96
+ ].join('\n');
97
+
98
+ // PRD § 3 Gherkin Pattern 3 spec: stderr lists template paths + ack hint.
99
+ // We emit BOTH stderr (human-readable per spec) AND the structured stdout
100
+ // JSON envelope (machine-readable for Claude Code hook protocol).
101
+ process.stderr.write(reason + '\n');
102
+ process.stdout.write(
103
+ JSON.stringify({ permissionDecision: 'deny', reason }) + '\n',
104
+ );
105
+ process.exit(2);
106
+ }
107
+
108
+ /**
109
+ * Resolve the policy file path, searching in priority order. Mirrors the
110
+ * resolution chain in pre-bash-destructive-guard.mjs so administrators only
111
+ * have to maintain a single mental model for policy locations.
112
+ *
113
+ * @param {string|null} projectDir
114
+ * @returns {string|null}
115
+ */
116
+ function resolvePolicyPath(projectDir) {
117
+ const candidates = [
118
+ path.join(
119
+ process.cwd(),
120
+ '.orchestrator',
121
+ 'policy',
122
+ 'templates-policy.json',
123
+ ),
124
+ ];
125
+
126
+ if (projectDir && projectDir !== process.cwd()) {
127
+ candidates.push(
128
+ path.join(projectDir, '.orchestrator', 'policy', 'templates-policy.json'),
129
+ );
130
+ }
131
+
132
+ const pluginRoot = resolvePluginRoot();
133
+ if (pluginRoot) {
134
+ candidates.push(
135
+ path.join(pluginRoot, '.orchestrator', 'policy', 'templates-policy.json'),
136
+ );
137
+ }
138
+
139
+ for (const candidate of candidates) {
140
+ if (existsSync(candidate)) return candidate;
141
+ }
142
+ return null;
143
+ }
144
+
145
+ /**
146
+ * Determine which host the command targets by inspecting the CREATE_REGEX
147
+ * capture. `gh` → "github", `glab` → "gitlab".
148
+ *
149
+ * @param {string} command
150
+ * @returns {"github"|"gitlab"|null}
151
+ */
152
+ function resolveHost(command) {
153
+ const m = command.match(CREATE_REGEX);
154
+ if (!m) return null;
155
+ return m[1] === 'gh' ? 'github' : 'gitlab';
156
+ }
157
+
158
+ /**
159
+ * True when the command starts with any of the bypass patterns. Bypass match
160
+ * is a prefix check with a word/EOL boundary on the trailing edge — this
161
+ * prevents trivial bypass via prefix-inclusion (e.g. policy entry
162
+ * "gh issue create --label bot" must not match "gh issue create --label botanical").
163
+ *
164
+ * @param {string} command
165
+ * @param {string[]} bypassPatterns
166
+ * @returns {boolean}
167
+ */
168
+ function matchesBypass(command, bypassPatterns) {
169
+ if (!Array.isArray(bypassPatterns) || bypassPatterns.length === 0) {
170
+ return false;
171
+ }
172
+ const stripped = command.replace(/^\s+/, '');
173
+ for (const pat of bypassPatterns) {
174
+ if (typeof pat !== 'string' || pat.length === 0) continue;
175
+ const patStripped = pat.replace(/^\s+/, '');
176
+ if (!stripped.startsWith(patStripped)) continue;
177
+ // Boundary check: next character must be whitespace, EOL, or absent.
178
+ // This prevents "gh foo --label bot" from matching policy "gh foo --label botanical".
179
+ const nextChar = stripped.charAt(patStripped.length);
180
+ if (nextChar === '' || /\s/.test(nextChar)) return true;
181
+ }
182
+ return false;
183
+ }
184
+
185
+ /**
186
+ * Check the acknowledgement file for the current session_id. Best-effort:
187
+ * any read or parse error means "no acknowledgement" (returns false) so the
188
+ * subsequent transcript-history check still runs. The acknowledgement file
189
+ * schema is intentionally minimal:
190
+ *
191
+ * { "<session_id>": { "acknowledgedAt": "<ISO timestamp>" } }
192
+ *
193
+ * A future /templates-ack command writes this file; the hook only reads it.
194
+ *
195
+ * @param {string} ackFilePath
196
+ * @param {string|null} sessionId
197
+ * @returns {Promise<boolean>}
198
+ */
199
+ async function isAcknowledged(ackFilePath, sessionId) {
200
+ if (!sessionId || typeof sessionId !== 'string') return false;
201
+ if (!existsSync(ackFilePath)) return false;
202
+ try {
203
+ const data = await readJson(ackFilePath);
204
+ if (!data || typeof data !== 'object') return false;
205
+ const entry = data[sessionId];
206
+ return Boolean(entry && typeof entry === 'object' && entry.acknowledgedAt);
207
+ } catch {
208
+ return false;
209
+ }
210
+ }
211
+
212
+ /**
213
+ * Pull the session_id from the hook stdin payload, with a single fallback
214
+ * to the persisted file written by on-session-start.mjs. Returns null when
215
+ * neither source yields a string.
216
+ *
217
+ * @param {object|null} input
218
+ * @param {string|null} projectDir
219
+ * @returns {Promise<string|null>}
220
+ */
221
+ async function resolveSessionId(input, projectDir) {
222
+ const fromStdin = input?.session_id ?? input?.sessionId ?? null;
223
+ if (typeof fromStdin === 'string' && fromStdin.length > 0) return fromStdin;
224
+
225
+ if (!projectDir) return null;
226
+ const persisted = path.join(projectDir, '.orchestrator', 'current-session.json');
227
+ if (!existsSync(persisted)) return null;
228
+ try {
229
+ const data = await readJson(persisted);
230
+ if (data && typeof data === 'object') {
231
+ const sid = data.session_id ?? data.sessionId ?? null;
232
+ if (typeof sid === 'string' && sid.length > 0) return sid;
233
+ }
234
+ } catch {
235
+ // ignore — null below
236
+ }
237
+ return null;
238
+ }
239
+
240
+ // ---------------------------------------------------------------------------
241
+ // Main
242
+ // ---------------------------------------------------------------------------
243
+
244
+ async function main() {
245
+ const input = await readStdin();
246
+ if (!input) return emitAllow();
247
+
248
+ // G1 — only Bash is gated.
249
+ if (input.tool_name !== 'Bash') return emitAllow();
250
+
251
+ // G2 — command must be a non-empty string.
252
+ const command = input?.tool_input?.command;
253
+ if (typeof command !== 'string' || command.length === 0) return emitAllow();
254
+
255
+ // G3 — regex gate. Non-matching commands pass through unconditionally.
256
+ const host = resolveHost(command);
257
+ if (!host) return emitAllow();
258
+
259
+ const projectDir = resolveProjectDir();
260
+
261
+ // G4 — policy load.
262
+ const policyPath = resolvePolicyPath(projectDir);
263
+ if (!policyPath) {
264
+ process.stderr.write(
265
+ '⚠ pre-bash-templates-first: policy file not found ' +
266
+ '(.orchestrator/policy/templates-policy.json) — skipping guard\n',
267
+ );
268
+ return emitAllow();
269
+ }
270
+
271
+ let policy;
272
+ try {
273
+ policy = await readJson(policyPath);
274
+ } catch {
275
+ process.stderr.write(
276
+ '⚠ pre-bash-templates-first: policy file is malformed (invalid JSON) — skipping guard\n',
277
+ );
278
+ return emitAllow();
279
+ }
280
+
281
+ if (!policy || typeof policy !== 'object') {
282
+ process.stderr.write(
283
+ '⚠ pre-bash-templates-first: policy file empty or non-object — skipping guard\n',
284
+ );
285
+ return emitAllow();
286
+ }
287
+
288
+ // Enforcement off → allow without inspection.
289
+ if (policy.enforcement === 'off') return emitAllow();
290
+
291
+ // G5 — bypass-pattern check.
292
+ if (matchesBypass(command, policy.bypass_patterns)) {
293
+ process.stderr.write(
294
+ `ℹ pre-bash-templates-first: bypass-pattern matched, allowing '${command.slice(0, 80)}'\n`,
295
+ );
296
+ return emitAllow();
297
+ }
298
+
299
+ // Resolve the acknowledgement file path (policy override or default).
300
+ const ackRel =
301
+ typeof policy.acknowledgement_file === 'string' && policy.acknowledgement_file.length > 0
302
+ ? policy.acknowledgement_file
303
+ : DEFAULT_ACK_PATH;
304
+ const ackFile = path.isAbsolute(ackRel)
305
+ ? ackRel
306
+ : path.join(projectDir || process.cwd(), ackRel);
307
+
308
+ // G6 — acknowledgement-file check.
309
+ const sessionId = await resolveSessionId(input, projectDir);
310
+ if (await isAcknowledged(ackFile, sessionId)) {
311
+ return emitAllow();
312
+ }
313
+
314
+ // G7 — transcript inspection.
315
+ // The hook stdin payload carries `transcript_path` per Claude Code's hook
316
+ // contract. When absent (older harness, Codex/Cursor port, manual smoke
317
+ // test) we treat it as "no evidence of prior Read" and fall through to
318
+ // deny — that is the default-deny safety posture for this gate.
319
+ const hostBlock = policy.hosts?.[host] ?? {};
320
+ const templatePathsConfigured = Array.isArray(hostBlock.template_paths)
321
+ ? hostBlock.template_paths.filter((p) => typeof p === 'string' && p.length > 0)
322
+ : [];
323
+
324
+ // Resolve configured paths to ACTUAL files on disk in the project.
325
+ // - File pattern (e.g. .github/PULL_REQUEST_TEMPLATE.md) → include if exists.
326
+ // - Directory pattern (e.g. .gitlab/merge_request_templates/) → expand to
327
+ // all *.md files inside (and inside immediate subdirs for ISSUE_TEMPLATE/).
328
+ // If NO templates resolve, nothing to enforce → allow.
329
+ const projectBase = projectDir || process.cwd();
330
+ const templatePaths = [];
331
+ for (const p of templatePathsConfigured) {
332
+ const abs = path.isAbsolute(p) ? p : path.join(projectBase, p);
333
+ if (!existsSync(abs)) continue;
334
+ let stat;
335
+ try {
336
+ const lstat = lstatSync(abs);
337
+ if (lstat.isSymbolicLink()) {
338
+ process.stderr.write(`⚠ pre-bash-templates-first: template path is a symlink (${p}) — rejected for security\n`);
339
+ continue;
340
+ }
341
+ stat = lstat;
342
+ } catch { continue; }
343
+ if (stat.isFile()) {
344
+ templatePaths.push(p);
345
+ continue;
346
+ }
347
+ if (stat.isDirectory()) {
348
+ let entries;
349
+ try { entries = readdirSync(abs); } catch { continue; }
350
+ const trimmed = p.endsWith('/') ? p.slice(0, -1) : p;
351
+ for (const entry of entries) {
352
+ if (entry.startsWith('.')) continue;
353
+ const entryAbs = path.join(abs, entry);
354
+ let estat;
355
+ try {
356
+ const elstat = lstatSync(entryAbs);
357
+ if (elstat.isSymbolicLink()) {
358
+ // Silent skip: symlinks inside template directories are not enforced templates.
359
+ continue;
360
+ }
361
+ estat = elstat;
362
+ } catch { continue; }
363
+ if (estat.isFile() && (entry.endsWith('.md') || entry.endsWith('.yml') || entry.endsWith('.yaml'))) {
364
+ templatePaths.push(`${trimmed}/${entry}`);
365
+ }
366
+ }
367
+ }
368
+ }
369
+
370
+ if (templatePaths.length === 0) {
371
+ process.stderr.write(
372
+ `ℹ pre-bash-templates-first: no ${host} template files found in repo — allowing '${command.slice(0, 80)}'\n`,
373
+ );
374
+ return emitAllow();
375
+ }
376
+
377
+ const transcriptPath =
378
+ typeof input.transcript_path === 'string' && input.transcript_path.length > 0
379
+ ? input.transcript_path
380
+ : null;
381
+
382
+ if (transcriptPath && templatePaths.length > 0) {
383
+ const result = await hasReadInSession(templatePaths, transcriptPath);
384
+ if (result.matched) return emitAllow();
385
+ }
386
+
387
+ // G8 — deny.
388
+ blockCreate({
389
+ host,
390
+ command,
391
+ templatePaths,
392
+ ackFile,
393
+ });
394
+ }
395
+
396
+ // Top-level error handler — never let exit 1 leak. Same posture as
397
+ // pre-bash-destructive-guard.mjs: fail-open on internal errors to avoid
398
+ // blocking legitimate work.
399
+ main().catch((e) => {
400
+ process.stderr.write(
401
+ `⚠ pre-bash-templates-first: internal error — ${e?.message || e}\n`,
402
+ );
403
+ process.exit(0);
404
+ });
@@ -0,0 +1,72 @@
1
+ #!/bin/sh
2
+ # hooks/run-node.sh — resolve the Node.js binary robustly, then exec a plugin hook.
3
+ #
4
+ # Why this exists (GH Kanevry/session-orchestrator#53): the Claude Code harness
5
+ # executes hook commands via `/bin/sh -c` with the PATH of the harness process
6
+ # itself. That shell does NOT source ~/.zshrc / ~/.bashrc, so Node installed via
7
+ # Homebrew on Apple Silicon (/opt/homebrew/bin), nvm, volta, or asdf may be
8
+ # invisible to hooks even though `node` works fine in a normal terminal. A bare
9
+ # `node ...` command then fails with "node: command not found" on EVERY hook of
10
+ # EVERY tool call — loud, repetitive, and useless to the operator.
11
+ #
12
+ # Contract:
13
+ # sh run-node.sh <hook-script.mjs> [args...]
14
+ # - Resolution order: $SO_NODE_BIN override > PATH > well-known install dirs
15
+ # ($SO_NODE_SEARCH_DIRS, colon-separated, overrides the built-in list) > nvm.
16
+ # - Found: exec's node — stdin/stdout/stderr and exit code pass through
17
+ # unchanged (PreToolUse exit-2 blocking still works).
18
+ # - Missing: prints ONE warning per rate-limit window (marker file in
19
+ # ${TMPDIR:-/tmp}, 6h TTL) and exits 0 so hooks degrade gracefully
20
+ # instead of spamming a shell error on every tool call.
21
+
22
+ # 1. Explicit operator override wins.
23
+ if [ -n "$SO_NODE_BIN" ] && [ -x "$SO_NODE_BIN" ]; then
24
+ exec "$SO_NODE_BIN" "$@"
25
+ fi
26
+
27
+ # 2. PATH as inherited from the harness.
28
+ if command -v node >/dev/null 2>&1; then
29
+ exec node "$@"
30
+ fi
31
+
32
+ # 3. Well-known install locations (Homebrew arm64/intel, system, volta, asdf).
33
+ search_dirs="${SO_NODE_SEARCH_DIRS:-/opt/homebrew/bin:/usr/local/bin:/usr/bin:${VOLTA_HOME:-$HOME/.volta}/bin:$HOME/.asdf/shims:$HOME/.local/bin}"
34
+ old_ifs="$IFS"
35
+ IFS=:
36
+ for dir in $search_dirs; do
37
+ if [ -n "$dir" ] && [ -x "$dir/node" ]; then
38
+ IFS="$old_ifs"
39
+ exec "$dir/node" "$@"
40
+ fi
41
+ done
42
+ IFS="$old_ifs"
43
+
44
+ # 4. nvm keeps versioned dirs; any installed version is good enough for hooks.
45
+ # (Glob order is lexical, not semver — acceptable for a last-resort fallback.)
46
+ for cand in "${NVM_DIR:-$HOME/.nvm}"/versions/node/*/bin/node; do
47
+ if [ -x "$cand" ]; then
48
+ exec "$cand" "$@"
49
+ fi
50
+ done
51
+
52
+ # 5. Not found anywhere: degrade gracefully. Warn at most once per 6 hours so
53
+ # the operator gets ONE actionable diagnostic instead of per-tool-call spam.
54
+ # Deliberately dependency-free: a PATH broken enough to lose `node` may also
55
+ # lack `touch`/`find`/`id`, so the marker is written via shell redirection
56
+ # and `find` only upgrades the check to a 6h TTL when it happens to exist.
57
+ marker="${TMPDIR:-/tmp}/session-orchestrator-node-missing-${USER:-uid}"
58
+ if [ -f "$marker" ]; then
59
+ expired="$(find "$marker" -mmin +360 2>/dev/null || true)"
60
+ else
61
+ expired="yes"
62
+ fi
63
+ if [ -n "$expired" ]; then
64
+ : > "$marker" 2>/dev/null || true
65
+ {
66
+ echo "session-orchestrator: 'node' not found on the hook PATH — plugin hooks are skipped."
67
+ echo " Fix: install Node.js 24+, expose it on the harness PATH, or set SO_NODE_BIN=/abs/path/to/node."
68
+ echo " (Hook shells do not source ~/.zshrc — Homebrew/nvm/volta installs can be invisible here."
69
+ echo " Rate-limited to once per 6h. See README.md § Troubleshooting.)"
70
+ } >&2
71
+ fi
72
+ exit 0
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * skill-invocation-telemetry.mjs — PreToolUse hook for Skill tool selection.
4
+ *
5
+ * Hook event: PreToolUse with matcher:"Skill" (issue #645, epic #643).
6
+ * Fires when the Skill tool is invoked (a skill is selected). Writes a
7
+ * selection record to `.orchestrator/metrics/skill-invocations.jsonl`.
8
+ *
9
+ * Decision flow:
10
+ * 1. shouldRunHook gate — exit 0 immediately when the hook is disabled.
11
+ * 2. Read JSON payload from stdin: { tool_name, tool_input: { skill }, session_id }.
12
+ * 3. Belt-and-suspenders guard: if tool_name !== "Skill", exit 0 immediately.
13
+ * 4. Build a 'selected' record and call appendSkillInvocation().
14
+ * 5. Output: nothing on stdout. Diagnostic errors to stderr only.
15
+ *
16
+ * Exit codes: 0 always (informational, never blocking).
17
+ */
18
+
19
+ import { shouldRunHook } from './_lib/profile-gate.mjs';
20
+ // Exit 0 immediately when disabled via SO_HOOK_PROFILE / SO_DISABLED_HOOKS.
21
+ if (!shouldRunHook('skill-invocation-telemetry')) process.exit(0);
22
+
23
+ import path from 'node:path';
24
+ import { appendSkillInvocation } from '../scripts/lib/skill-invocations-schema.mjs';
25
+ import { SO_PROJECT_DIR } from '../scripts/lib/platform.mjs';
26
+
27
+ // ---------------------------------------------------------------------------
28
+ // Constants
29
+ // ---------------------------------------------------------------------------
30
+
31
+ const JSONL_PATH = path.join(SO_PROJECT_DIR, '.orchestrator', 'metrics', 'skill-invocations.jsonl');
32
+
33
+ // ---------------------------------------------------------------------------
34
+ // Helpers
35
+ // ---------------------------------------------------------------------------
36
+
37
+ /**
38
+ * Read stdin to EOF (best-effort). Returns parsed JSON or null on failure.
39
+ * Uses a 5 s timeout consistent with Claude Code hook contract.
40
+ *
41
+ * @returns {Promise<object|null>}
42
+ */
43
+ function readStdinJson() {
44
+ return new Promise((resolve) => {
45
+ if (process.stdin.readableEnded || process.stdin.closed) {
46
+ resolve(null);
47
+ return;
48
+ }
49
+ const chunks = [];
50
+ const timer = setTimeout(() => { resolve(null); }, 5_000);
51
+ process.stdin.setEncoding('utf8');
52
+ process.stdin.on('data', (c) => chunks.push(c));
53
+ process.stdin.on('end', () => {
54
+ clearTimeout(timer);
55
+ const raw = chunks.join('').trim();
56
+ if (!raw) { resolve(null); return; }
57
+ try { resolve(JSON.parse(raw)); } catch { resolve(null); }
58
+ });
59
+ process.stdin.on('error', () => { clearTimeout(timer); resolve(null); });
60
+ process.stdin.resume();
61
+ });
62
+ }
63
+
64
+ // ---------------------------------------------------------------------------
65
+ // Main
66
+ // ---------------------------------------------------------------------------
67
+
68
+ async function main() {
69
+ const input = await readStdinJson();
70
+ if (!input) return;
71
+
72
+ // Belt-and-suspenders: the hooks.json matcher:"Skill" should already filter,
73
+ // but we guard defensively in case of misconfiguration or future matcher changes.
74
+ if (input.tool_name !== 'Skill') return;
75
+
76
+ const skillName = (typeof input.tool_input?.skill === 'string' && input.tool_input.skill.trim())
77
+ ? input.tool_input.skill.trim()
78
+ : 'unknown';
79
+
80
+ const sessionId = (typeof input.session_id === 'string' && input.session_id.trim())
81
+ ? input.session_id.trim()
82
+ : null;
83
+
84
+ /** @type {object} */
85
+ const record = {
86
+ timestamp: new Date().toISOString(),
87
+ event: 'selected',
88
+ skill: skillName,
89
+ session_id: sessionId,
90
+ schema_version: 1,
91
+ };
92
+
93
+ await appendSkillInvocation(JSONL_PATH, record);
94
+ }
95
+
96
+ // Exit 0 always — informational hook must never block the Skill tool.
97
+ main().catch((err) => {
98
+ process.stderr.write(`[skill-invocation-telemetry] ERROR: ${err?.message ?? err}\n`);
99
+ }).finally(() => process.exit(0));