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,162 @@
1
+ # Installing the HeySpex (SpexCode) plugin in GitHub Copilot CLI
2
+
3
+ Instructions written to be handed verbatim to a GitHub Copilot CLI agent. Follow the steps in
4
+ order and stop at any step that fails, reporting the exact output.
5
+
6
+ This guide is for a team that installs only the `heyspex` npm package. The heyspex-app repository
7
+ is not needed and is not available to customers.
8
+
9
+ Source of truth for the Copilot commands and file layout:
10
+ <https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-plugin-reference>.
11
+ Hook behaviour under Copilot: <https://docs.github.com/en/copilot/reference/hooks-configuration>.
12
+ Both pages were read on 2026-10-16. The plugin itself is documented in `node_modules/heyspex/plugins/heyspex/README.md`.
13
+
14
+ ## 1. Prerequisites
15
+
16
+ The heyspex-app repository is not required and is not available to customers. Everything below
17
+ works from the published npm package `heyspex` (or a tarball your HeySpex contact hands you), which
18
+ carries the plugin, the marketplace manifest, the hooks and the MCP server.
19
+
20
+ - Node.js 20 or newer on PATH (`node --version`).
21
+ - GitHub Copilot CLI installed and signed in (`copilot --version`).
22
+ - A git repo of your own (the one you want governed). From its root, install the package:
23
+
24
+ ```bash
25
+ npm install heyspex
26
+ # or, from a tarball you were given:
27
+ npm install ./heyspex-0.2.0.tgz
28
+ ```
29
+
30
+ - Sign the machine in to the HeySpex console so hooks and MCP tools can reach the vault:
31
+
32
+ ```bash
33
+ npx hs login
34
+ ```
35
+
36
+ ## 2. Pick ONE: the plugin or the repo hooks (never both)
37
+
38
+ Copilot reads hooks from an installed plugin and from `.github/hooks/` in the repo. With both,
39
+ every hook runs twice. Choose one.
40
+
41
+ **Option A: the plugin (recommended).** One command registers the marketplace shipped inside the
42
+ package and installs the plugin:
43
+
44
+ ```bash
45
+ npx hs install --target . --copilot-plugin-apply
46
+ ```
47
+
48
+ Without `npx hs`, the equivalent Copilot commands are:
49
+
50
+ ```bash
51
+ copilot plugin marketplace add ./node_modules/heyspex
52
+ copilot plugin install heyspex@heyspex-marketplace
53
+ copilot plugin list
54
+ ```
55
+
56
+ `./node_modules/heyspex/.claude-plugin/marketplace.json` is a Claude-format marketplace named
57
+ `heyspex-marketplace`; its plugin `source` (`./plugins/heyspex`) resolves inside the package.
58
+ `npx hs install --target . --copilot-plugin` (no `-apply`) only prints these commands.
59
+
60
+ **Option B: repo hooks, for teammates and the Copilot cloud agent.** Writes
61
+ `.github/hooks/heyspex.json` into your repo; commit it. Each command runs
62
+ `node_modules/heyspex/scripts/claude-hooks/_run.mjs` and exits 0 if the package is not installed,
63
+ so a checkout without `npm install` is never blocked.
64
+
65
+ ```bash
66
+ npx hs install --target . --copilot-hooks
67
+ ```
68
+
69
+ If you pass `--copilot-hooks` together with `--copilot-plugin[-apply]`, the installer warns and
70
+ skips the hooks file.
71
+
72
+ Then restart the Copilot session (`/restart`) so hooks load, and verify:
73
+
74
+ ```bash
75
+ copilot plugin list # Option A: heyspex is enabled
76
+ npx hs doctor # MCP, hooks and account surfaces healthy
77
+ ```
78
+
79
+ ## 3. What the plugin loads
80
+
81
+ | Component | Source | Behaviour under Copilot |
82
+ | --- | --- | --- |
83
+ | Hooks | `node_modules/heyspex/plugins/heyspex/hooks/hooks.json` | PreToolUse, PostToolUse, Stop, UserPromptSubmit and SessionStart gates. Every command locates the runtime itself and exits 0 if it cannot, so a missing variable never denies a tool call. A real deny arrives as a top-level `permissionDecision` with a reason. |
84
+ | MCP server | `node_modules/heyspex/plugins/heyspex/.mcp.json` | The `heyspex_*` vault tools and `hs-*` prompts. |
85
+ | Slash commands | not loaded | Claude Code commands are not a Copilot component. Use MCP prompts or the `hs` CLI. |
86
+
87
+ ## 4. Verify the install
88
+
89
+ 1. In a Copilot session inside any repo, run a harmless tool call, for example read a file. It
90
+ must succeed. A message containing "Denied by preToolUse hook" means a hook failed; go to
91
+ section 7.
92
+ 2. Confirm the MCP server is up by listing MCP servers in Copilot (`/mcp`) and calling
93
+ `heyspex_recall_memories` with `{ "limit": 3 }`. If the server is missing, go to section 7.
94
+ 3. Confirm the gates work: send a prompt that contains a new product idea of more than 60
95
+ characters, then try to edit a source file without capturing. The edit should be refused with a
96
+ reason that names `directive-obligation-gate`. Call `heyspex_update_capture` with the prompt
97
+ text, then retry the edit. It should pass.
98
+
99
+ ## 5. Turning HeySpex off and on
100
+
101
+ Run from the repo you are working in:
102
+
103
+ ```bash
104
+ hs mode status # on | off, and why
105
+ hs mode off # every hook exits 0 immediately, no restart needed
106
+ hs mode on
107
+ hs mode toggle
108
+ ```
109
+
110
+ Use `npx hs mode off` when `hs` is not on PATH. The switch writes
111
+ `.heyspex/mode.json` in the project and is git-ignored.
112
+
113
+ Per-shell variants that touch no files:
114
+
115
+ | Variable | Effect |
116
+ | --- | --- |
117
+ | `HEYSPEX_MODE=off` | Silences hooks for every harness in that shell |
118
+ | `HEYSPEX_COPILOT_HOOKS_OFF=1` | Silences hooks only when the caller is Copilot; Claude Code and Cursor keep theirs |
119
+
120
+ The config twin of the Copilot switch is `agent_behaviors.harness_hooks.copilot.enabled: false` in
121
+ the vault's `.heyspex/config.yaml`.
122
+
123
+ Four security gates ignore all of these by design: `env-vault-guard`, `research-method-guard`,
124
+ `research-protocol-gate` and `git-identity-guard`. They only act on secret writes, built-in
125
+ deep-research skills, unprotocolled web research and git identity changes.
126
+
127
+ ## 6. Everyday loop
128
+
129
+ With MCP available: `heyspex_next_on_deck`, `heyspex_claim_spec`, `heyspex_report_progress`,
130
+ `heyspex_submit_for_review`. Without MCP, the `hs` CLI (`npx hs`) covers the same loop; see
131
+ `docs/driving-heyspex-from-copilot.md`.
132
+
133
+ ## 7. Troubleshooting
134
+
135
+ - **Every tool call is denied.** Run `hs mode off` to unblock immediately, then capture the exact
136
+ deny text and the hook command it names. If the command still starts with
137
+ `node "$CLAUDE_PROJECT_DIR/...`, the package is old; run `npm install heyspex@latest` and reinstall the plugin.
138
+ - **MCP server does not start.** Copilot documents `${PLUGIN_ROOT}` for its own plugin format, and
139
+ whether it expands `${CLAUDE_PLUGIN_ROOT}` in a Claude-format plugin is unverified. Register the
140
+ server explicitly:
141
+
142
+ ```bash
143
+ copilot mcp add heyspex -- node ./node_modules/heyspex/plugins/heyspex/bin/launch-mcp.mjs
144
+ ```
145
+
146
+ - **A hook denies with no reason shown.** That is a hook exiting 2 the old way. Report the hook
147
+ name; it should be answering in Copilot's JSON format.
148
+ - **Hooks run twice.** The repo you are in also carries HeySpex rows in its own
149
+ `.claude/settings.json` from `hs install`. Use either the plugin or the install kit (or `.github/hooks`) in one repo,
150
+ not both.
151
+
152
+ ## 8. Report back
153
+
154
+ State the Copilot CLI version, the output of `copilot plugin list`, the result of the three checks
155
+ in section 4, and the exact text of any deny or MCP error.
156
+
157
+ ## Status of this document
158
+
159
+ The install commands come from GitHub's plugin reference, and the hook behaviour was verified by
160
+ replaying Copilot-shaped payloads through the registered commands, not by a live Copilot session.
161
+ The first agent that completes section 4 is the real test. Fix history: diagnose HS-20SW and
162
+ capture HS-HNO1 (2026-10-16).
@@ -0,0 +1,165 @@
1
+ # Driving HeySpex from GitHub Copilot (and other non-MCP assistants)
2
+
3
+ **Capability table dated: 2026-07-10.** Harness support changes fast; re-verify against the
4
+ sources before relying on a row. Refresh is owned by the harness-integrations pillar.
5
+
6
+ HeySpex is tool-agnostic by construction. Every everyday action reaches the vault through one of
7
+ three write paths, and at least one of them works in **any** assistant that can either speak MCP or
8
+ run a shell command:
9
+
10
+ 1. **MCP tools** — `heyspex_*` tools over the Model Context Protocol (richest surface).
11
+ 2. **The `hs` CLI** — plain shell commands with stable exit codes and `--json` output. No MCP
12
+ client required; works in any assistant, terminal, or CI runner that can shell out.
13
+ 3. **The console web UI** — `localhost:3000`, works in any browser.
14
+
15
+ This guide is the fallback path: how to drive the everyday agent loop when your assistant has
16
+ **no** MCP tool support, using only the `hs` CLI.
17
+
18
+ Grounded in [[HS-RDG9-RES-github-copilot-and-vs-code-mcp-support-t]] (the 2026 verification that
19
+ Copilot now has a real MCP client) and [[HS-TACM-RES-tool-agnostic-mcp-compatibility-matrix-2026-05-27]]
20
+ (the broader cross-tool matrix — note its "VS Code + Copilot = shell-only, no MCP" row is stale as
21
+ of the RDG9 refresh and is being amended separately).
22
+
23
+ ## Per-harness capability table (2026-07-10)
24
+
25
+ **Legend** — **MCP**: native MCP client (tools, and sometimes prompts/resources). **`hs` CLI**:
26
+ can shell out to `hs`. **Prompts**: supports MCP prompts exposed as slash commands. **Everyday
27
+ loop**: can do see-next → claim → report progress → submit for review.
28
+
29
+ | Harness | MCP | `hs` CLI | Prompts | Everyday loop | Honest ceiling |
30
+ | -------------------------------------------------------------------- | :----------------------------------------: | :-----------------------: | :--------------------------: | :---------------------------: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
31
+ | **VS Code agent mode (Copilot)** | ✓ full (`.vscode/mcp.json`, `servers` key) | ✓ | ✓ (`/mcp.<server>.<prompt>`) | via MCP tools **or** `hs` | Full MCP spec — tools, prompts, resources, sampling, OAuth. Subject to a 128-tool per-request cap; curate the exposed tool subset. |
32
+ | **GitHub Copilot CLI** | ✓ (auto-discovers `.github/mcp.json`) | ✓ | ✓ (`/mcp`) | via MCP tools **or** `hs` | Full MCP client (GA Feb 2026). Honors the org "MCP servers in Copilot" policy gate — admin approval may be required. |
33
+ | **Copilot coding agent (github.com cloud)** | ✓ **tools only** | ✓ if sandbox allows shell | ✗ no prompts | via MCP **tools** **or** `hs` | No MCP prompts, no resources, no OAuth. Servers are configured in repo settings, not a committed file; local/allowlisted servers only. **Do not rely on slash-command prompts here — use tools or the `hs` CLI.** |
34
+ | **Any assistant WITHOUT MCP tool support** | ✗ | ✓ | ✗ | via `hs` CLI only | The `hs` CLI is the complete fallback. Everything in the loop is a plain shell command; nothing is unreachable just because the assistant lacks tool support. |
35
+ | **Claude Code / Cursor / Cline / Continue.dev / Google Antigravity** | ✓ native | ✓ | ✓ | via MCP tools (primary) | First-class MCP today; the `hs` CLI is available as a fallback. See [[HS-TACM-RES-tool-agnostic-mcp-compatibility-matrix-2026-05-27]]. |
36
+
37
+ Design consequence: keep the primary UX in **tools**, not MCP prompts, because the cloud coding
38
+ agent doesn't support prompts. Treat slash-command prompts as a VS Code / Copilot-CLI enhancement,
39
+ and the `hs` CLI as the universal floor. HeySpex does **not** promise native slash-command parity on
40
+ a surface that cannot support prompts.
41
+
42
+ ## The everyday loop with the `hs` CLI
43
+
44
+ Run these from anywhere inside the vault (the CLI walks up to find `specs/`; or set
45
+ `HS_VAULT_ROOT`). All four commands are pure shell — no MCP client involved. Add `--json` for
46
+ machine-readable output.
47
+
48
+ ### 1. See what's next
49
+
50
+ ```bash
51
+ hs next --summary --json
52
+ ```
53
+
54
+ Returns the on-deck brief (spec id, title, summary, and a claim target). Drop `--json` for the
55
+ human-readable prompt; drop `--summary` for the full post-claim execution brief.
56
+
57
+ ### 2. Claim the work
58
+
59
+ ```bash
60
+ hs claim acquire HS-WJ1C-TASK --json
61
+ ```
62
+
63
+ Atomic: two concurrent acquires for one spec yield exactly one success and one `already_claimed`
64
+ conflict (exit 9) that names the existing claimant. Release on hand-off with
65
+ `hs claim release HS-WJ1C-TASK`.
66
+
67
+ ### 3. Report progress
68
+
69
+ ```bash
70
+ hs claim progress HS-WJ1C-TASK --stage Grounding --ac 0
71
+ ```
72
+
73
+ `--stage` takes a work-stage verb (Grounding, Breaking down, Drafting, Validating, Testing,
74
+ Reviewing). `--ac <n>` is the 0-based acceptance-criterion index you are on — it drives the live
75
+ checklist on the What's Next surface. Call it again as you move between stages and complete criteria.
76
+
77
+ ### 4. Submit for review
78
+
79
+ ```bash
80
+ hs mcp call heyspex_submit_for_review --arg spec_id=HS-WJ1C-TASK --json
81
+ ```
82
+
83
+ `hs mcp call` runs a single MCP tool as a **one-shot shell command** — it does not require your
84
+ assistant to be an MCP client. This close-out step validates acceptance-criteria progress against
85
+ your claim, PATCHes the status API (never hand-edit frontmatter `status:`), applies review-grain
86
+ coercion and parent rollup, releases the claim, and returns close-out guidance. A `409` on submit is
87
+ a real reason (e.g. incomplete criteria) — report it, don't work around it.
88
+
89
+ > Why `hs mcp call` and not a dedicated `hs submit` verb: see-next, claim, and report-progress each
90
+ > have a first-class `hs` verb; submit-for-review is reached through the generic one-shot MCP-call
91
+ > escape hatch, which reuses the exact close-out logic the MCP tool runs. It is still a plain shell
92
+ > command with no MCP-client requirement.
93
+
94
+ ## Configuring MCP where it IS supported
95
+
96
+ For VS Code agent mode and Copilot CLI you get the richer MCP tool surface. The MCP config
97
+ templates (`.vscode/mcp.json` with the `servers` key, `.github/mcp.json` for Copilot CLI
98
+ auto-discovery) and the Copilot instructions file are owned by the harness-integrations config work
99
+ and documented separately — this guide covers only the universal `hs` CLI fallback.
100
+
101
+ ## Hooks under Copilot
102
+
103
+ Copilot CLI runs the HeySpex hooks it finds in `.claude/settings.json` (and the plugin's `hooks/hooks.json`), so the
104
+ gates (capture-on-idea obligation, claim-before-build, naming guards) apply to Copilot agents too. What differs:
105
+
106
+ - **Fail-closed**: Copilot denies a tool call when a `preToolUse` command crashes or exits non-zero. Every registered
107
+ command is therefore a self-locating bootstrap that does not need `$CLAUDE_PROJECT_DIR` and exits 0 when it cannot find
108
+ the HeySpex runtime; `_run.mjs` itself never exits non-zero except for a deliberate deny (translated to Copilot's
109
+ top-level `{"permissionDecision":"deny"}` JSON with exit 0).
110
+ - **Turn it off**: `hs mode off` (all harnesses, per project; `hs mode on|status|toggle`), `HEYSPEX_MODE=off` for one
111
+ shell, or `HEYSPEX_COPILOT_HOOKS_OFF=1` / `agent_behaviors.harness_hooks.copilot.enabled: false` for Copilot only.
112
+ The four always-on security gates (`env-vault-guard`, `research-method-guard`, `research-protocol-gate`,
113
+ `git-identity-guard`) ignore all three.
114
+ - **Stopgap on an older checkout** (before the bootstrap ships): `HEYSPEX_MODE=off` only helps if the hook command can
115
+ start, and the old command needs `CLAUDE_PROJECT_DIR`; export it (`CLAUDE_PROJECT_DIR=<repo>`) alongside `HEYSPEX_MODE=off`.
116
+
117
+ ### One source of hooks, and the cloud agent
118
+
119
+ Plugin OR repo hooks, never both: Copilot CLI loads the heyspex plugin AND the repo's `.claude/settings.json` /
120
+ `.github/hooks/*.json`, so a repo with both fires every hook twice. `npm run doctor` (check `hook-double-fire`) warns
121
+ about that and reports `unknown`, not a failure, when it cannot read a plugin registry.
122
+
123
+ The Copilot **cloud agent** loads no plugins: its only hook source is `.github/hooks/*.json` on the **default branch**.
124
+ `npm run hooks:write-github` generates `.github/hooks/heyspex.json` (bash `command` entries only, camelCase events,
125
+ resolving `node_modules/heyspex/scripts/claude-hooks/_run.mjs` then `./scripts/claude-hooks/_run.mjs`, else exit 0).
126
+ Requirements: the sandbox must contain `node_modules/heyspex` (install it in `copilot-setup-steps`), the firewall must
127
+ allow the console URL (claim heartbeats), and MCP is configured in repository settings (tools only, no OAuth).
128
+
129
+ ### Gates that are weaker or absent on Copilot
130
+
131
+ Generated from `scripts/lib/hook-dispositions.mjs` (a test fails when this block is stale). The MCP preflight refusals
132
+ (`heyspex_claim_spec`, `heyspex_submit_for_review`, `heyspex_save_research`) are the hook-independent hard floor on every
133
+ surface that connects the MCP server.
134
+
135
+ <!-- hook-dispositions:copilot:begin (generated by scripts/lib/hook-dispositions.test.mjs; UPDATE_HOOK_DOCS=1 refreshes) -->
136
+ | Gate | Disposition | Compensating control / what is lost |
137
+ | --- | --- | --- |
138
+ | `research-method-guard` | unportable | MCP preflight refusal on heyspex_save_research (hard floor, hook-independent) + .github/copilot-instructions.md research rule; Copilot has no Skill or Workflow tool to hook. |
139
+ | `deep-research-cost-gate` | unportable | MCP preflight refusal on heyspex_save_research + .github/copilot-instructions.md cost-confirmation rule; Copilot has no Skill or Workflow tool to hook. |
140
+ | `plan-review-gate` | unportable | MCP preflight refusals (heyspex_claim_spec / heyspex_submit_for_review / heyspex_save_research) + .github/copilot-instructions.md plan rule (state the plan in chat, claim the spec before editing) + HS-20SW directive-obligation-gate claim-before-build deny |
141
+ | `plan-exit-ingest-gate` | unportable | MCP preflight refusals (heyspex_claim_spec / heyspex_submit_for_review / heyspex_save_research) + .github/copilot-instructions.md plan rule (state the plan in chat, claim the spec before editing) + HS-20SW directive-obligation-gate claim-before-build deny |
142
+ | `preflight-reminder` | advisory-degraded | Copilot drops command-hook output on userPromptSubmitted (no prompt-time context channel); the text moves to sessionStart / .github/copilot-instructions.md. Real enforcement is the MCP preflight refusal. |
143
+ | `intent-classifier-trigger` | advisory-degraded | Copilot drops command-hook output on userPromptSubmitted (no prompt-time context channel); the text moves to sessionStart / .github/copilot-instructions.md. The hook still runs and arms obligation state; the HS-20SW directive-obligation-gate turns that state into a hard deny. |
144
+ | `inject-communication-style` | advisory-degraded | Copilot drops command-hook output on userPromptSubmitted (no prompt-time context channel); the text moves to sessionStart / .github/copilot-instructions.md. |
145
+ | `inject-vault-context` | advisory-degraded | Copilot drops command-hook output on userPromptSubmitted (no prompt-time context channel); the text moves to sessionStart / .github/copilot-instructions.md. Per-prompt vault retrieval has no Copilot channel at all. |
146
+ | `claim-before-code-gate` | advisory-degraded | Armed only by plan-exit-ingest-gate, which has no Copilot trigger (no ExitPlanMode tool), so it stays dormant; covered by the HS-20SW claim-before-build rule. |
147
+ | `diagnose-capture-reminder` | advisory-degraded | Copilot preToolUse has no context channel for an inject, so this advisory is silent (lost). |
148
+ <!-- hook-dispositions:copilot:end -->
149
+
150
+ Plan mode: Copilot has no `ExitPlanMode` tool, so the plan gates cannot fire. State the plan in chat and claim the spec
151
+ before editing code (`.github/copilot-instructions.md`); the HS-20SW claim-before-build deny backs that up.
152
+
153
+ **Unverified** (no official page read, or not run live): the VS Code 128-tool per-request cap (the microsoft/vscode issue
154
+ below is the only source); the spelling of MCP tool names inside hook payloads (hooks match by suffix); whether
155
+ `${CLAUDE_PLUGIN_ROOT}` expands in the plugin `.mcp.json` under the Copilot CLI (documented for VS Code only); how the MCP
156
+ server learns the Copilot session id (its preflight marker falls back to a 4 hour TTL); whether the CLI reads a Claude-format
157
+ `hookSpecificOutput` deny.
158
+
159
+ ## Sources
160
+
161
+ - [[HS-RDG9-RES-github-copilot-and-vs-code-mcp-support-t]] — Copilot MCP support verified mid-2026 (cloud agent = tools only).
162
+ - [[HS-TACM-RES-tool-agnostic-mcp-compatibility-matrix-2026-05-27]] — cross-tool compatibility matrix (Copilot row being amended).
163
+ - [MCP and GitHub Copilot cloud agent — GitHub Docs](https://docs.github.com/en/copilot/concepts/agents/coding-agent/mcp-and-coding-agent) — cloud coding agent supports MCP tools only.
164
+ - [Adding MCP servers for GitHub Copilot CLI — GitHub Docs](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers) — `.github/mcp.json` auto-discovery.
165
+ - [Hard tool limit (128) in VS Code agent mode — microsoft/vscode#290356](https://github.com/microsoft/vscode/issues/290356) — 128-tool per-request cap.
@@ -13,6 +13,12 @@ points at `node ${CLAUDE_PROJECT_DIR}/vendor/heyspex-mcp/cli.mjs` — a path tha
13
13
  exists inside a clone of the HeySpex source repository** and is therefore useless to
14
14
  anyone who installed the package.
15
15
 
16
+ **Working from a clone of this repo instead?** `heyspex` is not published on the
17
+ public npm registry yet, so `npm install -g heyspex` below 404s. Skip to
18
+ [§1b — clone + `npm link`](#1b-clone--npm-link-working-from-source), and see
19
+ [Working from a clone](#working-from-a-clone-of-this-repo) below for how to sign in
20
+ once linked.
21
+
16
22
  ## 1a. Install the package (customers)
17
23
 
18
24
  ```sh
@@ -36,6 +42,16 @@ name, which is unambiguous:
36
42
  npx --yes --package heyspex heyspex-mcp
37
43
  ```
38
44
 
45
+ **What the agent kit injects at session start.** With the kit hooks installed (`hs install` /
46
+ `hs connect`, or the plugin), the `inject-doctrine` SessionStart hook adds the **baseline
47
+ edition of SpexCode Doctrine** to each session: a short list of general working principles
48
+ (verify before claiming done, report what failed, ask before irreversible writes, stay in scope),
49
+ read from `spexharness/doctrine/baseline/SPEXCODE-DOCTRINE.baseline.json` inside the installed
50
+ package. That is all it injects. It does not inject anything about how HeySpex itself is built
51
+ (no dev-server, database, or build-fleet rules), any learned principles from HeySpex's own
52
+ development sessions, or anything read from your repo, and it does not include a SpexCode Profile.
53
+ If the baseline file is missing, the hook injects nothing. Set `HEYSPEX_DOCTRINE_OFF=1` to turn it off.
54
+
39
55
  ## 1b. Clone + `npm link` (working from source)
40
56
 
41
57
  `npm install` in a clone does **not** put `hs` on your PATH. Nothing does, except
@@ -153,18 +169,131 @@ heyspex mcp pair <code>
153
169
  > clone has no `hs` at all. Run `npm run doctor` — its **`hs` on PATH → this
154
170
  > checkout** check names the cause.
155
171
 
172
+ ## Working from a clone of this repo
173
+
174
+ `npm install -g heyspex` above needs the package published on the public npm
175
+ registry, and it is not yet — that command 404s today. Until it ships, a machine
176
+ working from a clone of this repo signs in through the repo's own dispatcher instead
177
+ of a global `hs`/`heyspex` command:
178
+
179
+ ```sh
180
+ node bin/hs.mjs login
181
+ ```
182
+
183
+ Run that from the repo root (or pass an absolute path to `bin/hs.mjs` from any
184
+ folder). It opens the console, mints a pairing code, and writes the token to
185
+ `~/.heyspex/credentials.yaml` — the same file `heyspex login` writes once the package
186
+ is installed globally.
187
+
188
+ **Do not run `hs login` or `npx hs login` on a fresh clone.** Nothing in `npm install`
189
+ links the `hs` binary onto PATH, so a bare `hs login` fails with "command not found."
190
+ `npx hs login` fails worse: `hs` is the name of an unrelated package already on the
191
+ public registry, so `npx hs login` silently installs and runs *that* package instead
192
+ of this repo's — no error, just the wrong tool. `npm run doctor` reports which form of
193
+ the command actually runs on your machine (the `hs command form` check) — trust that
194
+ line over guessing.
195
+
196
+ Linking `hs` globally (`npm link` from the repo root) is available if you want the
197
+ bare `hs` command on this one machine, but it is not required and not the default —
198
+ it points `hs` at whatever branch happens to be checked out, so a machine that
199
+ switches branches often is better served by the dispatcher form above. See
200
+ [[HS-I6HT-EKYU-DIAG-every-message-tells-the-user-to-run-hs]] for why linking isn't the
201
+ shipped fix.
202
+
156
203
  ## Which vault the server reads
157
204
 
158
- Resolution order, highest first:
205
+ Resolution order, highest first. The directory the process actually started
206
+ in outranks the machine-wide active pointer: a server started inside one vault
207
+ must never write its bookkeeping into whichever vault another terminal last
208
+ marked active.
159
209
 
160
210
  | # | Source | Notes |
161
211
  |---|---|---|
162
- | 1 | An explicit vault id | `hs vault use <id>` |
163
- | 2 | `active_vault_id` in `~/.heyspex/registry.json` | the offline active-vault pointer |
164
- | 3 | `HEYSPEX_VAULT_ROOT` | the repository root; what the config above sets |
165
- | 4 | `HEYSPEX_VAULT_DIR` | the `specs/` directory itself |
166
- | 5 | The working directory | used when it contains a `specs/` directory |
212
+ | 1 | An explicit vault id | `hs vault use <id>`, or `hs --vault <id> <cmd>` |
213
+ | 2 | `HEYSPEX_VAULT_ROOT` / `HEYSPEX_VAULT_DIR` | the repository root / the `specs/` directory itself; what the config above sets |
214
+ | 3 | A vault or a satellite attachment at or above the working directory | walks up from the working directory; the nearest match wins, and an attachment beats a `heyspex.yaml` / `specs/` marker found at the same or a higher level |
215
+ | 4 | `active_vault_id` in `~/.heyspex/registry.json` | the offline active-vault pointer — reached only when the working directory sits inside no vault at all |
216
+ | 5 | The working directory | last resort, when nothing above matched |
217
+
218
+ Tier 3 is what makes [satellite repos](#satellite-repos-code-here-specs-elsewhere)
219
+ work, and why they do not depend on the active pointer.
220
+
221
+ ## Satellite repos: code here, specs elsewhere
222
+
223
+ A **satellite** is a code repo that gets the full agent tooling while its specs
224
+ live in a different, already-registered vault. It owns no `specs/` and no
225
+ `heyspex.yaml` — it is not a vault, it is attached to one. Use it whenever the
226
+ code and the vault are separate checkouts.
227
+
228
+ ```bash
229
+ cd /path/to/your-code-repo
230
+ hs install --attach-vault <vault-id> # `hs vault list` shows the ids
231
+ ```
232
+
233
+ The target is the repo you are standing in. `--attach-vault` also accepts the
234
+ vault repo's path (absolute or relative) instead of its id.
235
+
236
+ This writes the same MCP manifests and agent contract as a normal install, with
237
+ one difference: `HEYSPEX_VAULT_ROOT` is pinned to the **attached** vault's
238
+ absolute path instead of the client placeholder.
239
+
240
+ ```jsonc
241
+ {
242
+ "mcpServers": {
243
+ "heyspex": {
244
+ "type": "stdio",
245
+ "command": "node",
246
+ "args": ["/abs/path/to/heyspex/vendor/heyspex-mcp/cli.mjs"],
247
+ "env": {
248
+ // a normal install writes "${CLAUDE_PROJECT_DIR:-.}" here
249
+ "HEYSPEX_VAULT_ROOT": "/abs/path/to/the-vault-repo"
250
+ }
251
+ }
252
+ }
253
+ }
254
+ ```
255
+
256
+ That pin **is** the attachment — there is no marker file, so there is nothing to
257
+ drift. Every surface reads it: the MCP server resolves the vault through it,
258
+ and `hs connect --check`, `hs doctor` and `hs` itself use it to recognize the
259
+ repo as a satellite.
260
+
261
+ ### What the tooling does differently
262
+
263
+ - `hs connect --check` reports **Connected (satellite)** and evaluates the four
264
+ vault rows (marker, `specs/`, vault registered, workspace registered) against
265
+ the **attached** vault, plus a `satellite_attachment` row. A satellite never
266
+ reads as "missing heyspex.yaml".
267
+ - `hs connect` (full run) skips every vault-creating step, so it will not
268
+ scaffold a second vault into your code repo. It still installs plugin
269
+ surfaces and git hooks, and it needs no sign-in (it performs no cloud write).
270
+ - `hs doctor` audits the **attached vault**, because `hs` resolves the pin into
271
+ `HS_VAULT_ROOT` before doctor runs. It does not report the satellite's own
272
+ connection rows — use `hs connect --check` in the repo for those.
273
+
274
+ ### Rules and refusals
275
+
276
+ Every refusal happens before anything is written.
167
277
 
278
+ | Situation | Result |
279
+ |---|---|
280
+ | Vault id unknown, or a path with no registry row | exit 11 — register it first with `hs vault register --path <dir>` |
281
+ | The registered vault is missing from this machine | exit 11 |
282
+ | Attaching a vault to itself | exit 11 |
283
+ | A manifest already pins a **different** vault, or carries no pin | exit 11 — re-run with `--force` to re-pin |
284
+ | Both manifests already pin this vault | no-op, exit 0 |
285
+ | `--register-vault` or `--workspace` | exit 1 — a satellite never registers a vault of its own |
286
+ | `--no-cursor --no-claude` | exit 1 — nowhere to record the pin |
287
+ | `--remote` | exit 1 — the cloud endpoint resolves the vault from your **account**, not a local pin, so Claude Code and Cursor could read different vaults with nothing reporting the split |
288
+
289
+ ### Known limitation: the attachment does not survive a fresh clone
290
+
291
+ The pin is an absolute, machine-local path, so the manifests carrying it are
292
+ not committed. A teammate cloning a satellite gets a repo with no `specs/`, no
293
+ marker and no pin — indistinguishable from an unwired code repo, and `hs
294
+ connect` there would scaffold a vault into it. `hs connect` prints a
295
+ non-blocking warning when it can recognize the shape, but it cannot always
296
+ tell. Re-run `hs install --attach-vault <id>` after cloning.
168
297
  ## Which console the server calls
169
298
 
170
299
  Resolution order, highest first:
@@ -198,3 +327,127 @@ The real check is in the client: after restarting it, the `heyspex_*` tools shou
198
327
  listed. If they are not, the client did not restart, or the command is not on your
199
328
  `PATH` — from a clone run `npm link` (§1b); from an install, try the
200
329
  `npx --package heyspex heyspex-mcp` form.
330
+
331
+ ## Remote (cloud) MCP — no local server
332
+
333
+ The console also serves MCP directly over HTTPS at `https://app.heyspex.com/api/mcp`
334
+ (MCP Streamable HTTP, JSON-response mode). A customer machine needs no `heyspex-mcp`
335
+ process, no checkout and no `HEYSPEX_VAULT_ROOT` — only a token.
336
+
337
+ ### Get a token
338
+
339
+ The endpoint accepts the same `hsmcp_…` bearer the local server uses. Either command
340
+ writes it as `mcp_token:` in `~/.heyspex/credentials.yaml`:
341
+
342
+ ```sh
343
+ heyspex login # opens the console, mints a pairing code, redeems it
344
+ heyspex mcp pair <code> # redeem a code minted elsewhere (no browser needed)
345
+ ```
346
+
347
+ Read `mcp_token` out of that file (or mint one from the console's MCP pairing page)
348
+ and pass it as `HEYSPEX_MCP_TOKEN` below. Treat it like a password.
349
+
350
+ ### Claude Code
351
+
352
+ ```sh
353
+ claude mcp add --transport http heyspex https://app.heyspex.com/api/mcp \
354
+ --header "Authorization: Bearer ${HEYSPEX_MCP_TOKEN}"
355
+ ```
356
+
357
+ or, project scope, in `.mcp.json`:
358
+
359
+ ```json
360
+ {
361
+ "mcpServers": {
362
+ "heyspex": {
363
+ "type": "http",
364
+ "url": "https://app.heyspex.com/api/mcp",
365
+ "headers": {
366
+ "Authorization": "Bearer ${HEYSPEX_MCP_TOKEN}"
367
+ }
368
+ }
369
+ }
370
+ }
371
+ ```
372
+
373
+ Claude Code expands `${HEYSPEX_MCP_TOKEN}` from your environment at startup, so the
374
+ token never sits in the checked-in file. Any other Streamable-HTTP MCP client works
375
+ the same way: POST JSON-RPC to the URL with that `Authorization` header.
376
+
377
+ ### Let the CLI write it
378
+
379
+ Either verb generates exactly the block above — always with the **env reference**,
380
+ never the literal token:
381
+
382
+ ```sh
383
+ hs install --remote # full bootstrap; .mcp.json gets the http form
384
+ hs install --remote=https://my-preview.example.dev # a preview deployment
385
+ hs mcp install --remote # print only (no vault bootstrap)
386
+ hs mcp install --remote --write # …and write .mcp.json into the vault root
387
+ hs mcp install --remote --json # { url, mcp_json, claude_command, wrote }
388
+ ```
389
+
390
+ Both print the equivalent `claude mcp add --transport http …` one-liner. A bare
391
+ origin is normalized (`https://host` → `https://host/api/mcp`). `hs install --remote`
392
+ changes only the Claude Code `.mcp.json`; `.cursor/mcp.json` keeps the stdio form,
393
+ so a project can run local-first in Cursor and cloud in Claude Code.
394
+
395
+ ### Transport details
396
+
397
+ - **POST** — JSON-RPC in, one JSON reply out. `initialize` mints an `Mcp-Session-Id`
398
+ that later requests echo back. `initialize`'s `serverInfo.version` reports the
399
+ deployed package version (baked at build time, so it is real, not `0.0.0-unknown`).
400
+ - **GET** with `Accept: text/event-stream` — opens the Streamable-HTTP event stream.
401
+ It is deliberately **silent**: one opening comment, then a `: keepalive` comment
402
+ every 15 s, closed when the client aborts. No server-initiated messages are ever
403
+ sent on it, so a conforming client parses zero messages; it exists so clients that
404
+ open the channel are not met with a 405. A GET without that `Accept` is still 405.
405
+ - **DELETE** — acknowledges a session end with `200` and a small JSON body
406
+ (`{ ok, session_id, note }`). Sessions are stateless, so there is nothing to free.
407
+
408
+ ### What it serves, and what it does not
409
+
410
+ The remote endpoint runs the very same tool handlers as the local server, acting as
411
+ the account the token belongs to, but only the **cloud-safe subset** — the tools that
412
+ work entirely through the console API:
413
+
414
+ - session + procedures: `heyspex_recall_memories`, `heyspex_list_procedures`,
415
+ `heyspex_get_procedure`, `heyspex_preflight`, `heyspex_handoff_load`,
416
+ `heyspex_handoff_record`
417
+ - the claim contract: `heyspex_next_on_deck`, `heyspex_claim_spec`,
418
+ `heyspex_release_spec`, `heyspex_report_progress`, `heyspex_submit_for_review`,
419
+ `heyspex_record_wip`, `heyspex_defer_spec`, `heyspex_claim_list`,
420
+ `heyspex_claim_acquire`, `heyspex_claim_release`
421
+ - filing + context: `heyspex_file_spec`, `heyspex_active_capture`,
422
+ `heyspex_milestone_show`, `heyspex_events_show`, `heyspex_list_known_tags`
423
+ - focus / pin: `heyspex_pin_get`, `heyspex_pin_set`, `heyspex_get_focus_areas`,
424
+ `heyspex_set_focus_areas`
425
+
426
+ The authoritative list is `vendor/heyspex-mcp/cloud-tool-surface.mjs`. Calling any
427
+ other `heyspex_*` tool returns a JSON-RPC error saying it needs the local server —
428
+ those tools read or write the vault checkout on disk (research capture and
429
+ promotion, `push_plan`, `backfill_epic`, spec edits, alignment recording, the design
430
+ system, `dev_mode` switching, `update_capture`'s offline outbox). Keep the local
431
+ stdio server for those; the two can be registered side by side under different names.
432
+
433
+ Current limitations:
434
+
435
+ - **No server-initiated messages.** POST always answers with JSON (never an SSE
436
+ body), and the GET stream carries only keepalive comments — no notifications, no
437
+ progress, no server-side requests, no sampling/elicitation.
438
+ - **Stateless sessions.** `initialize` returns an `Mcp-Session-Id`; later calls echo it
439
+ and `DELETE` acknowledges it, but nothing is kept server-side, so there is no
440
+ `heyspex_load_tools` progressive surface (the list above is the whole list) and the
441
+ local server's PreToolUse/PostToolUse hooks and on-disk preflight proof-of-use gate
442
+ do not run remotely.
443
+ - **Enrichment degrades.** `heyspex_next_on_deck`'s core brief (scheduler cohort,
444
+ the spec itself, its task graph) is served from the cloud, and so is the previous
445
+ session's WIP block when the hand-off landed in the Neon `wip_ledger`. Extras the
446
+ local server reads from the checkout — plan amendments, memory scoring, the
447
+ file-based `.heyspex/wip-state.json` fallback — stay empty on the remote path,
448
+ because a serverless runtime has no vault checkout to read them from.
449
+ - **`heyspex_file_spec`'s landing probe reports the cloud verdict only.** It cannot
450
+ stat a local file (there is none), so `local_file_exists` is `null` and the verdict
451
+ rests on the console's own write response.
452
+ - **Cursor is stdio-only here.** `hs install --remote` rewrites the Claude Code
453
+ `.mcp.json`; point Cursor at the same URL by hand if you want it cloud-backed.