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
@@ -19,6 +19,8 @@ import {
19
19
  mkdirSync,
20
20
  unlinkSync,
21
21
  } from 'node:fs';
22
+ import { yamlScalar } from './yaml-scalar.mjs';
23
+ import { splitRawSpec } from './cloud-vault-writes.mjs';
22
24
 
23
25
  // ─────────────────────────────────────────────────────────────────────────────
24
26
  // Date / string utilities
@@ -278,3 +280,252 @@ export function commitWrites(writes) {
278
280
  return { ok: false, error: err };
279
281
  }
280
282
  }
283
+
284
+ // ─────────────────────────────────────────────────────────────────────────────
285
+ // Cloud-tier (neon) read support — [[HS-KR16-CWPX-TASK-promotion-reads-through-the-cloud-tier]]
286
+ // ─────────────────────────────────────────────────────────────────────────────
287
+ //
288
+ // The disk-tier loaders throughout promote-capture.mjs / promote-research.mjs
289
+ // (`find*ByIdLocal`, `find*ByBasename`, etc.) all return the same shape:
290
+ // `{ basename, absPath, relPath, raw }` — `raw` being the FULL file text
291
+ // (frontmatter fence + body), which every downstream consumer parses with the
292
+ // regex-based `getFrontmatterBlock`/`getScalarField`/`parseListFieldBasenames`
293
+ // helpers above. The console's `GET /api/specs/[id]` route (the same by-id
294
+ // route `loadSpecByIdViaTier` in vault-io.mjs uses) instead returns ALREADY
295
+ // PARSED `frontmatter` (an object) + a fenced-out `body` — so a neon-tier read
296
+ // reconstructs an equivalent `raw` string via {@link synthesizeRawFromSpec}
297
+ // rather than requiring every regex consumer to grow a second, object-shaped
298
+ // code path. `absPath` is always `null` on a neon read (no local file backs
299
+ // it) — safe because nothing reads `absPath` before the write phase, which
300
+ // stays disk-only and is out of this task's scope.
301
+
302
+ /**
303
+ * Reconstruct a byte-plausible "raw" markdown file (frontmatter fence + body)
304
+ * from a console-returned `{ frontmatter, body }` pair. Round-trip fidelity
305
+ * only needs to satisfy the regex readers above, not survive a re-write —
306
+ * every neon-tier document in this flow is a READ-ONLY input.
307
+ */
308
+ export function synthesizeRawFromSpec(frontmatter, body) {
309
+ const lines = [];
310
+ for (const [key, value] of Object.entries(frontmatter ?? {})) {
311
+ if (value === undefined) continue;
312
+ if (value === null) {
313
+ lines.push(`${key}: null`);
314
+ continue;
315
+ }
316
+ if (Array.isArray(value)) {
317
+ if (value.length === 0) {
318
+ lines.push(`${key}: []`);
319
+ continue;
320
+ }
321
+ lines.push(`${key}:`);
322
+ for (const item of value) {
323
+ if (typeof item === 'string' && /^\[\[[^\]]+\]\]$/.test(item)) {
324
+ // Already wikilink-wrapped (the shape every cross-ref list field
325
+ // stores) — quote it verbatim so parseListFieldBasenames's
326
+ // `- "[[basename]]"` pattern matches.
327
+ lines.push(` - "${item}"`);
328
+ } else {
329
+ lines.push(` - ${yamlScalar(item)}`);
330
+ }
331
+ }
332
+ continue;
333
+ }
334
+ if (typeof value === 'object') {
335
+ // Rare in this flow (frontmatter here is scalars + wikilink lists) —
336
+ // best-effort JSON scalar rather than a second nested-YAML writer.
337
+ lines.push(`${key}: ${JSON.stringify(value)}`);
338
+ continue;
339
+ }
340
+ lines.push(`${key}: ${yamlScalar(value)}`);
341
+ }
342
+ return `---\n${lines.join('\n')}\n---\n${body ?? ''}`;
343
+ }
344
+
345
+ /**
346
+ * Fetch one spec by id/basename from the console via an INJECTED
347
+ * `consoleFetch` and reshape it into the `{ basename, absPath, relPath, raw }`
348
+ * contract every disk-tier loader above already returns. Mirrors the
349
+ * `GET /api/specs/[id]` contract `loadSpecByIdViaTier` (vault-io.mjs) uses —
350
+ * same route, same "404 is a real not-found answer" rule — but goes through
351
+ * the CALLER's own injected `consoleFetch` instead of that module's hardwired
352
+ * transport, matching promote-capture.mjs / promote-research.mjs's existing
353
+ * deps-injection convention (`defaultProposeStubs`) so callers/tests never
354
+ * need a real socket. A non-404 failure throws; the caller wraps this with
355
+ * `readViaSelector` (read-path.mjs) so it surfaces as
356
+ * `CONSOLE_UNREACHABLE_CLOUD_MODE` naming the route.
357
+ */
358
+ export async function fetchSpecRecordViaConsole(consoleFetchFn, specId) {
359
+ if (typeof consoleFetchFn !== 'function') {
360
+ throw new Error('fetchSpecRecordViaConsole: a consoleFetch dependency is required in the neon tier');
361
+ }
362
+ const res = await consoleFetchFn(`/api/specs/${encodeURIComponent(specId)}`);
363
+ if (res.ok) {
364
+ const spec = res.body?.spec;
365
+ if (!spec) return null;
366
+ const relPath = spec.relPath ?? spec.path ?? null;
367
+ const basename = relPath
368
+ ? String(relPath).split(/[\\/]/).pop().replace(/\.md$/i, '')
369
+ : String(spec.frontmatter?.id ?? specId);
370
+ return {
371
+ basename,
372
+ absPath: null,
373
+ relPath,
374
+ raw: synthesizeRawFromSpec(spec.frontmatter || {}, spec.body || ''),
375
+ };
376
+ }
377
+ if (res.status === 404) return null; // not_found / ambiguous_id — a real answer, not a failure.
378
+ throw new Error(
379
+ `GET /api/specs/${specId} returned ${res.status}: ${res.error || JSON.stringify(res.body ?? {})}`,
380
+ );
381
+ }
382
+
383
+ // ─────────────────────────────────────────────────────────────────────────────
384
+ // Cloud-mode WRITE support — [[HS-BYU4-CWPX-TASK-promotion-writes-go-through-the-console]]
385
+ // ─────────────────────────────────────────────────────────────────────────────
386
+ //
387
+ // The READ half above (HS-KR16) taught the promotion flows to FIND their input
388
+ // documents through the console. This half teaches them to SAVE the result
389
+ // there too. The machinery itself lives in `cloud-vault-writes.mjs` (the
390
+ // write-side twin of read-path.mjs); what belongs HERE is only the small bit of
391
+ // shared vocabulary every promotion module must agree on:
392
+ //
393
+ // - how the mode is read off `deps` (resolved ONCE per handler call by the
394
+ // caller, never re-derived inside a helper — the same rule `deps.tier`
395
+ // follows), and
396
+ // - how a write that has NO cloud equivalent at all reports itself.
397
+ //
398
+ // On the second point: `POST /api/specs` can only create documents whose
399
+ // `type` the console's TYPE_TO_FOLDER knows (task, epic, milestone, diagnose,
400
+ // capture, planning-flow, memory-*, protocol, workflow-recipe, research,
401
+ // review, pillar, agent, golden-case, adr, draft, daily). A roadmap manifest
402
+ // append, a soft-delete into a trash folder, a local pin file — none of those
403
+ // is a spec of a known kind, and inventing a type for them would file a
404
+ // document into a folder the console does not model. Those degrade EXPLICITLY
405
+ // instead, carrying {@link CLOUD_MODE_UNSUPPORTED_WRITE} and naming both the
406
+ // file and the reason, so the caller reports a real gap rather than silently
407
+ // skipping a write.
408
+ //
409
+ // NOTE on the local dot-directory state (`review-focus.yaml`,
410
+ // `research-focus.yaml`, the promote-research review-gate markers): those are
411
+ // LOCAL MACHINE STATE, not vault content — they do not live under `specs/`,
412
+ // nothing indexes them, and they are per-workstation by design (HS-KR16 §Scope
413
+ // made exactly this call for the marker cache). They keep writing to disk in
414
+ // cloud mode and are deliberately NOT routed through the console.
415
+
416
+ /** Error code for a write with no console equivalent. */
417
+ export const CLOUD_MODE_UNSUPPORTED_WRITE = 'CLOUD_MODE_UNSUPPORTED_WRITE';
418
+
419
+ /**
420
+ * Repair the ONE lossy case in the markdown → object round-trip these flows
421
+ * depend on.
422
+ *
423
+ * Every cloud write starts from markdown one of the shared content builders
424
+ * produced, and `splitRawSpec` (cloud-vault-writes.mjs) parses it with
425
+ * `parseFrontmatter`/`parseSimpleYaml` from vault-io.mjs — the vault's own YAML
426
+ * dialect, deliberately reused so there is no second parser to drift. That
427
+ * parser renders an INLINE EMPTY LIST (`depends_on: []`, `tags: []`,
428
+ * `children: []`, `epics: []`, `related: []` — every stub template writes
429
+ * several) as `['']`: a one-element list holding an empty string.
430
+ *
431
+ * On disk that never mattered, because the disk path writes the markdown
432
+ * verbatim and never round-trips it. Through the console it very much does: a
433
+ * `depends_on: ['']` would be stored as a real one-entry list whose entry is a
434
+ * dangling empty wikilink. Normalizing here — at the single seam where parsed
435
+ * frontmatter becomes a request body — fixes every caller at once, and is
436
+ * deliberately narrow: ONLY the exact `['']` shape collapses, so a genuine
437
+ * list that merely contains a blank alongside real entries is left alone for
438
+ * the console to reject on its own terms.
439
+ */
440
+ export function normalizeParsedFrontmatter(frontmatter) {
441
+ const out = {};
442
+ for (const [key, value] of Object.entries(frontmatter ?? {})) {
443
+ out[key] =
444
+ Array.isArray(value) && value.length === 1 && value[0] === '' ? [] : value;
445
+ }
446
+ return out;
447
+ }
448
+
449
+ /**
450
+ * `splitRawSpec` + {@link normalizeParsedFrontmatter} — the single call every
451
+ * cloud write in these modules uses to turn built markdown into the
452
+ * `{ frontmatter, body }` pair the console's POST/PUT routes take.
453
+ */
454
+ export function splitRawSpecForConsole(raw) {
455
+ const { frontmatter, body } = splitRawSpec(raw);
456
+ return { frontmatter: normalizeParsedFrontmatter(frontmatter), body };
457
+ }
458
+
459
+ /**
460
+ * The vault write mode for this call: `deps.writeMode` when the caller
461
+ * resolved one (`resolveVaultWriteMode()` from read-path.mjs), else `local`.
462
+ *
463
+ * Defaulting to `local` — NOT to the resolver's own prod-default `cloud` — is
464
+ * what keeps every pre-existing caller and test byte-identical: a caller that
465
+ * never heard of this task passes no `writeMode` and takes the disk path it
466
+ * always took.
467
+ */
468
+ export function resolveWriteModeFromDeps(deps) {
469
+ return deps?.writeMode === 'cloud' ? 'cloud' : 'local';
470
+ }
471
+
472
+ /**
473
+ * Build the canonical "this write cannot exist in cloud mode" result — the
474
+ * same `{ error, message }` shape every promotion handler already returns, so
475
+ * a caller renders it with no new branch.
476
+ */
477
+ export function cloudModeUnsupportedWrite(file, why, details = {}) {
478
+ return {
479
+ error: CLOUD_MODE_UNSUPPORTED_WRITE,
480
+ message:
481
+ `CLOUD_MODE_UNSUPPORTED_WRITE: "${file}" cannot be written through the console — ${why}. ` +
482
+ 'Nothing was written for this step; re-run in local (disk) write mode if this document is required.',
483
+ file,
484
+ reason: why,
485
+ ...details,
486
+ };
487
+ }
488
+
489
+ /**
490
+ * Render a failed cloud write as the `{ error, message }` result shape every
491
+ * promotion handler already returns.
492
+ *
493
+ * There is deliberately NO rollback claim: `commitWrites`'s disk transaction
494
+ * can restore a snapshot, the console cannot un-create. So the result names
495
+ * the step that failed AND lists the steps that already landed, and says so in
496
+ * words — a caller must never read this as "nothing happened"
497
+ * ([[HS-BYU4-CWPX-TASK-promotion-writes-go-through-the-console]] AC5).
498
+ *
499
+ * `message` is passed through verbatim from `cloud-vault-writes.mjs`, so it
500
+ * always STARTS WITH `CONSOLE_UNREACHABLE_CLOUD_MODE` and names the route and
501
+ * the console.
502
+ */
503
+ export function cloudWriteFailureResult(err, { step = null, completed = [] } = {}) {
504
+ const message = String(err?.message ?? err);
505
+ return {
506
+ error: 'CONSOLE_UNREACHABLE_CLOUD_MODE',
507
+ message,
508
+ route: err?.route ?? null,
509
+ console_url: err?.console_url ?? null,
510
+ write_mode: 'cloud',
511
+ failed_step: step,
512
+ completed_steps: completed,
513
+ partial: completed.length > 0,
514
+ rollback:
515
+ completed.length > 0
516
+ ? 'none — the console has no un-create, so every step listed in completed_steps DID land; reconcile from there rather than retrying blind'
517
+ : 'nothing landed — the first console write failed',
518
+ };
519
+ }
520
+
521
+ /**
522
+ * Throwable twin of {@link cloudModeUnsupportedWrite}, for the code paths that
523
+ * signal by exception rather than by return value.
524
+ */
525
+ export function cloudModeUnsupportedWriteError(file, why, details = {}) {
526
+ const payload = cloudModeUnsupportedWrite(file, why, details);
527
+ const err = new Error(payload.message);
528
+ err.name = CLOUD_MODE_UNSUPPORTED_WRITE;
529
+ Object.assign(err, payload);
530
+ return err;
531
+ }