heyspex 0.1.0 → 0.2.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 (322) hide show
  1. package/README.md +21 -0
  2. package/bin/hs.mjs +931 -98
  3. package/bin/spexcode.mjs +262 -0
  4. package/dev-factory/engine/worktree.mjs +740 -0
  5. package/dev-factory/lib/code-repo-root.mjs +67 -0
  6. package/dev-factory/lib/context-budget.mjs +84 -0
  7. package/dev-factory/lib/epic-detect.mjs +190 -0
  8. package/dev-factory/lib/fleet-queue-file.mjs +846 -0
  9. package/dev-factory/lib/fleet-queue.mjs +426 -0
  10. package/dev-factory/lib/fleet-state.mjs +14 -18
  11. package/dev-factory/lib/model-catalog.mjs +338 -0
  12. package/dev-factory/lib/seat-context.mjs +199 -0
  13. package/dev-factory/lib/spec-io.mjs +93 -0
  14. package/dev-factory/lib/sufficiency-score.mjs +8 -2
  15. package/dev-factory/lib/worktree-allocator.mjs +744 -0
  16. package/dev-factory/model-catalog.json +222 -0
  17. package/dist/cli/hs-check.mjs +1085 -103
  18. package/dist/cli/hs-claim.mjs +936 -63
  19. package/dist/cli/hs-connect.mjs +9786 -1910
  20. package/dist/cli/hs-defer.mjs +5267 -3053
  21. package/dist/cli/hs-dev.mjs +564 -0
  22. package/dist/cli/hs-env.mjs +385 -299
  23. package/dist/cli/hs-index-rebuild.mjs +7129 -0
  24. package/dist/cli/hs-index-reconcile.mjs +7852 -0
  25. package/dist/cli/hs-init.mjs +777 -138
  26. package/dist/cli/hs-install.mjs +6583 -485
  27. package/dist/cli/hs-join.mjs +10137 -2368
  28. package/dist/cli/hs-vault-pull.mjs +4659 -5882
  29. package/dist/cli/hs-vault.mjs +3793 -1537
  30. package/dist/cli/hs-workspace.mjs +2550 -524
  31. package/dist/cli-templates/customer-vault/specs/entity-model.md +594 -601
  32. package/dist/cli-templates/customer-vault/specs/protocols/canonical-frontmatter-templates.md +110 -177
  33. package/dist/cli-templates/customer-vault/specs/protocols/destructive-action-checklist.md +122 -0
  34. package/dist/cli-templates/customer-vault/specs/protocols/memory-protocol.md +13 -15
  35. package/dist/cli-templates/customer-vault/specs/protocols/session-close-protocol.md +91 -0
  36. package/dist/cli-templates/customer-vault/specs/protocols/spec-hierarchy.md +150 -168
  37. package/dist/cli-templates/customer-vault/specs/protocols/spec-summary-authoring.md +83 -0
  38. package/dist/cli-templates/harness-commands/claude/hs-auto.md +36 -0
  39. package/dist/cli-templates/harness-commands/claude/hs-backfill.md +28 -0
  40. package/dist/cli-templates/harness-commands/claude/hs-capture.md +62 -0
  41. package/dist/cli-templates/harness-commands/claude/hs-defer.md +29 -0
  42. package/dist/cli-templates/harness-commands/claude/hs-dev.md +20 -0
  43. package/dist/cli-templates/harness-commands/claude/hs-doctor.md +32 -0
  44. package/dist/cli-templates/harness-commands/claude/hs-ground.md +28 -0
  45. package/dist/cli-templates/harness-commands/claude/hs-handoff.md +33 -0
  46. package/dist/cli-templates/harness-commands/claude/hs-log.md +27 -0
  47. package/dist/cli-templates/harness-commands/claude/hs-next.md +29 -0
  48. package/dist/cli-templates/harness-commands/claude/hs-promote.md +70 -0
  49. package/dist/cli-templates/harness-commands/claude/hs-push.md +35 -0
  50. package/dist/cli-templates/harness-commands/claude/hs-qc.md +27 -0
  51. package/dist/cli-templates/harness-commands/claude/hs-res.md +63 -0
  52. package/dist/cli-templates/harness-commands/claude/hs-resolve.md +23 -0
  53. package/dist/cli-templates/harness-commands/claude/hs-review.md +23 -0
  54. package/dist/cli-templates/harness-commands/claude/hs-view.md +26 -0
  55. package/dist/cli-templates/harness-commands/claude/kill-ports.md +32 -0
  56. package/dist/cli-templates/harness-commands/claude/prototype.md +91 -0
  57. package/dist/cli-templates/harness-commands/cursor/hs-auto.md +40 -0
  58. package/dist/cli-templates/harness-commands/cursor/hs-backfill.md +31 -0
  59. package/dist/cli-templates/harness-commands/cursor/hs-capture.md +65 -0
  60. package/dist/cli-templates/harness-commands/cursor/hs-defer.md +32 -0
  61. package/dist/cli-templates/harness-commands/cursor/hs-dev.md +24 -0
  62. package/dist/cli-templates/harness-commands/cursor/hs-doctor.md +36 -0
  63. package/dist/cli-templates/harness-commands/cursor/hs-ground.md +31 -0
  64. package/dist/cli-templates/harness-commands/cursor/hs-handoff.md +37 -0
  65. package/dist/cli-templates/harness-commands/cursor/hs-log.md +31 -0
  66. package/dist/cli-templates/harness-commands/cursor/hs-next.md +32 -0
  67. package/dist/cli-templates/harness-commands/cursor/hs-promote.md +73 -0
  68. package/dist/cli-templates/harness-commands/cursor/hs-push.md +38 -0
  69. package/dist/cli-templates/harness-commands/cursor/hs-qc.md +30 -0
  70. package/dist/cli-templates/harness-commands/cursor/hs-res.md +67 -0
  71. package/dist/cli-templates/harness-commands/cursor/hs-resolve.md +26 -0
  72. package/dist/cli-templates/harness-commands/cursor/hs-review.md +26 -0
  73. package/dist/cli-templates/harness-commands/cursor/hs-view.md +30 -0
  74. package/dist/cli-templates/harness-commands/cursor/kill-ports.md +35 -0
  75. package/dist/cli-templates/harness-commands/cursor/prototype.md +95 -0
  76. package/docs/mcp-client-config.md +259 -6
  77. package/package.json +231 -124
  78. package/plugins/heyspex/.claude-plugin/plugin.json +12 -0
  79. package/plugins/heyspex/.cursor-plugin/plugin.json +15 -0
  80. package/plugins/heyspex/.mcp.json +12 -0
  81. package/plugins/heyspex/bin/launch-mcp.mjs +95 -0
  82. package/plugins/heyspex/bin/run-hook.mjs +62 -0
  83. package/plugins/heyspex/hooks/cursor-hooks.json +227 -0
  84. package/plugins/heyspex/hooks/hooks.json +361 -0
  85. package/plugins/heyspex/mcp.json +13 -0
  86. package/scripts/check-mcp-freshness.mjs +17 -9
  87. package/scripts/claude-hooks/_env-vault-events.mjs +68 -0
  88. package/scripts/claude-hooks/_guardrail-events.mjs +96 -0
  89. package/scripts/claude-hooks/_guardrail-loader.mjs +494 -0
  90. package/scripts/claude-hooks/_intent-classifier-router.mjs +410 -0
  91. package/scripts/claude-hooks/_intent-classifier-semantic.mjs +351 -0
  92. package/scripts/claude-hooks/_run.mjs +120 -0
  93. package/scripts/claude-hooks/_transcript-text.mjs +60 -0
  94. package/scripts/claude-hooks/_vault-retrieval.mjs +322 -0
  95. package/scripts/claude-hooks/agent-spawn-delegation-gate.mjs +133 -0
  96. package/scripts/claude-hooks/capture-workflow-gate.mjs +11 -0
  97. package/scripts/claude-hooks/check-auto-memory-budget.mjs +396 -0
  98. package/scripts/claude-hooks/check-claude-md-budget.mjs +327 -0
  99. package/scripts/claude-hooks/check-mcp-freshness-hook.mjs +14 -0
  100. package/scripts/claude-hooks/claim-before-code-gate.mjs +11 -0
  101. package/scripts/claude-hooks/claim-liveness-shared.mjs +575 -0
  102. package/scripts/claude-hooks/close-terminal-on-ship.mjs +64 -0
  103. package/scripts/claude-hooks/coo-denylist-gate.mjs +11 -0
  104. package/scripts/claude-hooks/coo-guard-check.mjs +11 -0
  105. package/scripts/claude-hooks/deep-research-cost-gate.mjs +11 -0
  106. package/scripts/claude-hooks/dev-server-task-reminder.mjs +15 -0
  107. package/scripts/claude-hooks/emit-claim-status.mjs +41 -0
  108. package/scripts/claude-hooks/enforce-session-sequence.mjs +11 -0
  109. package/scripts/claude-hooks/enforce-vault-naming.mjs +11 -0
  110. package/scripts/claude-hooks/env-vault-guard.mjs +11 -0
  111. package/scripts/claude-hooks/epic-milestone-phrasing-gate.mjs +11 -0
  112. package/scripts/claude-hooks/git-identity-guard.mjs +11 -0
  113. package/scripts/claude-hooks/git-reflog-audit.mjs +15 -0
  114. package/scripts/claude-hooks/git-stash-gate.mjs +11 -0
  115. package/scripts/claude-hooks/guard-auto-memory-writes.mjs +137 -0
  116. package/scripts/claude-hooks/id-display-format-gate.mjs +11 -0
  117. package/scripts/claude-hooks/inject-communication-style.mjs +66 -0
  118. package/scripts/claude-hooks/inject-coo-seat.mjs +78 -0
  119. package/scripts/claude-hooks/inject-dev-server-awareness.mjs +11 -0
  120. package/scripts/claude-hooks/inject-doctrine.mjs +13 -0
  121. package/scripts/claude-hooks/inject-vault-context.mjs +14 -0
  122. package/scripts/claude-hooks/intent-classifier-trigger.mjs +247 -0
  123. package/scripts/claude-hooks/log-session-activity.mjs +341 -0
  124. package/scripts/claude-hooks/naughty-list-gate.mjs +11 -0
  125. package/scripts/claude-hooks/notify-status-flip.mjs +72 -0
  126. package/scripts/claude-hooks/plan-exit-ingest-gate.mjs +170 -0
  127. package/scripts/claude-hooks/plan-ingest-close-reminder.mjs +66 -0
  128. package/scripts/claude-hooks/plan-review-gate.mjs +11 -0
  129. package/scripts/claude-hooks/preflight-reminder.mjs +262 -0
  130. package/scripts/claude-hooks/protected-action-intent.mjs +221 -0
  131. package/scripts/claude-hooks/research-method-guard.mjs +398 -0
  132. package/scripts/claude-hooks/research-protocol-gate.mjs +11 -0
  133. package/scripts/claude-hooks/session-end.mjs +449 -0
  134. package/scripts/claude-hooks/settings-write-gate.mjs +11 -0
  135. package/scripts/claude-hooks/settlement-check-gate.mjs +39 -0
  136. package/scripts/claude-hooks/status-flip-detect.mjs +17 -0
  137. package/scripts/claude-hooks/terminal-close-shared.mjs +426 -0
  138. package/scripts/claude-hooks/terminal-close-watcher.mjs +122 -0
  139. package/scripts/claude-hooks/wip-checkpoint.mjs +298 -0
  140. package/scripts/cursor-hooks/manifest.mjs +235 -0
  141. package/scripts/dev-server-status.mjs +34 -13
  142. package/scripts/dev-server-stop.mjs +313 -0
  143. package/scripts/heyspex-mode.mjs +268 -0
  144. package/scripts/hs-auto-resolve.mjs +240 -0
  145. package/scripts/hs-auto-source.mjs +398 -0
  146. package/scripts/hs-auto.mjs +134 -0
  147. package/scripts/hs-capture-cli.mjs +326 -0
  148. package/scripts/hs-classifier.mjs +136 -0
  149. package/scripts/hs-companion.mjs +88 -0
  150. package/scripts/hs-gateway.mjs +115 -0
  151. package/scripts/hs-mode.mjs +125 -0
  152. package/scripts/hs-next.mjs +441 -0
  153. package/scripts/hs-settings.mjs +338 -0
  154. package/scripts/hs-view.mjs +333 -0
  155. package/scripts/hs-worktree.mjs +201 -0
  156. package/scripts/install-claude-code-hooks.mjs +270 -0
  157. package/scripts/install-cursor-hooks.mjs +471 -0
  158. package/scripts/lib/agent-env-markers.mjs +38 -0
  159. package/scripts/lib/console-url-resolver.mjs +197 -60
  160. package/scripts/lib/customer-kit.mjs +886 -0
  161. package/scripts/lib/dev-mode.mjs +244 -28
  162. package/scripts/lib/heyspex-home.mjs +72 -0
  163. package/scripts/lib/hs-command.mjs +277 -0
  164. package/scripts/lib/hs-companion-settings.mjs +472 -0
  165. package/scripts/lib/hs-source-commit.mjs +59 -5
  166. package/scripts/lib/hs-source-identity.mjs +526 -0
  167. package/scripts/lib/hs-source-log.mjs +11 -21
  168. package/scripts/lib/hs-source-push.mjs +107 -58
  169. package/scripts/lib/hs-worktree-args.mjs +115 -0
  170. package/scripts/lib/shared-path-helpers.mjs +134 -0
  171. package/scripts/lib/standalone-doctor.mjs +540 -3
  172. package/scripts/lib/subagent-git-lock.mjs +109 -0
  173. package/scripts/lib/template-pin.mjs +34 -0
  174. package/scripts/provenance-lib.mjs +91 -0
  175. package/scripts/stamp-provenance-on-edit.mjs +222 -0
  176. package/scripts/wip-ledger-health.mjs +653 -0
  177. package/spexharness/doctrine/baseline/SPEXCODE-DOCTRINE.baseline.json +29 -0
  178. package/spexharness/src/adapters/audit.mjs +197 -0
  179. package/spexharness/src/adapters/claude-code.mjs +441 -0
  180. package/spexharness/src/chat/tui/ansi.mjs +448 -0
  181. package/spexharness/src/chat/tui/palette.mjs +22 -0
  182. package/spexharness/src/chat/tui/select.mjs +208 -0
  183. package/spexharness/src/config-root.mjs +54 -0
  184. package/spexharness/src/context-budget.mjs +141 -0
  185. package/spexharness/src/dev-server-control.mjs +389 -0
  186. package/spexharness/src/doctrine/behaviour.mjs +371 -0
  187. package/spexharness/src/doctrine/corpus.mjs +733 -0
  188. package/spexharness/src/doctrine/inject.mjs +338 -0
  189. package/spexharness/src/doctrine/merge.mjs +184 -0
  190. package/spexharness/src/doctrine/sources.mjs +252 -0
  191. package/spexharness/src/doctrine/synthesize.mjs +401 -0
  192. package/spexharness/src/doctrine/vault-source.mjs +574 -0
  193. package/spexharness/src/doctrine/writer.mjs +176 -0
  194. package/spexharness/src/events.mjs +84 -0
  195. package/spexharness/src/gates/capture-workflow-gate.mjs +202 -0
  196. package/spexharness/src/gates/claim-before-code-gate.decide.mjs +33 -0
  197. package/spexharness/src/gates/claim-before-code-gate.mjs +129 -0
  198. package/spexharness/src/gates/deep-research-cost-gate.mjs +274 -0
  199. package/spexharness/src/gates/enforce-session-sequence.mjs +895 -0
  200. package/spexharness/src/gates/enforce-vault-naming.mjs +215 -0
  201. package/spexharness/src/gates/epic-milestone-phrasing-gate.mjs +233 -0
  202. package/spexharness/src/gates/git-identity-guard.decide.mjs +436 -0
  203. package/spexharness/src/gates/git-identity-guard.mjs +61 -0
  204. package/spexharness/src/gates/git-reflog-audit.mjs +151 -0
  205. package/spexharness/src/gates/git-stash-gate.decide.mjs +361 -0
  206. package/spexharness/src/gates/git-stash-gate.mjs +159 -0
  207. package/spexharness/src/gates/id-display-format-gate.mjs +190 -0
  208. package/spexharness/src/gates/inject-doctrine-gate.mjs +89 -0
  209. package/spexharness/src/gates/inject-vault-context.mjs +239 -0
  210. package/spexharness/src/gates/naughty-list-gate.mjs +213 -0
  211. package/spexharness/src/gates/plan-review-gate.mjs +233 -0
  212. package/spexharness/src/gates/preflight-reminder-gate.mjs +265 -0
  213. package/spexharness/src/gates/research-protocol-gate.mjs +175 -0
  214. package/spexharness/src/gates/settings-write-gate.decide.mjs +96 -0
  215. package/spexharness/src/gates/settings-write-gate.mjs +104 -0
  216. package/spexharness/src/git-reflog-audit.mjs +294 -0
  217. package/spexharness/src/intent-classifier.mjs +194 -0
  218. package/spexharness/src/intent-directive.mjs +541 -0
  219. package/spexharness/src/profile/learn.mjs +551 -0
  220. package/spexharness/src/profile/proposals.mjs +357 -0
  221. package/spexharness/src/profile/vault-inclusion.mjs +386 -0
  222. package/spexharness/src/redact.mjs +151 -0
  223. package/spexharness/src/rule-table.mjs +819 -0
  224. package/spexharness/src/seat-context.mjs +122 -0
  225. package/spexharness/src/session-bootstrap.mjs +512 -0
  226. package/spexharness/src/session-record.mjs +815 -0
  227. package/spexharness/src/token-inventory.mjs +207 -0
  228. package/vendor/heyspex-mcp/account-switch.mjs +95 -0
  229. package/vendor/heyspex-mcp/alignment-gate.mjs +315 -1
  230. package/vendor/heyspex-mcp/blocker-resolver.mjs +37 -2
  231. package/vendor/heyspex-mcp/breakdown-ladder.mjs +119 -4
  232. package/vendor/heyspex-mcp/breakdown-source.mjs +271 -0
  233. package/vendor/heyspex-mcp/breakdown-writer.mjs +23 -3
  234. package/vendor/heyspex-mcp/capture-buffer-patches.mjs +46 -5
  235. package/vendor/heyspex-mcp/capture-channel.mjs +55 -5
  236. package/vendor/heyspex-mcp/capture-console-client.mjs +80 -1
  237. package/vendor/heyspex-mcp/capture-focus.mjs +1035 -29
  238. package/vendor/heyspex-mcp/capture-outbox.mjs +5 -1
  239. package/vendor/heyspex-mcp/capture-tools.mjs +1219 -0
  240. package/vendor/heyspex-mcp/claim-tools.mjs +1124 -0
  241. package/vendor/heyspex-mcp/cli-verbs.mjs +2076 -0
  242. package/vendor/heyspex-mcp/cli.mjs +201 -15524
  243. package/vendor/heyspex-mcp/cloud-tool-surface.mjs +128 -0
  244. package/vendor/heyspex-mcp/cloud-vault-writes.mjs +412 -0
  245. package/vendor/heyspex-mcp/config-seed.yaml +15 -0
  246. package/vendor/heyspex-mcp/config-settings.mjs +290 -7
  247. package/vendor/heyspex-mcp/console-fetch.mjs +657 -16
  248. package/vendor/heyspex-mcp/console-transport.mjs +166 -0
  249. package/vendor/heyspex-mcp/credentials.mjs +584 -0
  250. package/vendor/heyspex-mcp/defer-spec.mjs +44 -4
  251. package/vendor/heyspex-mcp/deferred-reclaim.mjs +29 -3
  252. package/vendor/heyspex-mcp/design-handlers.mjs +31 -0
  253. package/vendor/heyspex-mcp/design-tools.mjs +4 -1
  254. package/vendor/heyspex-mcp/dev-factory-bridge.mjs +4 -4
  255. package/vendor/heyspex-mcp/dev-mode-core.mjs +45 -0
  256. package/vendor/heyspex-mcp/dev-tools.mjs +124 -0
  257. package/vendor/heyspex-mcp/diagnose-handlers.mjs +54 -0
  258. package/vendor/heyspex-mcp/events-tools.mjs +207 -0
  259. package/vendor/heyspex-mcp/filing-tools.mjs +688 -0
  260. package/vendor/heyspex-mcp/fleet-handlers.mjs +37 -0
  261. package/vendor/heyspex-mcp/fleet-queue-tools.mjs +69 -14
  262. package/vendor/heyspex-mcp/focus-tools.mjs +190 -0
  263. package/vendor/heyspex-mcp/folder-trust-store.mjs +59 -0
  264. package/vendor/heyspex-mcp/http-transport.mjs +300 -0
  265. package/vendor/heyspex-mcp/list-tools.mjs +257 -0
  266. package/vendor/heyspex-mcp/login-handoff.mjs +15 -1
  267. package/vendor/heyspex-mcp/mcp-config.mjs +94 -0
  268. package/vendor/heyspex-mcp/memory-tools.mjs +523 -0
  269. package/vendor/heyspex-mcp/mvp-mode.mjs +53 -6
  270. package/vendor/heyspex-mcp/occupied-keys.mjs +141 -0
  271. package/vendor/heyspex-mcp/on-deck-brief.mjs +3360 -0
  272. package/vendor/heyspex-mcp/on-deck-scheduler.mjs +1708 -0
  273. package/vendor/heyspex-mcp/package-root.mjs +32 -0
  274. package/vendor/heyspex-mcp/peer-presence.mjs +8 -1
  275. package/vendor/heyspex-mcp/plan-ground.mjs +621 -652
  276. package/vendor/heyspex-mcp/plan-push.mjs +906 -21
  277. package/vendor/heyspex-mcp/plan-review.mjs +124 -30
  278. package/vendor/heyspex-mcp/preflight-gate.mjs +0 -0
  279. package/vendor/heyspex-mcp/procedure-handlers.mjs +325 -0
  280. package/vendor/heyspex-mcp/procedure-tools.mjs +540 -351
  281. package/vendor/heyspex-mcp/promote-capture.mjs +386 -69
  282. package/vendor/heyspex-mcp/promote-diagnose.mjs +74 -0
  283. package/vendor/heyspex-mcp/promote-research-to-diagnose.mjs +9 -2
  284. package/vendor/heyspex-mcp/promote-research.mjs +660 -53
  285. package/vendor/heyspex-mcp/promotion-helpers.mjs +251 -0
  286. package/vendor/heyspex-mcp/prompts.mjs +1460 -0
  287. package/vendor/heyspex-mcp/read-path.mjs +29 -9
  288. package/vendor/heyspex-mcp/receipt-shape.mjs +146 -0
  289. package/vendor/heyspex-mcp/recipe-handlers.mjs +117 -0
  290. package/vendor/heyspex-mcp/regen-tasks.mjs +210 -3
  291. package/vendor/heyspex-mcp/register-spec.mjs +266 -54
  292. package/vendor/heyspex-mcp/request-context.mjs +59 -0
  293. package/vendor/heyspex-mcp/research-focus.mjs +207 -4
  294. package/vendor/heyspex-mcp/research-handlers.mjs +623 -0
  295. package/vendor/heyspex-mcp/research-tools.mjs +4 -4
  296. package/vendor/heyspex-mcp/response-budget.mjs +348 -0
  297. package/vendor/heyspex-mcp/review-focus.mjs +25 -1
  298. package/vendor/heyspex-mcp/search-specs.mjs +280 -0
  299. package/vendor/heyspex-mcp/seat-block-ledger.mjs +113 -0
  300. package/vendor/heyspex-mcp/seat-identity.mjs +2 -6
  301. package/vendor/heyspex-mcp/session-owner.mjs +108 -0
  302. package/vendor/heyspex-mcp/session-tools.mjs +152 -0
  303. package/vendor/heyspex-mcp/settings-registry.mjs +232 -0
  304. package/vendor/heyspex-mcp/settings-tools.mjs +85 -12
  305. package/vendor/heyspex-mcp/spec-edit-tools.mjs +446 -0
  306. package/vendor/heyspex-mcp/spec-id-lib.mjs +93 -17
  307. package/vendor/heyspex-mcp/split-research.mjs +301 -56
  308. package/vendor/heyspex-mcp/stdio-rpc.mjs +22 -0
  309. package/vendor/heyspex-mcp/submit-for-review.mjs +132 -6
  310. package/vendor/heyspex-mcp/summary-contract.mjs +105 -0
  311. package/vendor/heyspex-mcp/summary-write-tools.mjs +224 -0
  312. package/vendor/heyspex-mcp/symptom-query.mjs +146 -0
  313. package/vendor/heyspex-mcp/test-helpers.mjs +108 -1
  314. package/vendor/heyspex-mcp/tool-catalog.mjs +2813 -0
  315. package/vendor/heyspex-mcp/tool-dispatch.mjs +639 -0
  316. package/vendor/heyspex-mcp/tool-helpers.mjs +325 -0
  317. package/vendor/heyspex-mcp/validate-linkage.mjs +414 -27
  318. package/vendor/heyspex-mcp/vault-io.mjs +724 -0
  319. package/vendor/heyspex-mcp/vault-less-endpoints.mjs +52 -0
  320. package/vendor/heyspex-mcp/vault-resolve.mjs +366 -68
  321. package/vendor/heyspex-mcp/verify-reproduction.mjs +270 -30
  322. package/vendor/heyspex-mcp/whoami.mjs +91 -0
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ // Thin shell over the spexharness engine port of this gate (wave 6 of
3
+ // [[HS-AZ61-NYPR]]). Same shape as the twelve shells
4
+ // scripts/generate-hook-shells.mjs writes; this one is authored rather than
5
+ // generated only because it is not part of that generator's frozen twelve.
6
+ // To change what this gate DECIDES, edit
7
+ // spexharness/src/gates/dev-server-task-reminder.mjs. The classification, the
8
+ // worktree bypass, the front read and the fleet-queue claim wrapper live in
9
+ // spexharness/src/dev-server-control.mjs — one copy in the tree, shared by the
10
+ // gate, this shell, and ./dev-server-task-reminder.smoke.mjs.
11
+
12
+ import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
13
+ import gate from '../../spexharness/src/gates/dev-server-task-reminder.mjs';
14
+
15
+ await runGateAsHook(gate);
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env node
2
+ // Claude Code + Cursor CLI hook → console claim-status / heartbeat emitter.
3
+ // ([[HS-TASK-P89W]] / [[HS-EPIC-2BKX]] / [[HS-TASK-A3FE]] producer path)
4
+ //
5
+ // Resolves the agent session id from stdin payload + host env, then PATCHes
6
+ // `/api/control/active-claims/heartbeat` (tier-dispatched — works on Neon and
7
+ // free-file tiers). Does NOT read `.heyspex/active-claims.json`.
8
+ //
9
+ // MUST exit 0 on every failure path — a hook that breaks the agent is worse
10
+ // than a hook that silently does nothing.
11
+ //
12
+ // CLI: emit-claim-status.mjs [--event=PreToolUse|preToolUse|Stop|stop|PostToolUse|postToolUse]
13
+ // --event is optional; falls back to stdin.hook_event_name.
14
+
15
+ import {
16
+ emitClaimLivenessFromHook,
17
+ parseArgs,
18
+ readStdin,
19
+ } from './claim-liveness-shared.mjs';
20
+
21
+ async function main() {
22
+ const args = parseArgs(process.argv);
23
+ const stdinRaw = await readStdin();
24
+ let payload = null;
25
+ if (stdinRaw) {
26
+ try {
27
+ payload = JSON.parse(stdinRaw);
28
+ } catch {
29
+ // Non-JSON stdin — proceed with null payload; event must come from --event.
30
+ }
31
+ }
32
+
33
+ await emitClaimLivenessFromHook({
34
+ eventArg: args.event,
35
+ payload,
36
+ });
37
+ }
38
+
39
+ main().catch(() => {
40
+ // Swallow — never break the host agent on a hook failure.
41
+ });
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ // GENERATED by scripts/generate-hook-shells.mjs (HS-IQBF) — do not hand-edit.
3
+ // This file only wires Claude Code's hook stdin/stdout contract to the
4
+ // spexharness engine port of this gate. To change what this gate DECIDES,
5
+ // edit spexharness/src/gates/enforce-session-sequence.mjs. To change the SHAPE of this shell,
6
+ // edit the generator, then rerun: node scripts/generate-hook-shells.mjs
7
+
8
+ import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
9
+ import gate from '../../spexharness/src/gates/enforce-session-sequence.mjs';
10
+
11
+ await runGateAsHook(gate);
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ // GENERATED by scripts/generate-hook-shells.mjs (HS-IQBF) — do not hand-edit.
3
+ // This file only wires Claude Code's hook stdin/stdout contract to the
4
+ // spexharness engine port of this gate. To change what this gate DECIDES,
5
+ // edit spexharness/src/gates/enforce-vault-naming.mjs. To change the SHAPE of this shell,
6
+ // edit the generator, then rerun: node scripts/generate-hook-shells.mjs
7
+
8
+ import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
9
+ import gate from '../../spexharness/src/gates/enforce-vault-naming.mjs';
10
+
11
+ await runGateAsHook(gate);
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ // GENERATED by scripts/generate-hook-shells.mjs (HS-IQBF) — do not hand-edit.
3
+ // This file only wires Claude Code's hook stdin/stdout contract to the
4
+ // spexharness engine port of this gate. To change what this gate DECIDES,
5
+ // edit spexharness/src/gates/env-vault-guard.mjs. To change the SHAPE of this shell,
6
+ // edit the generator, then rerun: node scripts/generate-hook-shells.mjs
7
+
8
+ import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
9
+ import gate from '../../spexharness/src/gates/env-vault-guard.mjs';
10
+
11
+ await runGateAsHook(gate);
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ // GENERATED by scripts/generate-hook-shells.mjs (HS-IQBF) — do not hand-edit.
3
+ // This file only wires Claude Code's hook stdin/stdout contract to the
4
+ // spexharness engine port of this gate. To change what this gate DECIDES,
5
+ // edit spexharness/src/gates/epic-milestone-phrasing-gate.mjs. To change the SHAPE of this shell,
6
+ // edit the generator, then rerun: node scripts/generate-hook-shells.mjs
7
+
8
+ import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
9
+ import gate from '../../spexharness/src/gates/epic-milestone-phrasing-gate.mjs';
10
+
11
+ await runGateAsHook(gate);
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ // GENERATED by scripts/generate-hook-shells.mjs (HS-IQBF) — do not hand-edit.
3
+ // This file only wires Claude Code's hook stdin/stdout contract to the
4
+ // spexharness engine port of this gate. To change what this gate DECIDES,
5
+ // edit spexharness/src/gates/git-identity-guard.mjs. To change the SHAPE of this shell,
6
+ // edit the generator, then rerun: node scripts/generate-hook-shells.mjs
7
+
8
+ import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
9
+ import gate from '../../spexharness/src/gates/git-identity-guard.mjs';
10
+
11
+ await runGateAsHook(gate);
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ // Thin shell over the spexharness engine port of this gate (wave 6 of
3
+ // [[HS-AZ61-NYPR]]). `.claude/settings.json` wires this ONE script to BOTH
4
+ // SessionStart and Stop, so it uses `runGatesAsHook` — read stdin once, run
5
+ // whichever of the pair is registered for the incoming event.
6
+ //
7
+ // To change what this gate DECIDES, edit
8
+ // spexharness/src/gates/git-reflog-audit.mjs. The reflog/stash audit logic
9
+ // itself lives in spexharness/src/git-reflog-audit.mjs — one copy in the tree,
10
+ // shared by the gate, this shell, and ./git-reflog-audit.test.mjs.
11
+
12
+ import { runGatesAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
13
+ import gate, { snapshotGate } from '../../spexharness/src/gates/git-reflog-audit.mjs';
14
+
15
+ await runGatesAsHook([snapshotGate, gate]);
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ // GENERATED by scripts/generate-hook-shells.mjs (HS-IQBF) — do not hand-edit.
3
+ // This file only wires Claude Code's hook stdin/stdout contract to the
4
+ // spexharness engine port of this gate. To change what this gate DECIDES,
5
+ // edit spexharness/src/gates/git-stash-gate.mjs. To change the SHAPE of this shell,
6
+ // edit the generator, then rerun: node scripts/generate-hook-shells.mjs
7
+
8
+ import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
9
+ import gate from '../../spexharness/src/gates/git-stash-gate.mjs';
10
+
11
+ await runGateAsHook(gate);
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env node
2
+ // Claude Code PreToolUse hook → keeps the Claude Code auto-memory directory thin by
3
+ // blocking NEW topic-file creation there, redirecting durable HeySpex knowledge to
4
+ // the vault.
5
+ //
6
+ // Per the retention policy ([[auto-memory-index-hygiene]] / [[HS-VN9W-RES]]) the
7
+ // auto-memory index (~/.claude/projects/<repo>/memory/) is a curated working-set +
8
+ // ROUTER over the vault — NOT a store. Durable HeySpex facts belong in the vault
9
+ // (specs/memory/, via heyspex_file_spec), which is served dynamically by
10
+ // heyspex_recall_memories. Writing new `<slug>.md` topic files into the auto-memory
11
+ // dir is what re-bloats the always-loaded index over time (each new topic file earns
12
+ // an index line). This hook is the prevention half; the self-heal pass in
13
+ // check-auto-memory-budget.mjs is the cure half.
14
+ //
15
+ // What is blocked: creating a NEW `.md` topic file (anything other than MEMORY.md)
16
+ // under `…/.claude/projects/<repo>/memory/`.
17
+ // What is allowed: writing MEMORY.md itself (the router line + sanctioned pinned
18
+ // working set), and Edit on any existing file (migrations, pinned-set tweaks).
19
+ //
20
+ // Env:
21
+ // HEYSPEX_AUTO_MEMORY_WRITE_GUARD_OFF=1 kill switch — never blocks.
22
+ //
23
+ // Stdin: Claude Code hook JSON ({tool_name, tool_input, ...}).
24
+ // Exit 0 = allow. Exit 2 = block (stderr surfaces back to the model).
25
+ // FAIL-SAFE: any internal error → exit 0 (never strand the agent).
26
+
27
+ import path from 'node:path';
28
+
29
+ // Matches a path inside a Claude Code auto-memory dir: `…/.claude/projects/<repo>/memory/`.
30
+ // Tolerant of either path separator (Windows or POSIX) in the raw tool input.
31
+ const AUTO_MEMORY_DIR_RE = /[\\/]\.claude[\\/]projects[\\/][^\\/]+[\\/]memory[\\/]/i;
32
+
33
+ function isGuardedTopicFile(p) {
34
+ if (!p || typeof p !== 'string') return false;
35
+ if (!AUTO_MEMORY_DIR_RE.test(p)) return false;
36
+ const base = path.basename(p);
37
+ if (!/\.md$/i.test(base)) return false; // only markdown topic files
38
+ if (base.toUpperCase() === 'MEMORY.MD') return false; // the index itself is allowed
39
+ return true;
40
+ }
41
+
42
+ // Heuristic shell scanner — pulls file-creation targets out of common Bash /
43
+ // PowerShell idioms so a topic file written via `echo > slug.md` or `New-Item`
44
+ // can't sneak past the Write|NotebookEdit guard. Mirrors the conservative scanner
45
+ // in enforce-vault-naming.mjs. Conservative by design: a missed target only means
46
+ // the guard stays silent (fail-open), never a false block of legitimate work.
47
+ function extractShellTargets(command) {
48
+ if (!command || typeof command !== 'string') return [];
49
+ const targets = new Set();
50
+
51
+ // 1. Redirects: `> path` / `>> path` / `| tee path` / `| tee -a path`.
52
+ const redirectRe = /(?:>>?|\|\s*tee(?:\s+-a)?)\s+("([^"]+)"|'([^']+)'|(\S+))/g;
53
+ for (const m of command.matchAll(redirectRe)) targets.add(m[2] ?? m[3] ?? m[4]);
54
+
55
+ // 2. mv / cp / touch / install / Set-Content / New-Item etc. — destination args.
56
+ const cmdRe =
57
+ /\b(?:mv|cp|touch|install|rename|tee|Move-Item|Copy-Item|New-Item|Set-Content|Out-File|Add-Content)\s+([^|;&\n]+)/g;
58
+ for (const m of command.matchAll(cmdRe)) {
59
+ const head = m[0].split(/\s/)[0];
60
+ const args = m[1]
61
+ .trim()
62
+ .split(/\s+/)
63
+ .filter((a) => a && !a.startsWith('-'));
64
+ if (args.length === 0) continue;
65
+ if (/^(?:mv|cp|install|rename|Move-Item|Copy-Item)$/.test(head)) {
66
+ targets.add(args[args.length - 1]); // last arg is the destination
67
+ } else {
68
+ for (const a of args) targets.add(a); // touch / New-Item / *-Content: each is a target
69
+ }
70
+ }
71
+
72
+ return [...targets]
73
+ .map((t) => t.replace(/^['"]|['"]$/g, ''))
74
+ .filter(Boolean)
75
+ .filter((t) => !/[$`(){}]/.test(t)); // skip command substitutions / non-paths
76
+ }
77
+
78
+ function reason(p) {
79
+ return [
80
+ `HeySpex auto-memory guard: ${p}`,
81
+ ` The Claude Code auto-memory directory is a thin curated index + router over the`,
82
+ ` vault — not a knowledge store. Do NOT create new topic files here; durable HeySpex`,
83
+ ` facts belong in the vault and load on demand via heyspex_recall_memories.`,
84
+ ` → File this as a vault memory instead: heyspex_file_spec`,
85
+ ` (memory-lesson / memory-decision / memory-reference / memory-ui-pattern).`,
86
+ ` → A genuinely machine-local fact (this physical box's hardware, a per-machine path)`,
87
+ ` goes to the vault as a memory-reference tagged 'machine-local'.`,
88
+ ` Only MEMORY.md (the router line + sanctioned [pinned] working set) lives here.`,
89
+ ` See specs/protocols/auto-memory-index-hygiene.md.`,
90
+ ].join('\n');
91
+ }
92
+
93
+ async function readStdinJson() {
94
+ if (process.stdin.isTTY) return null;
95
+ let buf = '';
96
+ process.stdin.setEncoding('utf8');
97
+ for await (const chunk of process.stdin) buf += chunk;
98
+ if (!buf.trim()) return null;
99
+ try {
100
+ return JSON.parse(buf);
101
+ } catch {
102
+ return null;
103
+ }
104
+ }
105
+
106
+ function block(msg) {
107
+ process.stderr.write(`\n[HeySpex auto-memory guard]\n${msg}\n`);
108
+ process.exit(2);
109
+ }
110
+
111
+ async function main() {
112
+ if (process.env.HEYSPEX_AUTO_MEMORY_WRITE_GUARD_OFF === '1') return;
113
+
114
+ const payload = await readStdinJson();
115
+ if (!payload) return;
116
+
117
+ const toolName = payload.tool_name;
118
+ const input = payload.tool_input ?? {};
119
+
120
+ // Only guard file CREATION. Edit/MultiEdit on existing files is fine (migrations,
121
+ // pinned-set tweaks); the file already exists, so it is not new re-bloat.
122
+ let targets = [];
123
+ if (toolName === 'Write') targets = [input.file_path];
124
+ else if (toolName === 'NotebookEdit') targets = [input.notebook_path];
125
+ else if (toolName === 'Bash' || toolName === 'PowerShell')
126
+ targets = extractShellTargets(input.command); // close the shell-redirect bypass
127
+ else return; // unrelated tool
128
+
129
+ for (const target of targets) {
130
+ if (isGuardedTopicFile(target)) block(reason(target)); // block() exits on first hit
131
+ }
132
+ }
133
+
134
+ main().catch(() => {
135
+ // Fail-open: never block legitimate work on a hook crash.
136
+ process.exit(0);
137
+ });
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ // GENERATED by scripts/generate-hook-shells.mjs (HS-IQBF) — do not hand-edit.
3
+ // This file only wires Claude Code's hook stdin/stdout contract to the
4
+ // spexharness engine port of this gate. To change what this gate DECIDES,
5
+ // edit spexharness/src/gates/id-display-format-gate.mjs. To change the SHAPE of this shell,
6
+ // edit the generator, then rerun: node scripts/generate-hook-shells.mjs
7
+
8
+ import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
9
+ import gate from '../../spexharness/src/gates/id-display-format-gate.mjs';
10
+
11
+ await runGateAsHook(gate);
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env node
2
+ // Claude Code hook → RETIRED UserPromptSubmit injection of the OWNER COMMUNICATION STYLE rules.
3
+ //
4
+ // RETIRED (HS-XIYJ, epic HS-1YDJ, 2026-09-09).
5
+ //
6
+ // WHY THIS EXISTED
7
+ // -----------------
8
+ // This hook used to inject the compiled `communication-style-prime` rule's full prose
9
+ // (specs/protocols/communication-style-protocol.md, ~3.0 KB) into EVERY UserPromptSubmit
10
+ // turn, unconditionally — added after the owner asked for plain English twice (2026-08-11,
11
+ // 2026-08-14; see git history for the full rationale) because a memory lesson and a
12
+ // preflight reminder both failed to reach an ordinary interactive turn.
13
+ //
14
+ // WHY IT IS RETIRED NOW
15
+ // ----------------------
16
+ // The epic measured this hook as ~3.0 KB of every single prompt's budget, on top of the
17
+ // intent classifier's own per-prompt cost (HS-5ISS) — together the largest mechanical, non-
18
+ // content share of a seat's context window. The voice epic's first profile is the intended
19
+ // replacement mechanism for carrying writing-style behavior across turns without re-teaching
20
+ // it every one; this task's job is narrower — make the injection actually stop, and prove it
21
+ // stopped via measurement (spexharness/src/context-budget.mjs, HS-7UAQ) rather than just
22
+ // trusting a diff.
23
+ //
24
+ // THIS FILE IS KEPT, NOT DELETED
25
+ // -------------------------------
26
+ // `.claude/settings.json` still names `inject-communication-style` as the UserPromptSubmit
27
+ // hook and scripts/claude-hooks/_run.mjs dispatches to it by that name on every prompt —
28
+ // deleting the file would turn a silent no-op into a "hook not found" stderr line on every
29
+ // turn instead. `main()` below now ALWAYS returns without emitting anything; the decision
30
+ // lives in {@link shouldInject}, a one-line function kept separate from `main()` so a test
31
+ // can assert the retirement directly instead of only inferring it from captured stdout, and
32
+ // so any future un-retirement is a one-line change here rather than a rewrite.
33
+ //
34
+ // HEYSPEX_COMMUNICATION_STYLE_OFF=1 Historical kill switch — still honored
35
+ // (checked first, same as before), though
36
+ // shouldInject() already returns false
37
+ // unconditionally regardless of its value.
38
+ // agent_behaviors.communication_style.enabled Historical config toggle — no longer read;
39
+ // the registry lookup this hook used to do
40
+ // is gone, so a stale/missing/corrupt
41
+ // .heyspex/guardrails.json can no longer
42
+ // affect this hook either way.
43
+
44
+ /**
45
+ * Should this hook inject the communication-style prose? Retired: always false. Kept as a
46
+ * named export (rather than inlined into `main()`) so this is the ONE place the retirement
47
+ * decision lives, and a test asserts it directly.
48
+ * @returns {boolean}
49
+ */
50
+ export function shouldInject() {
51
+ return false;
52
+ }
53
+
54
+ /**
55
+ * The hook body. Reads nothing and writes nothing — retirement means there is no longer
56
+ * anything for it to read the payload FOR. Exported so a test can call it directly and
57
+ * capture stdout around it.
58
+ * @returns {Promise<void>}
59
+ */
60
+ export async function main() {
61
+ if (!shouldInject()) return; // retired — see module header.
62
+ }
63
+
64
+ main().catch(() => {
65
+ // Never break Claude Code on a hook failure.
66
+ });
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env node
2
+ // Claude Code hook → SessionStart injection of dev-factory seat mandates.
3
+ //
4
+ // Reads the seats registry at dev-factory/seats.json. When settings.cooMode is
5
+ // true, injects one line per ACTIVE seat so every new session opens already
6
+ // holding its seat (delegate-first COO orchestration) without being told:
7
+ //
8
+ // DEV-FACTORY SEAT: <title> — <mandate>
9
+ //
10
+ // Toggle lives in the console at Settings > ADMIN > Dev-Factory (persisted via
11
+ // PATCH /api/admin/factory/seats). Hard requirements honored here:
12
+ // - additive: registered as its OWN SessionStart hook entry; the existing
13
+ // dev-server awareness injection (inject-dev-server-awareness.mjs) is untouched.
14
+ // - non-fatal: missing/corrupt seats.json, cooMode false, or no active seats
15
+ // → inject nothing and exit 0 (the fail-silent hook contract).
16
+ // - fast: one local file read; no network calls.
17
+ // HEYSPEX_COO_SEAT_OFF=1 Kill switch — exits silently.
18
+ //
19
+ // Output shape (same as the sibling SessionStart hooks):
20
+ // { hookSpecificOutput: { hookEventName, additionalContext } }
21
+
22
+ // buildSeatContext + repoRoot moved to the shared lib so Command Code
23
+ // (sync into COMMANDCODE.md) and Cursor (sync into a .cursor rule) inject the
24
+ // byte-identical seat context — see dev-factory/lib/seat-context.mjs.
25
+ import { buildSeatContext } from '../../dev-factory/lib/seat-context.mjs';
26
+
27
+ async function readStdinJson() {
28
+ if (process.stdin.isTTY) return null;
29
+ return new Promise((resolve) => {
30
+ let buf = '';
31
+ let settled = false;
32
+ const finish = (value) => {
33
+ if (settled) return;
34
+ settled = true;
35
+ resolve(value);
36
+ };
37
+ const timer = setTimeout(() => finish(buf || ''), 200);
38
+ process.stdin.setEncoding('utf8');
39
+ process.stdin.on('data', (chunk) => {
40
+ buf += chunk;
41
+ });
42
+ process.stdin.on('end', () => {
43
+ clearTimeout(timer);
44
+ finish(buf);
45
+ });
46
+ process.stdin.on('error', () => {
47
+ clearTimeout(timer);
48
+ finish(buf);
49
+ });
50
+ });
51
+ }
52
+
53
+ function emit(eventName, additionalContext) {
54
+ process.stdout.write(
55
+ JSON.stringify({ hookSpecificOutput: { hookEventName: eventName, additionalContext } }),
56
+ );
57
+ }
58
+
59
+ async function main() {
60
+ if (process.env.HEYSPEX_COO_SEAT_OFF === '1') return;
61
+ const context = buildSeatContext();
62
+ if (!context) return; // cooMode off / no registry / no active seats
63
+ const raw = await readStdinJson();
64
+ let event = 'SessionStart';
65
+ if (raw) {
66
+ try {
67
+ const payload = JSON.parse(raw);
68
+ if (payload?.hook_event_name) event = payload.hook_event_name;
69
+ } catch {
70
+ // Non-JSON stdin — default to SessionStart and emit anyway.
71
+ }
72
+ }
73
+ emit(event, context);
74
+ }
75
+
76
+ main().catch(() => {
77
+ // Never break Claude Code on a hook failure.
78
+ });
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ // GENERATED by scripts/generate-hook-shells.mjs (HS-IQBF) — do not hand-edit.
3
+ // This file only wires Claude Code's hook stdin/stdout contract to the
4
+ // spexharness engine port of this gate. To change what this gate DECIDES,
5
+ // edit spexharness/src/gates/dev-server-awareness-gate.mjs. To change the SHAPE of this shell,
6
+ // edit the generator, then rerun: node scripts/generate-hook-shells.mjs
7
+
8
+ import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
9
+ import gate from '../../spexharness/src/gates/dev-server-awareness-gate.mjs';
10
+
11
+ await runGateAsHook(gate);
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ // Thin shell over the spexharness engine gate (HS-X3S1, DR3). Same shape as
3
+ // inject-vault-context.mjs's own shell — this one is authored rather than
4
+ // generated (like that one) because it is not part of
5
+ // scripts/generate-hook-shells.mjs's frozen twelve. To change what this
6
+ // injection DECIDES, edit spexharness/src/gates/inject-doctrine-gate.mjs
7
+ // (the rendering itself lives in spexharness/src/doctrine/inject.mjs, shared
8
+ // with every SpexCode seat's own bootstrap — session-bootstrap.mjs).
9
+
10
+ import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
11
+ import gate from '../../spexharness/src/gates/inject-doctrine-gate.mjs';
12
+
13
+ await runGateAsHook(gate);
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ // Thin shell over the spexharness engine port of this gate (wave 6 of
3
+ // [[HS-AZ61-NYPR]]). Same shape as the twelve shells
4
+ // scripts/generate-hook-shells.mjs writes; this one is authored rather than
5
+ // generated only because it is not part of that generator's frozen twelve.
6
+ // To change what this gate DECIDES, edit
7
+ // spexharness/src/gates/inject-vault-context.mjs (the scoring stays in
8
+ // ./_vault-retrieval.mjs; the byte accounting in
9
+ // spexharness/src/context-budget.mjs).
10
+
11
+ import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
12
+ import gate from '../../spexharness/src/gates/inject-vault-context.mjs';
13
+
14
+ await runGateAsHook(gate);