heyspex 0.1.0 → 0.2.1

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 (352) hide show
  1. package/.claude-plugin/marketplace.json +14 -0
  2. package/README.md +21 -0
  3. package/bin/hs.mjs +1089 -104
  4. package/bin/spexcode.mjs +262 -0
  5. package/dev-factory/engine/worktree.mjs +740 -0
  6. package/dev-factory/lib/code-repo-root.mjs +67 -0
  7. package/dev-factory/lib/context-budget.mjs +84 -0
  8. package/dev-factory/lib/epic-detect.mjs +190 -0
  9. package/dev-factory/lib/fleet-queue-file.mjs +846 -0
  10. package/dev-factory/lib/fleet-queue.mjs +426 -0
  11. package/dev-factory/lib/fleet-state.mjs +14 -18
  12. package/dev-factory/lib/model-catalog.mjs +338 -0
  13. package/dev-factory/lib/seat-context.mjs +199 -0
  14. package/dev-factory/lib/spec-io.mjs +93 -0
  15. package/dev-factory/lib/sufficiency-score.mjs +8 -2
  16. package/dev-factory/lib/worktree-allocator.mjs +744 -0
  17. package/dev-factory/model-catalog.json +222 -0
  18. package/dist/cli/hs-check.mjs +1127 -103
  19. package/dist/cli/hs-claim.mjs +981 -63
  20. package/dist/cli/hs-connect.mjs +10059 -1729
  21. package/dist/cli/hs-defer.mjs +5507 -3072
  22. package/dist/cli/hs-dev.mjs +576 -0
  23. package/dist/cli/hs-env.mjs +416 -302
  24. package/dist/cli/hs-index-rebuild.mjs +7334 -0
  25. package/dist/cli/hs-index-reconcile.mjs +8138 -0
  26. package/dist/cli/hs-init.mjs +2840 -149
  27. package/dist/cli/hs-install.mjs +7214 -594
  28. package/dist/cli/hs-join.mjs +10640 -2421
  29. package/dist/cli/hs-vault-pull.mjs +8157 -6370
  30. package/dist/cli/hs-vault-push.mjs +6433 -0
  31. package/dist/cli/hs-vault.mjs +4029 -1555
  32. package/dist/cli/hs-workspace.mjs +2702 -538
  33. package/dist/cli-templates/customer-vault/specs/entity-model.md +594 -601
  34. package/dist/cli-templates/customer-vault/specs/protocols/canonical-frontmatter-templates.md +110 -177
  35. package/dist/cli-templates/customer-vault/specs/protocols/destructive-action-checklist.md +122 -0
  36. package/dist/cli-templates/customer-vault/specs/protocols/memory-protocol.md +13 -15
  37. package/dist/cli-templates/customer-vault/specs/protocols/session-close-protocol.md +91 -0
  38. package/dist/cli-templates/customer-vault/specs/protocols/spec-hierarchy.md +150 -168
  39. package/dist/cli-templates/customer-vault/specs/protocols/spec-summary-authoring.md +83 -0
  40. package/dist/cli-templates/harness-commands/claude/hs-auto.md +36 -0
  41. package/dist/cli-templates/harness-commands/claude/hs-backfill.md +28 -0
  42. package/dist/cli-templates/harness-commands/claude/hs-capture.md +62 -0
  43. package/dist/cli-templates/harness-commands/claude/hs-defer.md +29 -0
  44. package/dist/cli-templates/harness-commands/claude/hs-dev.md +20 -0
  45. package/dist/cli-templates/harness-commands/claude/hs-doctor.md +32 -0
  46. package/dist/cli-templates/harness-commands/claude/hs-ground.md +30 -0
  47. package/dist/cli-templates/harness-commands/claude/hs-handoff.md +33 -0
  48. package/dist/cli-templates/harness-commands/claude/hs-log.md +27 -0
  49. package/dist/cli-templates/harness-commands/claude/hs-next.md +29 -0
  50. package/dist/cli-templates/harness-commands/claude/hs-promote.md +70 -0
  51. package/dist/cli-templates/harness-commands/claude/hs-push.md +35 -0
  52. package/dist/cli-templates/harness-commands/claude/hs-qc.md +27 -0
  53. package/dist/cli-templates/harness-commands/claude/hs-res.md +63 -0
  54. package/dist/cli-templates/harness-commands/claude/hs-resolve.md +23 -0
  55. package/dist/cli-templates/harness-commands/claude/hs-review.md +23 -0
  56. package/dist/cli-templates/harness-commands/claude/hs-view.md +28 -0
  57. package/dist/cli-templates/harness-commands/claude/kill-ports.md +32 -0
  58. package/dist/cli-templates/harness-commands/claude/prototype.md +91 -0
  59. package/dist/cli-templates/harness-commands/cursor/hs-auto.md +40 -0
  60. package/dist/cli-templates/harness-commands/cursor/hs-backfill.md +31 -0
  61. package/dist/cli-templates/harness-commands/cursor/hs-capture.md +65 -0
  62. package/dist/cli-templates/harness-commands/cursor/hs-defer.md +32 -0
  63. package/dist/cli-templates/harness-commands/cursor/hs-dev.md +24 -0
  64. package/dist/cli-templates/harness-commands/cursor/hs-doctor.md +36 -0
  65. package/dist/cli-templates/harness-commands/cursor/hs-ground.md +33 -0
  66. package/dist/cli-templates/harness-commands/cursor/hs-handoff.md +37 -0
  67. package/dist/cli-templates/harness-commands/cursor/hs-log.md +31 -0
  68. package/dist/cli-templates/harness-commands/cursor/hs-next.md +32 -0
  69. package/dist/cli-templates/harness-commands/cursor/hs-promote.md +73 -0
  70. package/dist/cli-templates/harness-commands/cursor/hs-push.md +38 -0
  71. package/dist/cli-templates/harness-commands/cursor/hs-qc.md +30 -0
  72. package/dist/cli-templates/harness-commands/cursor/hs-res.md +67 -0
  73. package/dist/cli-templates/harness-commands/cursor/hs-resolve.md +26 -0
  74. package/dist/cli-templates/harness-commands/cursor/hs-review.md +26 -0
  75. package/dist/cli-templates/harness-commands/cursor/hs-view.md +32 -0
  76. package/dist/cli-templates/harness-commands/cursor/kill-ports.md +35 -0
  77. package/dist/cli-templates/harness-commands/cursor/prototype.md +95 -0
  78. package/docs/copilot-plugin-install.md +162 -0
  79. package/docs/driving-heyspex-from-copilot.md +165 -0
  80. package/docs/mcp-client-config.md +259 -6
  81. package/package.json +249 -124
  82. package/plugins/heyspex/.claude-plugin/plugin.json +12 -0
  83. package/plugins/heyspex/.cursor-plugin/plugin.json +15 -0
  84. package/plugins/heyspex/.mcp.json +12 -0
  85. package/plugins/heyspex/README.md +309 -0
  86. package/plugins/heyspex/bin/launch-mcp.mjs +95 -0
  87. package/plugins/heyspex/bin/run-hook.mjs +80 -0
  88. package/plugins/heyspex/hooks/cursor-hooks.json +308 -0
  89. package/plugins/heyspex/hooks/hooks.json +418 -0
  90. package/plugins/heyspex/mcp.json +13 -0
  91. package/scripts/check-mcp-freshness.mjs +17 -9
  92. package/scripts/claude-hooks/_env-vault-events.mjs +68 -0
  93. package/scripts/claude-hooks/_guardrail-events.mjs +96 -0
  94. package/scripts/claude-hooks/_guardrail-loader.mjs +494 -0
  95. package/scripts/claude-hooks/_intent-classifier-router.mjs +456 -0
  96. package/scripts/claude-hooks/_intent-classifier-semantic.mjs +356 -0
  97. package/scripts/claude-hooks/_run.mjs +413 -0
  98. package/scripts/claude-hooks/_transcript-text.mjs +60 -0
  99. package/scripts/claude-hooks/_vault-retrieval.mjs +322 -0
  100. package/scripts/claude-hooks/agent-spawn-delegation-gate.mjs +133 -0
  101. package/scripts/claude-hooks/capture-execution-gate.mjs +51 -0
  102. package/scripts/claude-hooks/capture-workflow-gate.mjs +11 -0
  103. package/scripts/claude-hooks/check-auto-memory-budget.mjs +396 -0
  104. package/scripts/claude-hooks/check-claude-md-budget.mjs +327 -0
  105. package/scripts/claude-hooks/check-mcp-freshness-hook.mjs +14 -0
  106. package/scripts/claude-hooks/claim-before-code-gate.mjs +11 -0
  107. package/scripts/claude-hooks/claim-liveness-shared.mjs +577 -0
  108. package/scripts/claude-hooks/close-terminal-on-ship.mjs +64 -0
  109. package/scripts/claude-hooks/coo-denylist-gate.mjs +11 -0
  110. package/scripts/claude-hooks/coo-guard-check.mjs +11 -0
  111. package/scripts/claude-hooks/deep-research-cost-gate.mjs +11 -0
  112. package/scripts/claude-hooks/dev-server-task-reminder.mjs +15 -0
  113. package/scripts/claude-hooks/diagnose-capture-reminder.mjs +11 -0
  114. package/scripts/claude-hooks/directive-obligation-gate.mjs +11 -0
  115. package/scripts/claude-hooks/emit-claim-status.mjs +41 -0
  116. package/scripts/claude-hooks/enforce-session-sequence.mjs +11 -0
  117. package/scripts/claude-hooks/enforce-vault-naming.mjs +11 -0
  118. package/scripts/claude-hooks/env-vault-guard.mjs +11 -0
  119. package/scripts/claude-hooks/epic-milestone-phrasing-gate.mjs +11 -0
  120. package/scripts/claude-hooks/git-identity-guard.mjs +11 -0
  121. package/scripts/claude-hooks/git-reflog-audit.mjs +15 -0
  122. package/scripts/claude-hooks/git-stash-gate.mjs +11 -0
  123. package/scripts/claude-hooks/guard-auto-memory-writes.mjs +137 -0
  124. package/scripts/claude-hooks/id-display-format-gate.mjs +11 -0
  125. package/scripts/claude-hooks/inject-communication-style.mjs +86 -0
  126. package/scripts/claude-hooks/inject-coo-seat.mjs +78 -0
  127. package/scripts/claude-hooks/inject-dev-server-awareness.mjs +11 -0
  128. package/scripts/claude-hooks/inject-doctrine.mjs +13 -0
  129. package/scripts/claude-hooks/inject-vault-context.mjs +14 -0
  130. package/scripts/claude-hooks/intent-classifier-trigger.mjs +279 -0
  131. package/scripts/claude-hooks/log-session-activity.mjs +341 -0
  132. package/scripts/claude-hooks/naughty-list-gate.mjs +11 -0
  133. package/scripts/claude-hooks/notify-status-flip.mjs +72 -0
  134. package/scripts/claude-hooks/plan-exit-ingest-gate.mjs +170 -0
  135. package/scripts/claude-hooks/plan-ingest-close-reminder.mjs +66 -0
  136. package/scripts/claude-hooks/plan-review-gate.mjs +11 -0
  137. package/scripts/claude-hooks/preflight-reminder.mjs +262 -0
  138. package/scripts/claude-hooks/protected-action-intent.mjs +221 -0
  139. package/scripts/claude-hooks/research-method-guard.mjs +398 -0
  140. package/scripts/claude-hooks/research-protocol-gate.mjs +11 -0
  141. package/scripts/claude-hooks/session-end.mjs +451 -0
  142. package/scripts/claude-hooks/settings-write-gate.mjs +11 -0
  143. package/scripts/claude-hooks/settlement-check-gate.mjs +39 -0
  144. package/scripts/claude-hooks/status-flip-detect.mjs +17 -0
  145. package/scripts/claude-hooks/terminal-close-shared.mjs +426 -0
  146. package/scripts/claude-hooks/terminal-close-watcher.mjs +122 -0
  147. package/scripts/claude-hooks/vault-mirror-catchup.mjs +11 -0
  148. package/scripts/claude-hooks/vault-write-tier-guard.mjs +11 -0
  149. package/scripts/claude-hooks/wip-checkpoint.mjs +302 -0
  150. package/scripts/cursor-hooks/manifest.mjs +281 -0
  151. package/scripts/dev-server-status.mjs +34 -13
  152. package/scripts/dev-server-stop.mjs +313 -0
  153. package/scripts/heyspex-mode.mjs +288 -0
  154. package/scripts/hs-auto-resolve.mjs +240 -0
  155. package/scripts/hs-auto-source.mjs +398 -0
  156. package/scripts/hs-auto.mjs +134 -0
  157. package/scripts/hs-capture-cli.mjs +326 -0
  158. package/scripts/hs-classifier.mjs +136 -0
  159. package/scripts/hs-companion.mjs +88 -0
  160. package/scripts/hs-gateway.mjs +115 -0
  161. package/scripts/hs-mode.mjs +125 -0
  162. package/scripts/hs-next.mjs +441 -0
  163. package/scripts/hs-settings.mjs +338 -0
  164. package/scripts/hs-view.mjs +496 -0
  165. package/scripts/hs-worktree.mjs +201 -0
  166. package/scripts/install-claude-code-hooks.mjs +272 -0
  167. package/scripts/install-cursor-hooks.mjs +471 -0
  168. package/scripts/lib/agent-env-markers.mjs +38 -0
  169. package/scripts/lib/console-url-resolver.mjs +199 -61
  170. package/scripts/lib/customer-kit.mjs +1203 -0
  171. package/scripts/lib/dev-mode.mjs +249 -32
  172. package/scripts/lib/directive-obligations.mjs +349 -0
  173. package/scripts/lib/heyspex-home.mjs +72 -0
  174. package/scripts/lib/hook-dispositions.mjs +210 -0
  175. package/scripts/lib/hook-vault-header.mjs +30 -0
  176. package/scripts/lib/hs-command.mjs +277 -0
  177. package/scripts/lib/hs-companion-settings.mjs +472 -0
  178. package/scripts/lib/hs-source-branch.mjs +196 -0
  179. package/scripts/lib/hs-source-commit.mjs +59 -5
  180. package/scripts/lib/hs-source-identity.mjs +526 -0
  181. package/scripts/lib/hs-source-log.mjs +13 -22
  182. package/scripts/lib/hs-source-preflight.mjs +18 -4
  183. package/scripts/lib/hs-source-push.mjs +386 -307
  184. package/scripts/lib/hs-worktree-args.mjs +115 -0
  185. package/scripts/lib/shared-path-helpers.mjs +134 -0
  186. package/scripts/lib/standalone-doctor.mjs +540 -3
  187. package/scripts/lib/subagent-git-lock.mjs +109 -0
  188. package/scripts/lib/template-pin.mjs +34 -0
  189. package/scripts/lib/window-placement.mjs +109 -0
  190. package/scripts/provenance-lib.mjs +91 -0
  191. package/scripts/stamp-provenance-on-edit.mjs +222 -0
  192. package/scripts/wip-ledger-health.mjs +653 -0
  193. package/spexharness/doctrine/baseline/SPEXCODE-DOCTRINE.baseline.json +29 -0
  194. package/spexharness/src/adapters/audit.mjs +197 -0
  195. package/spexharness/src/adapters/claude-code.mjs +449 -0
  196. package/spexharness/src/adapters/copilot.mjs +236 -0
  197. package/spexharness/src/adapters/detect-harness.mjs +34 -0
  198. package/spexharness/src/chat/tui/ansi.mjs +448 -0
  199. package/spexharness/src/chat/tui/palette.mjs +22 -0
  200. package/spexharness/src/chat/tui/select.mjs +208 -0
  201. package/spexharness/src/config-root.mjs +54 -0
  202. package/spexharness/src/context-budget.mjs +141 -0
  203. package/spexharness/src/dev-server-control.mjs +389 -0
  204. package/spexharness/src/doctrine/behaviour.mjs +371 -0
  205. package/spexharness/src/doctrine/corpus.mjs +733 -0
  206. package/spexharness/src/doctrine/inject.mjs +338 -0
  207. package/spexharness/src/doctrine/merge.mjs +184 -0
  208. package/spexharness/src/doctrine/sources.mjs +252 -0
  209. package/spexharness/src/doctrine/synthesize.mjs +401 -0
  210. package/spexharness/src/doctrine/vault-source.mjs +574 -0
  211. package/spexharness/src/doctrine/writer.mjs +176 -0
  212. package/spexharness/src/events.mjs +84 -0
  213. package/spexharness/src/gates/_shell-write-targets.mjs +77 -0
  214. package/spexharness/src/gates/capture-workflow-gate.mjs +202 -0
  215. package/spexharness/src/gates/claim-before-code-gate.decide.mjs +33 -0
  216. package/spexharness/src/gates/claim-before-code-gate.mjs +129 -0
  217. package/spexharness/src/gates/deep-research-cost-gate.mjs +275 -0
  218. package/spexharness/src/gates/diagnose-capture-reminder.mjs +112 -0
  219. package/spexharness/src/gates/directive-obligation-gate.decide.mjs +132 -0
  220. package/spexharness/src/gates/directive-obligation-gate.mjs +183 -0
  221. package/spexharness/src/gates/enforce-session-sequence.mjs +895 -0
  222. package/spexharness/src/gates/enforce-vault-naming.mjs +215 -0
  223. package/spexharness/src/gates/epic-milestone-phrasing-gate.mjs +233 -0
  224. package/spexharness/src/gates/git-identity-guard.decide.mjs +436 -0
  225. package/spexharness/src/gates/git-identity-guard.mjs +61 -0
  226. package/spexharness/src/gates/git-reflog-audit.mjs +151 -0
  227. package/spexharness/src/gates/git-stash-gate.decide.mjs +361 -0
  228. package/spexharness/src/gates/git-stash-gate.mjs +159 -0
  229. package/spexharness/src/gates/id-display-format-gate.mjs +190 -0
  230. package/spexharness/src/gates/inject-doctrine-gate.mjs +89 -0
  231. package/spexharness/src/gates/inject-vault-context.mjs +239 -0
  232. package/spexharness/src/gates/naughty-list-gate.mjs +213 -0
  233. package/spexharness/src/gates/plan-review-gate.mjs +233 -0
  234. package/spexharness/src/gates/preflight-reminder-gate.mjs +265 -0
  235. package/spexharness/src/gates/research-protocol-gate.mjs +175 -0
  236. package/spexharness/src/gates/settings-write-gate.decide.mjs +96 -0
  237. package/spexharness/src/gates/settings-write-gate.mjs +104 -0
  238. package/spexharness/src/gates/vault-mirror-catchup.mjs +124 -0
  239. package/spexharness/src/gates/vault-write-tier-guard.decide.mjs +125 -0
  240. package/spexharness/src/gates/vault-write-tier-guard.mjs +42 -0
  241. package/spexharness/src/git-reflog-audit.mjs +294 -0
  242. package/spexharness/src/intent-classifier.mjs +196 -0
  243. package/spexharness/src/intent-directive.mjs +626 -0
  244. package/spexharness/src/profile/learn.mjs +551 -0
  245. package/spexharness/src/profile/proposals.mjs +357 -0
  246. package/spexharness/src/profile/vault-inclusion.mjs +386 -0
  247. package/spexharness/src/redact.mjs +151 -0
  248. package/spexharness/src/rule-table.mjs +849 -0
  249. package/spexharness/src/seat-context.mjs +122 -0
  250. package/spexharness/src/session-bootstrap.mjs +512 -0
  251. package/spexharness/src/session-record.mjs +815 -0
  252. package/spexharness/src/token-inventory.mjs +207 -0
  253. package/vendor/heyspex-mcp/account-switch.mjs +96 -0
  254. package/vendor/heyspex-mcp/alignment-gate.mjs +315 -1
  255. package/vendor/heyspex-mcp/blocker-resolver.mjs +37 -2
  256. package/vendor/heyspex-mcp/breakdown-ladder.mjs +119 -4
  257. package/vendor/heyspex-mcp/breakdown-source.mjs +271 -0
  258. package/vendor/heyspex-mcp/breakdown-writer.mjs +23 -3
  259. package/vendor/heyspex-mcp/capture-buffer-patches.mjs +77 -8
  260. package/vendor/heyspex-mcp/capture-channel.mjs +55 -5
  261. package/vendor/heyspex-mcp/capture-console-client.mjs +117 -3
  262. package/vendor/heyspex-mcp/capture-focus.mjs +1061 -31
  263. package/vendor/heyspex-mcp/capture-outbox.mjs +15 -5
  264. package/vendor/heyspex-mcp/capture-sources.mjs +195 -0
  265. package/vendor/heyspex-mcp/capture-tools.mjs +1264 -0
  266. package/vendor/heyspex-mcp/claim-tools.mjs +1147 -0
  267. package/vendor/heyspex-mcp/cli-verbs.mjs +2074 -0
  268. package/vendor/heyspex-mcp/cli.mjs +207 -15524
  269. package/vendor/heyspex-mcp/close-branch-report.mjs +102 -0
  270. package/vendor/heyspex-mcp/cloud-tool-surface.mjs +128 -0
  271. package/vendor/heyspex-mcp/cloud-vault-writes.mjs +602 -0
  272. package/vendor/heyspex-mcp/config-seed.yaml +15 -0
  273. package/vendor/heyspex-mcp/config-settings.mjs +290 -7
  274. package/vendor/heyspex-mcp/console-fetch.mjs +822 -17
  275. package/vendor/heyspex-mcp/console-transport.mjs +172 -0
  276. package/vendor/heyspex-mcp/credentials.mjs +585 -0
  277. package/vendor/heyspex-mcp/defer-spec.mjs +44 -4
  278. package/vendor/heyspex-mcp/deferred-reclaim.mjs +29 -3
  279. package/vendor/heyspex-mcp/design-handlers.mjs +31 -0
  280. package/vendor/heyspex-mcp/design-tools.mjs +4 -1
  281. package/vendor/heyspex-mcp/dev-factory-bridge.mjs +4 -4
  282. package/vendor/heyspex-mcp/dev-mode-core.mjs +45 -0
  283. package/vendor/heyspex-mcp/dev-tools.mjs +131 -0
  284. package/vendor/heyspex-mcp/diagnose-handlers.mjs +54 -0
  285. package/vendor/heyspex-mcp/events-tools.mjs +207 -0
  286. package/vendor/heyspex-mcp/filing-tools.mjs +723 -0
  287. package/vendor/heyspex-mcp/fleet-handlers.mjs +37 -0
  288. package/vendor/heyspex-mcp/fleet-queue-tools.mjs +71 -15
  289. package/vendor/heyspex-mcp/focus-tools.mjs +190 -0
  290. package/vendor/heyspex-mcp/folder-trust-store.mjs +60 -0
  291. package/vendor/heyspex-mcp/http-transport.mjs +302 -0
  292. package/vendor/heyspex-mcp/list-tools.mjs +257 -0
  293. package/vendor/heyspex-mcp/login-handoff.mjs +15 -1
  294. package/vendor/heyspex-mcp/mcp-config.mjs +107 -0
  295. package/vendor/heyspex-mcp/memory-tools.mjs +523 -0
  296. package/vendor/heyspex-mcp/mvp-mode.mjs +53 -6
  297. package/vendor/heyspex-mcp/obligation-backstop.mjs +103 -0
  298. package/vendor/heyspex-mcp/occupied-keys.mjs +142 -0
  299. package/vendor/heyspex-mcp/on-deck-brief.mjs +3377 -0
  300. package/vendor/heyspex-mcp/on-deck-scheduler.mjs +1708 -0
  301. package/vendor/heyspex-mcp/package-root.mjs +32 -0
  302. package/vendor/heyspex-mcp/peer-presence.mjs +8 -1
  303. package/vendor/heyspex-mcp/plan-ground.mjs +621 -652
  304. package/vendor/heyspex-mcp/plan-push.mjs +908 -22
  305. package/vendor/heyspex-mcp/plan-review.mjs +124 -30
  306. package/vendor/heyspex-mcp/preflight-gate.mjs +0 -0
  307. package/vendor/heyspex-mcp/procedure-handlers.mjs +327 -0
  308. package/vendor/heyspex-mcp/procedure-tools.mjs +1181 -970
  309. package/vendor/heyspex-mcp/promote-capture.mjs +388 -69
  310. package/vendor/heyspex-mcp/promote-diagnose.mjs +74 -0
  311. package/vendor/heyspex-mcp/promote-research-to-diagnose.mjs +9 -2
  312. package/vendor/heyspex-mcp/promote-research.mjs +666 -53
  313. package/vendor/heyspex-mcp/promotion-helpers.mjs +251 -0
  314. package/vendor/heyspex-mcp/prompts.mjs +1460 -0
  315. package/vendor/heyspex-mcp/read-path.mjs +191 -15
  316. package/vendor/heyspex-mcp/receipt-shape.mjs +146 -0
  317. package/vendor/heyspex-mcp/recipe-handlers.mjs +117 -0
  318. package/vendor/heyspex-mcp/regen-tasks.mjs +210 -3
  319. package/vendor/heyspex-mcp/register-spec.mjs +266 -54
  320. package/vendor/heyspex-mcp/request-context.mjs +83 -0
  321. package/vendor/heyspex-mcp/research-focus.mjs +207 -4
  322. package/vendor/heyspex-mcp/research-handlers.mjs +625 -0
  323. package/vendor/heyspex-mcp/research-tools.mjs +4 -4
  324. package/vendor/heyspex-mcp/response-budget.mjs +348 -0
  325. package/vendor/heyspex-mcp/review-focus.mjs +25 -1
  326. package/vendor/heyspex-mcp/roadmap-default.mjs +70 -0
  327. package/vendor/heyspex-mcp/search-specs.mjs +280 -0
  328. package/vendor/heyspex-mcp/seat-block-ledger.mjs +113 -0
  329. package/vendor/heyspex-mcp/seat-identity.mjs +2 -6
  330. package/vendor/heyspex-mcp/session-owner.mjs +109 -0
  331. package/vendor/heyspex-mcp/session-tools.mjs +162 -0
  332. package/vendor/heyspex-mcp/settings-registry.mjs +232 -0
  333. package/vendor/heyspex-mcp/settings-tools.mjs +85 -12
  334. package/vendor/heyspex-mcp/spec-edit-tools.mjs +453 -0
  335. package/vendor/heyspex-mcp/spec-id-lib.mjs +93 -17
  336. package/vendor/heyspex-mcp/split-research.mjs +304 -56
  337. package/vendor/heyspex-mcp/stdio-rpc.mjs +22 -0
  338. package/vendor/heyspex-mcp/submit-for-review.mjs +150 -7
  339. package/vendor/heyspex-mcp/summary-contract.mjs +105 -0
  340. package/vendor/heyspex-mcp/summary-write-tools.mjs +228 -0
  341. package/vendor/heyspex-mcp/symptom-query.mjs +146 -0
  342. package/vendor/heyspex-mcp/test-helpers.mjs +123 -1
  343. package/vendor/heyspex-mcp/tool-catalog.mjs +2819 -0
  344. package/vendor/heyspex-mcp/tool-dispatch.mjs +657 -0
  345. package/vendor/heyspex-mcp/tool-helpers.mjs +325 -0
  346. package/vendor/heyspex-mcp/validate-linkage.mjs +414 -27
  347. package/vendor/heyspex-mcp/vault-io.mjs +720 -0
  348. package/vendor/heyspex-mcp/vault-less-endpoints.mjs +52 -0
  349. package/vendor/heyspex-mcp/vault-resolve.mjs +554 -68
  350. package/vendor/heyspex-mcp/verify-reproduction.mjs +270 -30
  351. package/vendor/heyspex-mcp/whoami.mjs +92 -0
  352. package/vendor/heyspex-mcp/write-outbox.mjs +512 -0
@@ -0,0 +1,232 @@
1
+ /**
2
+ * HeySpex close-out settings registry — the single declaration of every close-out
3
+ * setting: its dotted key, type, shipped default, description, CLI flag, admin-only
4
+ * marker, enforced marker, and which vault templates ship it.
5
+ *
6
+ * WHY: nothing today says which close-out settings exist, so a shipped default has
7
+ * nowhere to live and a mistyped key fails silently ([[HS-FCF5-15XI-RES-user-editable-close-out-settings-with]]).
8
+ * This registry is the one source every face is meant to read — `hs settings`, the
9
+ * MCP settings tools, and (later) the console — instead of each guessing its own
10
+ * fallback.
11
+ *
12
+ * DECLARATION ONLY (HS-6TDH): this module does not read or write
13
+ * `.heyspex/config.yaml`, does not import `config-settings.mjs`, and does not change
14
+ * any existing settings behavior. A later task in the same epic
15
+ * ([[HS-KW38-15XI-EPIC-settings-registry-core]]) teaches `config-settings.mjs` to
16
+ * resolve reads/writes through this registry (defaults, unknown-key refusal,
17
+ * enforced-entry refusal, type/enum validation).
18
+ *
19
+ * DEPENDENCY-FREE: Node stdlib only, no filesystem access at all — same rationale as
20
+ * the sibling module's "DEPENDENCY-FREE" note.
21
+ *
22
+ * Traceability: [[HS-KW38-15XI-EPIC-settings-registry-core]] ·
23
+ * [[HS-FCF5-15XI-RES-user-editable-close-out-settings-with]] ·
24
+ * [[HS-6TDH-15XI-TASK-declare-every-close-out-setting-in-one]]
25
+ */
26
+
27
+ /**
28
+ * @typedef {'boolean' | 'string' | 'enum'} SettingType
29
+ *
30
+ * @typedef {Object} SettingEntry
31
+ * @property {string} key - Dotted key, e.g. "close_out.update_docs".
32
+ * @property {SettingType} type - The value's declared type.
33
+ * @property {*} default - The shipped default value (absent-key resolution target).
34
+ * @property {string} description - One or two sentences a person can read as help text.
35
+ * @property {string|null} cliFlag - The `hs close` / `hs settings` flag name (e.g.
36
+ * "--update-docs"), or `null` for an enforced entry with no user-facing flag.
37
+ * @property {boolean} adminOnly - True for a HeySpex-admin-only entry; a non-admin
38
+ * vault must treat the key as unknown.
39
+ * @property {boolean} enforced - True for a hard rule that cannot be changed by
40
+ * anyone through any face, including a HeySpex admin.
41
+ * @property {string[]} templates - Which vault templates ship this entry:
42
+ * "heyspex" (the HeySpex platform vault) and/or "customer" (the shipped customer
43
+ * template).
44
+ * @property {string[]} [values] - Allowed values; present only when `type` is "enum".
45
+ */
46
+
47
+ /**
48
+ * The ordered list of every declared close-out setting. Order is the order the
49
+ * close-out runner is meant to evaluate them in (a later task); it is also the
50
+ * order `hs settings list` should render them in.
51
+ *
52
+ * @type {ReadonlyArray<Readonly<SettingEntry>>}
53
+ */
54
+ export const SETTINGS_REGISTRY = Object.freeze(
55
+ [
56
+ {
57
+ key: 'close_out.update_docs',
58
+ type: 'boolean',
59
+ default: true,
60
+ description:
61
+ 'Updates docs/user and docs/admin per the docs-action rule (create/edit/append) at every close-out.',
62
+ cliFlag: '--update-docs',
63
+ adminOnly: false,
64
+ enforced: false,
65
+ templates: ['heyspex', 'customer'],
66
+ },
67
+ {
68
+ key: 'close_out.review_grain',
69
+ type: 'enum',
70
+ values: ['milestone', 'task'],
71
+ default: 'milestone',
72
+ description:
73
+ 'Chooses the close-out review unit: "milestone" flips a completed task straight to closed with no per-task review companion, "task" is the canonical per-task close-out protocol with one HS-REV per task.',
74
+ cliFlag: '--review-grain',
75
+ adminOnly: false,
76
+ enforced: false,
77
+ templates: ['heyspex', 'customer'],
78
+ },
79
+ {
80
+ key: 'close_out.review_backlog_never_blocks',
81
+ type: 'boolean',
82
+ default: true,
83
+ description:
84
+ 'A review backlog sitting at in_review/review_pending never blocks a new claim and never needs owner permission.',
85
+ cliFlag: '--review-backlog-never-blocks',
86
+ adminOnly: false,
87
+ enforced: false,
88
+ templates: ['heyspex', 'customer'],
89
+ },
90
+ {
91
+ key: 'close_out.flip_completed_to_closed',
92
+ type: 'boolean',
93
+ default: true,
94
+ description: 'Flips a completed task straight to closed at close-out.',
95
+ cliFlag: '--flip-completed-to-closed',
96
+ adminOnly: false,
97
+ enforced: false,
98
+ templates: ['heyspex', 'customer'],
99
+ },
100
+ {
101
+ key: 'close_out.append_review_seed',
102
+ type: 'boolean',
103
+ default: true,
104
+ description: 'Appends a one-line review seed to the task change-log at close-out.',
105
+ cliFlag: '--append-review-seed',
106
+ adminOnly: false,
107
+ enforced: false,
108
+ templates: ['heyspex', 'customer'],
109
+ },
110
+ {
111
+ key: 'close_out.rolling_review_doc',
112
+ type: 'boolean',
113
+ default: true,
114
+ description: 'Accumulates one rolling review doc per milestone at close-out.',
115
+ cliFlag: '--rolling-review-doc',
116
+ adminOnly: false,
117
+ enforced: false,
118
+ templates: ['heyspex', 'customer'],
119
+ },
120
+ {
121
+ key: 'close_out.run_command_drift_doctor',
122
+ type: 'boolean',
123
+ default: true,
124
+ description:
125
+ 'Runs the HeySpex command-drift doctor at close-out. HeySpex-admin-only; a customer vault never sees this key.',
126
+ cliFlag: '--run-command-drift-doctor',
127
+ adminOnly: true,
128
+ enforced: false,
129
+ templates: ['heyspex'],
130
+ },
131
+ // Hard rules: enforced entries cannot be changed by anyone through any face,
132
+ // including a HeySpex admin, so they carry no user-facing CLI flag.
133
+ {
134
+ key: 'close_out.alignment',
135
+ type: 'boolean',
136
+ default: true,
137
+ description: 'Hard rule: alignment stays on. No mode may relax it.',
138
+ cliFlag: null,
139
+ adminOnly: false,
140
+ enforced: true,
141
+ templates: ['heyspex', 'customer'],
142
+ },
143
+ {
144
+ key: 'close_out.capture',
145
+ type: 'boolean',
146
+ default: true,
147
+ description: 'Hard rule: capture stays on. No mode may relax it.',
148
+ cliFlag: null,
149
+ adminOnly: false,
150
+ enforced: true,
151
+ templates: ['heyspex', 'customer'],
152
+ },
153
+ {
154
+ key: 'close_out.research',
155
+ type: 'boolean',
156
+ default: true,
157
+ description: 'Hard rule: research stays on. No mode may relax it.',
158
+ cliFlag: null,
159
+ adminOnly: false,
160
+ enforced: true,
161
+ templates: ['heyspex', 'customer'],
162
+ },
163
+ // `close_out.git_commit` moved OUT of the hard-rule set above (owner ruling
164
+ // 2026-09-11, [[HS-PROTO-spexsource-agent-protocol]]): whether an agent
165
+ // ever commits at close-out is now a real, permission-gated toggle instead
166
+ // of an unconditional refusal. Default stays `false` for every vault —
167
+ // heyspex and customer alike — so nobody's out-of-box behavior changes; an
168
+ // owner opts in per vault via the normal settings-write-permission flow
169
+ // (`heyspex_settings_set` / `hs settings set --confirmed-by-user`). When
170
+ // `true`, the agent does not commit unconditionally — it still obeys the
171
+ // existing mode logic: the close-out commit lands at the boundary of the
172
+ // *active review grain* (`close_out.review_grain` — task / epic /
173
+ // milestone), routes only through the sanctioned `hs source preflight` →
174
+ // `hs source commit` path, and stays bound by every entry in
175
+ // spexsource-agent-protocol's always-forbidden list (no `--no-verify`, no
176
+ // force, no push — pushing is the separate `close_out.git_push` key,
177
+ // still enforced below). An explicit owner instruction for the session
178
+ // (e.g. "don't commit this one") overrides the setting for that session;
179
+ // the setting only changes the *default* when the owner said nothing.
180
+ {
181
+ key: 'close_out.git_commit',
182
+ type: 'boolean',
183
+ default: false,
184
+ description:
185
+ 'Whether the agent commits automatically at close-out. Default false (a dirty tree is the expected hand-off; the human reviewer commits on Pass). When true, the agent still obeys the active review grain (close_out.review_grain) for WHEN to commit and the spexsource-agent-protocol always-forbidden list for HOW — never a bypass of those rules, just an opt-in default.',
186
+ cliFlag: '--git-commit',
187
+ adminOnly: false,
188
+ enforced: false,
189
+ templates: ['heyspex', 'customer'],
190
+ },
191
+ {
192
+ key: 'close_out.git_push',
193
+ type: 'boolean',
194
+ default: false,
195
+ description: 'Hard rule: an agent never pushes at close-out.',
196
+ cliFlag: null,
197
+ adminOnly: false,
198
+ enforced: true,
199
+ templates: ['heyspex', 'customer'],
200
+ },
201
+ ].map((entry) => Object.freeze(entry)),
202
+ );
203
+
204
+ /** Fast key → entry lookup, built once from `SETTINGS_REGISTRY`. */
205
+ const BY_KEY = new Map(SETTINGS_REGISTRY.map((entry) => [entry.key, entry]));
206
+
207
+ /**
208
+ * Look up one registry entry by its dotted key.
209
+ * @param {string} key
210
+ * @returns {Readonly<SettingEntry>|null}
211
+ */
212
+ export function getSettingEntry(key) {
213
+ if (typeof key !== 'string') return null;
214
+ return BY_KEY.get(key) ?? null;
215
+ }
216
+
217
+ /** True when `key` names a declared registry entry. */
218
+ export function isKnownSetting(key) {
219
+ return getSettingEntry(key) !== null;
220
+ }
221
+
222
+ /** Every declared key, in registry order. */
223
+ export function listRegistryKeys() {
224
+ return SETTINGS_REGISTRY.map((entry) => entry.key);
225
+ }
226
+
227
+ /** Every declared key the given vault template ships ("heyspex" or "customer"). */
228
+ export function listKeysForTemplate(template) {
229
+ return SETTINGS_REGISTRY.filter((entry) => entry.templates.includes(template)).map(
230
+ (entry) => entry.key,
231
+ );
232
+ }
@@ -1,10 +1,21 @@
1
1
  /**
2
2
  * HeySpex settings MCP tools — the agent face over the settings core
3
- * (config-settings.mjs), mounted in cli.mjs as:
3
+ * (config-settings.mjs) and the settings registry (settings-registry.mjs),
4
+ * mounted in cli.mjs as:
4
5
  * - heyspex_settings_list (read — open)
5
6
  * - heyspex_settings_get (read — open)
6
7
  * - heyspex_settings_set (WRITE — permission-gated two-step confirm)
7
8
  *
9
+ * THIRD FACE (HS-OTEQ): these tools resolve every read through
10
+ * `getEffectiveSetting` (file value → registry default → absent) and the
11
+ * registry's key list, and every write through `validateSettingWrite` — the
12
+ * same functions the CLI face (`hs settings`) and, later, the console face
13
+ * resolve through. No fallback of its own: a registry-governed key answers
14
+ * identically no matter which face asks. A key the registry does not declare
15
+ * (e.g. `agent_behaviors.*`, `mvp_mode.*`) keeps working exactly as before —
16
+ * registry entries are additive, never a replacement for the freeform
17
+ * `.heyspex/config.yaml` surface.
18
+ *
8
19
  * WRITE-PERMISSION GUARDRAIL (owner directive 2026-07-11, documented in
9
20
  * specs/protocols/agent-settings-protocol.md): a settings write is a protected
10
21
  * class. `heyspex_settings_set` without `confirm_token` never writes — it records
@@ -16,31 +27,62 @@
16
27
  * (scripts/claude-hooks/settings-write-gate.mjs) additionally routes the confirm
17
28
  * call through the harness permission prompt in Claude Code.
18
29
  *
30
+ * `requestSettingsWrite` (step 1) and `confirmSettingsWrite`/`setConfigLeaf`
31
+ * (step 2) already run every write through `validateSettingWrite` inside the
32
+ * core, so this file does not re-validate — it only shapes the core's
33
+ * `{ ok:false, error, message }` refusal into the tool's response unchanged
34
+ * (never re-worded), which keeps the reason identical to what the CLI face
35
+ * gives for the same refused write.
36
+ *
19
37
  * Pattern source: procedure-tools.mjs (pure-logic execute* functions; cli.mjs wraps).
20
38
  */
21
39
 
22
40
  import {
23
41
  listConfigLeaves,
24
- getConfigLeaf,
42
+ getEffectiveSetting,
25
43
  requestSettingsWrite,
26
44
  confirmSettingsWrite,
27
45
  validateSettingKey,
28
46
  CONFIG_REL,
29
47
  } from './config-settings.mjs';
48
+ import { getSettingEntry, listRegistryKeys } from './settings-registry.mjs';
30
49
 
31
50
  const MCP_FACE = 'mcp';
32
51
 
52
+ /** True when `key` equals `prefix` or is nested under it (dotted-segment match). */
53
+ function matchesPrefix(key, prefix) {
54
+ return !prefix || key === prefix || key.startsWith(prefix + '.');
55
+ }
56
+
33
57
  export function executeSettingsList(vaultRoot, args = {}) {
34
58
  const prefix = typeof args.prefix === 'string' ? args.prefix.trim() : '';
35
- let settings = listConfigLeaves(vaultRoot);
36
- if (prefix) {
37
- settings = settings.filter((s) => s.key === prefix || s.key.startsWith(prefix + '.'));
59
+
60
+ const fileLeaves = listConfigLeaves(vaultRoot);
61
+ const seen = new Set();
62
+ const settings = [];
63
+
64
+ // Registry-declared keys first, in registry order, resolved through the same
65
+ // file → registry-default chain every face reads through — so a key never
66
+ // written to disk still appears, carrying its shipped default.
67
+ for (const key of listRegistryKeys()) {
68
+ if (!matchesPrefix(key, prefix)) continue;
69
+ const effective = getEffectiveSetting(vaultRoot, key);
70
+ settings.push({ key, value: effective.value, source: effective.source, found: effective.found });
71
+ seen.add(key);
38
72
  }
73
+
74
+ // Then any file leaf outside the registry's namespaces (agent_behaviors.*,
75
+ // mvp_mode.*, …) — additive, unchanged from the pre-registry behavior.
76
+ for (const leaf of fileLeaves) {
77
+ if (seen.has(leaf.key) || !matchesPrefix(leaf.key, prefix)) continue;
78
+ settings.push({ key: leaf.key, value: leaf.value, source: 'file', found: true });
79
+ }
80
+
39
81
  return {
40
82
  ok: true,
41
83
  config_file: CONFIG_REL.replace(/\\/g, '/'),
42
84
  count: settings.length,
43
- settings: settings.map(({ key, value }) => ({ key, value })),
85
+ settings,
44
86
  };
45
87
  }
46
88
 
@@ -48,13 +90,26 @@ export function executeSettingsGet(vaultRoot, args = {}) {
48
90
  const key = typeof args.key === 'string' ? args.key.trim() : '';
49
91
  const check = validateSettingKey(key);
50
92
  if (!check.ok) return { ok: false, error: 'invalid_key', message: check.reason };
51
- const leaf = getConfigLeaf(vaultRoot, key);
93
+
94
+ const effective = getEffectiveSetting(vaultRoot, key);
95
+ let note;
96
+ if (effective.source === 'registry_default') {
97
+ const entry = getSettingEntry(key);
98
+ note = `Key absent from .heyspex/config.yaml — resolved to the registry default (${entry?.description ?? 'see settings-registry.mjs'}).`;
99
+ } else if (effective.source === 'absent') {
100
+ note = 'Key absent from .heyspex/config.yaml and not declared in the settings registry — consumers fall back to their documented default.';
101
+ } else if (effective.source === 'computed') {
102
+ note =
103
+ 'Computed live from the machine-local hs trust store (~/.heyspex/trusted-folders.json) — ' +
104
+ 'never read from .heyspex/config.yaml. Read-only: revoke a folder with "hs trust revoke <path>".';
105
+ }
52
106
  return {
53
107
  ok: true,
54
108
  key,
55
- found: leaf.found,
56
- value: leaf.found ? leaf.value : null,
57
- ...(leaf.found ? {} : { note: 'Key absent from .heyspex/config.yaml — consumers fall back to their documented default.' }),
109
+ found: effective.found,
110
+ value: effective.value,
111
+ source: effective.source,
112
+ ...(note ? { note } : {}),
58
113
  };
59
114
  }
60
115
 
@@ -81,14 +136,32 @@ export function executeSettingsSet(vaultRoot, args = {}) {
81
136
  face: MCP_FACE,
82
137
  });
83
138
  if (!result.ok) return result;
139
+ // MEASURED, NOT ASSUMED ([[HS-IOJW-5YDH-DIAG]] sweep). "applied and audited"
140
+ // used to be printed unconditionally while `appendSettingsAudit`'s boolean
141
+ // was thrown away inside `setConfigLeaf`, so a settings write with no audit
142
+ // row — the one artifact that makes a protected-class write reviewable after
143
+ // the fact — read exactly like a fully audited one. The config write itself
144
+ // DID land, so `ok` stays true and nothing is retried; `audited` + `status`
145
+ // are what let the caller tell a full success from a partial one.
146
+ const audited = result.audited === true;
84
147
  return {
85
148
  ok: true,
86
- status: 'applied',
149
+ status: audited ? 'applied' : 'applied_not_audited',
150
+ partial: !audited,
151
+ audited,
87
152
  key: result.key,
88
153
  previous: result.previous,
89
154
  value: result.value,
90
155
  created: result.created,
91
- note: 'Setting applied and audited to .heyspex/settings-history.jsonl.',
156
+ // HS-4C76 fix 3: the core seeds a missing config.yaml from the template on
157
+ // the first write instead of refusing; surface that so the caller can say so.
158
+ ...(result.seeded === true ? { seeded: true } : {}),
159
+ note: audited
160
+ ? `Setting applied and audited to .heyspex/settings-history.jsonl.${result.seeded === true ? ' (.heyspex/config.yaml was missing and was seeded from the template first.)' : ''}`
161
+ : 'Setting APPLIED to .heyspex/config.yaml, but the audit append to ' +
162
+ '.heyspex/settings-history.jsonl FAILED — this write has NO audit row. The value is live; do not ' +
163
+ 're-apply it. Tell the user the change is in effect but unaudited, and check that ' +
164
+ '.heyspex/settings-history.jsonl is writable.',
92
165
  };
93
166
  }
94
167