heyspex 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/README.md +21 -0
  2. package/bin/hs.mjs +931 -98
  3. package/bin/spexcode.mjs +262 -0
  4. package/dev-factory/engine/worktree.mjs +740 -0
  5. package/dev-factory/lib/code-repo-root.mjs +67 -0
  6. package/dev-factory/lib/context-budget.mjs +84 -0
  7. package/dev-factory/lib/epic-detect.mjs +190 -0
  8. package/dev-factory/lib/fleet-queue-file.mjs +846 -0
  9. package/dev-factory/lib/fleet-queue.mjs +426 -0
  10. package/dev-factory/lib/fleet-state.mjs +14 -18
  11. package/dev-factory/lib/model-catalog.mjs +338 -0
  12. package/dev-factory/lib/seat-context.mjs +199 -0
  13. package/dev-factory/lib/spec-io.mjs +93 -0
  14. package/dev-factory/lib/sufficiency-score.mjs +8 -2
  15. package/dev-factory/lib/worktree-allocator.mjs +744 -0
  16. package/dev-factory/model-catalog.json +222 -0
  17. package/dist/cli/hs-check.mjs +1085 -103
  18. package/dist/cli/hs-claim.mjs +936 -63
  19. package/dist/cli/hs-connect.mjs +9786 -1910
  20. package/dist/cli/hs-defer.mjs +5267 -3053
  21. package/dist/cli/hs-dev.mjs +564 -0
  22. package/dist/cli/hs-env.mjs +385 -299
  23. package/dist/cli/hs-index-rebuild.mjs +7129 -0
  24. package/dist/cli/hs-index-reconcile.mjs +7852 -0
  25. package/dist/cli/hs-init.mjs +777 -138
  26. package/dist/cli/hs-install.mjs +6583 -485
  27. package/dist/cli/hs-join.mjs +10137 -2368
  28. package/dist/cli/hs-vault-pull.mjs +4659 -5882
  29. package/dist/cli/hs-vault.mjs +3793 -1537
  30. package/dist/cli/hs-workspace.mjs +2550 -524
  31. package/dist/cli-templates/customer-vault/specs/entity-model.md +594 -601
  32. package/dist/cli-templates/customer-vault/specs/protocols/canonical-frontmatter-templates.md +110 -177
  33. package/dist/cli-templates/customer-vault/specs/protocols/destructive-action-checklist.md +122 -0
  34. package/dist/cli-templates/customer-vault/specs/protocols/memory-protocol.md +13 -15
  35. package/dist/cli-templates/customer-vault/specs/protocols/session-close-protocol.md +91 -0
  36. package/dist/cli-templates/customer-vault/specs/protocols/spec-hierarchy.md +150 -168
  37. package/dist/cli-templates/customer-vault/specs/protocols/spec-summary-authoring.md +83 -0
  38. package/dist/cli-templates/harness-commands/claude/hs-auto.md +36 -0
  39. package/dist/cli-templates/harness-commands/claude/hs-backfill.md +28 -0
  40. package/dist/cli-templates/harness-commands/claude/hs-capture.md +62 -0
  41. package/dist/cli-templates/harness-commands/claude/hs-defer.md +29 -0
  42. package/dist/cli-templates/harness-commands/claude/hs-dev.md +20 -0
  43. package/dist/cli-templates/harness-commands/claude/hs-doctor.md +32 -0
  44. package/dist/cli-templates/harness-commands/claude/hs-ground.md +28 -0
  45. package/dist/cli-templates/harness-commands/claude/hs-handoff.md +33 -0
  46. package/dist/cli-templates/harness-commands/claude/hs-log.md +27 -0
  47. package/dist/cli-templates/harness-commands/claude/hs-next.md +29 -0
  48. package/dist/cli-templates/harness-commands/claude/hs-promote.md +70 -0
  49. package/dist/cli-templates/harness-commands/claude/hs-push.md +35 -0
  50. package/dist/cli-templates/harness-commands/claude/hs-qc.md +27 -0
  51. package/dist/cli-templates/harness-commands/claude/hs-res.md +63 -0
  52. package/dist/cli-templates/harness-commands/claude/hs-resolve.md +23 -0
  53. package/dist/cli-templates/harness-commands/claude/hs-review.md +23 -0
  54. package/dist/cli-templates/harness-commands/claude/hs-view.md +26 -0
  55. package/dist/cli-templates/harness-commands/claude/kill-ports.md +32 -0
  56. package/dist/cli-templates/harness-commands/claude/prototype.md +91 -0
  57. package/dist/cli-templates/harness-commands/cursor/hs-auto.md +40 -0
  58. package/dist/cli-templates/harness-commands/cursor/hs-backfill.md +31 -0
  59. package/dist/cli-templates/harness-commands/cursor/hs-capture.md +65 -0
  60. package/dist/cli-templates/harness-commands/cursor/hs-defer.md +32 -0
  61. package/dist/cli-templates/harness-commands/cursor/hs-dev.md +24 -0
  62. package/dist/cli-templates/harness-commands/cursor/hs-doctor.md +36 -0
  63. package/dist/cli-templates/harness-commands/cursor/hs-ground.md +31 -0
  64. package/dist/cli-templates/harness-commands/cursor/hs-handoff.md +37 -0
  65. package/dist/cli-templates/harness-commands/cursor/hs-log.md +31 -0
  66. package/dist/cli-templates/harness-commands/cursor/hs-next.md +32 -0
  67. package/dist/cli-templates/harness-commands/cursor/hs-promote.md +73 -0
  68. package/dist/cli-templates/harness-commands/cursor/hs-push.md +38 -0
  69. package/dist/cli-templates/harness-commands/cursor/hs-qc.md +30 -0
  70. package/dist/cli-templates/harness-commands/cursor/hs-res.md +67 -0
  71. package/dist/cli-templates/harness-commands/cursor/hs-resolve.md +26 -0
  72. package/dist/cli-templates/harness-commands/cursor/hs-review.md +26 -0
  73. package/dist/cli-templates/harness-commands/cursor/hs-view.md +30 -0
  74. package/dist/cli-templates/harness-commands/cursor/kill-ports.md +35 -0
  75. package/dist/cli-templates/harness-commands/cursor/prototype.md +95 -0
  76. package/docs/mcp-client-config.md +259 -6
  77. package/package.json +231 -124
  78. package/plugins/heyspex/.claude-plugin/plugin.json +12 -0
  79. package/plugins/heyspex/.cursor-plugin/plugin.json +15 -0
  80. package/plugins/heyspex/.mcp.json +12 -0
  81. package/plugins/heyspex/bin/launch-mcp.mjs +95 -0
  82. package/plugins/heyspex/bin/run-hook.mjs +62 -0
  83. package/plugins/heyspex/hooks/cursor-hooks.json +227 -0
  84. package/plugins/heyspex/hooks/hooks.json +361 -0
  85. package/plugins/heyspex/mcp.json +13 -0
  86. package/scripts/check-mcp-freshness.mjs +17 -9
  87. package/scripts/claude-hooks/_env-vault-events.mjs +68 -0
  88. package/scripts/claude-hooks/_guardrail-events.mjs +96 -0
  89. package/scripts/claude-hooks/_guardrail-loader.mjs +494 -0
  90. package/scripts/claude-hooks/_intent-classifier-router.mjs +410 -0
  91. package/scripts/claude-hooks/_intent-classifier-semantic.mjs +351 -0
  92. package/scripts/claude-hooks/_run.mjs +120 -0
  93. package/scripts/claude-hooks/_transcript-text.mjs +60 -0
  94. package/scripts/claude-hooks/_vault-retrieval.mjs +322 -0
  95. package/scripts/claude-hooks/agent-spawn-delegation-gate.mjs +133 -0
  96. package/scripts/claude-hooks/capture-workflow-gate.mjs +11 -0
  97. package/scripts/claude-hooks/check-auto-memory-budget.mjs +396 -0
  98. package/scripts/claude-hooks/check-claude-md-budget.mjs +327 -0
  99. package/scripts/claude-hooks/check-mcp-freshness-hook.mjs +14 -0
  100. package/scripts/claude-hooks/claim-before-code-gate.mjs +11 -0
  101. package/scripts/claude-hooks/claim-liveness-shared.mjs +575 -0
  102. package/scripts/claude-hooks/close-terminal-on-ship.mjs +64 -0
  103. package/scripts/claude-hooks/coo-denylist-gate.mjs +11 -0
  104. package/scripts/claude-hooks/coo-guard-check.mjs +11 -0
  105. package/scripts/claude-hooks/deep-research-cost-gate.mjs +11 -0
  106. package/scripts/claude-hooks/dev-server-task-reminder.mjs +15 -0
  107. package/scripts/claude-hooks/emit-claim-status.mjs +41 -0
  108. package/scripts/claude-hooks/enforce-session-sequence.mjs +11 -0
  109. package/scripts/claude-hooks/enforce-vault-naming.mjs +11 -0
  110. package/scripts/claude-hooks/env-vault-guard.mjs +11 -0
  111. package/scripts/claude-hooks/epic-milestone-phrasing-gate.mjs +11 -0
  112. package/scripts/claude-hooks/git-identity-guard.mjs +11 -0
  113. package/scripts/claude-hooks/git-reflog-audit.mjs +15 -0
  114. package/scripts/claude-hooks/git-stash-gate.mjs +11 -0
  115. package/scripts/claude-hooks/guard-auto-memory-writes.mjs +137 -0
  116. package/scripts/claude-hooks/id-display-format-gate.mjs +11 -0
  117. package/scripts/claude-hooks/inject-communication-style.mjs +66 -0
  118. package/scripts/claude-hooks/inject-coo-seat.mjs +78 -0
  119. package/scripts/claude-hooks/inject-dev-server-awareness.mjs +11 -0
  120. package/scripts/claude-hooks/inject-doctrine.mjs +13 -0
  121. package/scripts/claude-hooks/inject-vault-context.mjs +14 -0
  122. package/scripts/claude-hooks/intent-classifier-trigger.mjs +247 -0
  123. package/scripts/claude-hooks/log-session-activity.mjs +341 -0
  124. package/scripts/claude-hooks/naughty-list-gate.mjs +11 -0
  125. package/scripts/claude-hooks/notify-status-flip.mjs +72 -0
  126. package/scripts/claude-hooks/plan-exit-ingest-gate.mjs +170 -0
  127. package/scripts/claude-hooks/plan-ingest-close-reminder.mjs +66 -0
  128. package/scripts/claude-hooks/plan-review-gate.mjs +11 -0
  129. package/scripts/claude-hooks/preflight-reminder.mjs +262 -0
  130. package/scripts/claude-hooks/protected-action-intent.mjs +221 -0
  131. package/scripts/claude-hooks/research-method-guard.mjs +398 -0
  132. package/scripts/claude-hooks/research-protocol-gate.mjs +11 -0
  133. package/scripts/claude-hooks/session-end.mjs +449 -0
  134. package/scripts/claude-hooks/settings-write-gate.mjs +11 -0
  135. package/scripts/claude-hooks/settlement-check-gate.mjs +39 -0
  136. package/scripts/claude-hooks/status-flip-detect.mjs +17 -0
  137. package/scripts/claude-hooks/terminal-close-shared.mjs +426 -0
  138. package/scripts/claude-hooks/terminal-close-watcher.mjs +122 -0
  139. package/scripts/claude-hooks/wip-checkpoint.mjs +298 -0
  140. package/scripts/cursor-hooks/manifest.mjs +235 -0
  141. package/scripts/dev-server-status.mjs +34 -13
  142. package/scripts/dev-server-stop.mjs +313 -0
  143. package/scripts/heyspex-mode.mjs +268 -0
  144. package/scripts/hs-auto-resolve.mjs +240 -0
  145. package/scripts/hs-auto-source.mjs +398 -0
  146. package/scripts/hs-auto.mjs +134 -0
  147. package/scripts/hs-capture-cli.mjs +326 -0
  148. package/scripts/hs-classifier.mjs +136 -0
  149. package/scripts/hs-companion.mjs +88 -0
  150. package/scripts/hs-gateway.mjs +115 -0
  151. package/scripts/hs-mode.mjs +125 -0
  152. package/scripts/hs-next.mjs +441 -0
  153. package/scripts/hs-settings.mjs +338 -0
  154. package/scripts/hs-view.mjs +333 -0
  155. package/scripts/hs-worktree.mjs +201 -0
  156. package/scripts/install-claude-code-hooks.mjs +270 -0
  157. package/scripts/install-cursor-hooks.mjs +471 -0
  158. package/scripts/lib/agent-env-markers.mjs +38 -0
  159. package/scripts/lib/console-url-resolver.mjs +197 -60
  160. package/scripts/lib/customer-kit.mjs +886 -0
  161. package/scripts/lib/dev-mode.mjs +244 -28
  162. package/scripts/lib/heyspex-home.mjs +72 -0
  163. package/scripts/lib/hs-command.mjs +277 -0
  164. package/scripts/lib/hs-companion-settings.mjs +472 -0
  165. package/scripts/lib/hs-source-commit.mjs +59 -5
  166. package/scripts/lib/hs-source-identity.mjs +526 -0
  167. package/scripts/lib/hs-source-log.mjs +11 -21
  168. package/scripts/lib/hs-source-push.mjs +107 -58
  169. package/scripts/lib/hs-worktree-args.mjs +115 -0
  170. package/scripts/lib/shared-path-helpers.mjs +134 -0
  171. package/scripts/lib/standalone-doctor.mjs +540 -3
  172. package/scripts/lib/subagent-git-lock.mjs +109 -0
  173. package/scripts/lib/template-pin.mjs +34 -0
  174. package/scripts/provenance-lib.mjs +91 -0
  175. package/scripts/stamp-provenance-on-edit.mjs +222 -0
  176. package/scripts/wip-ledger-health.mjs +653 -0
  177. package/spexharness/doctrine/baseline/SPEXCODE-DOCTRINE.baseline.json +29 -0
  178. package/spexharness/src/adapters/audit.mjs +197 -0
  179. package/spexharness/src/adapters/claude-code.mjs +441 -0
  180. package/spexharness/src/chat/tui/ansi.mjs +448 -0
  181. package/spexharness/src/chat/tui/palette.mjs +22 -0
  182. package/spexharness/src/chat/tui/select.mjs +208 -0
  183. package/spexharness/src/config-root.mjs +54 -0
  184. package/spexharness/src/context-budget.mjs +141 -0
  185. package/spexharness/src/dev-server-control.mjs +389 -0
  186. package/spexharness/src/doctrine/behaviour.mjs +371 -0
  187. package/spexharness/src/doctrine/corpus.mjs +733 -0
  188. package/spexharness/src/doctrine/inject.mjs +338 -0
  189. package/spexharness/src/doctrine/merge.mjs +184 -0
  190. package/spexharness/src/doctrine/sources.mjs +252 -0
  191. package/spexharness/src/doctrine/synthesize.mjs +401 -0
  192. package/spexharness/src/doctrine/vault-source.mjs +574 -0
  193. package/spexharness/src/doctrine/writer.mjs +176 -0
  194. package/spexharness/src/events.mjs +84 -0
  195. package/spexharness/src/gates/capture-workflow-gate.mjs +202 -0
  196. package/spexharness/src/gates/claim-before-code-gate.decide.mjs +33 -0
  197. package/spexharness/src/gates/claim-before-code-gate.mjs +129 -0
  198. package/spexharness/src/gates/deep-research-cost-gate.mjs +274 -0
  199. package/spexharness/src/gates/enforce-session-sequence.mjs +895 -0
  200. package/spexharness/src/gates/enforce-vault-naming.mjs +215 -0
  201. package/spexharness/src/gates/epic-milestone-phrasing-gate.mjs +233 -0
  202. package/spexharness/src/gates/git-identity-guard.decide.mjs +436 -0
  203. package/spexharness/src/gates/git-identity-guard.mjs +61 -0
  204. package/spexharness/src/gates/git-reflog-audit.mjs +151 -0
  205. package/spexharness/src/gates/git-stash-gate.decide.mjs +361 -0
  206. package/spexharness/src/gates/git-stash-gate.mjs +159 -0
  207. package/spexharness/src/gates/id-display-format-gate.mjs +190 -0
  208. package/spexharness/src/gates/inject-doctrine-gate.mjs +89 -0
  209. package/spexharness/src/gates/inject-vault-context.mjs +239 -0
  210. package/spexharness/src/gates/naughty-list-gate.mjs +213 -0
  211. package/spexharness/src/gates/plan-review-gate.mjs +233 -0
  212. package/spexharness/src/gates/preflight-reminder-gate.mjs +265 -0
  213. package/spexharness/src/gates/research-protocol-gate.mjs +175 -0
  214. package/spexharness/src/gates/settings-write-gate.decide.mjs +96 -0
  215. package/spexharness/src/gates/settings-write-gate.mjs +104 -0
  216. package/spexharness/src/git-reflog-audit.mjs +294 -0
  217. package/spexharness/src/intent-classifier.mjs +194 -0
  218. package/spexharness/src/intent-directive.mjs +541 -0
  219. package/spexharness/src/profile/learn.mjs +551 -0
  220. package/spexharness/src/profile/proposals.mjs +357 -0
  221. package/spexharness/src/profile/vault-inclusion.mjs +386 -0
  222. package/spexharness/src/redact.mjs +151 -0
  223. package/spexharness/src/rule-table.mjs +819 -0
  224. package/spexharness/src/seat-context.mjs +122 -0
  225. package/spexharness/src/session-bootstrap.mjs +512 -0
  226. package/spexharness/src/session-record.mjs +815 -0
  227. package/spexharness/src/token-inventory.mjs +207 -0
  228. package/vendor/heyspex-mcp/account-switch.mjs +95 -0
  229. package/vendor/heyspex-mcp/alignment-gate.mjs +315 -1
  230. package/vendor/heyspex-mcp/blocker-resolver.mjs +37 -2
  231. package/vendor/heyspex-mcp/breakdown-ladder.mjs +119 -4
  232. package/vendor/heyspex-mcp/breakdown-source.mjs +271 -0
  233. package/vendor/heyspex-mcp/breakdown-writer.mjs +23 -3
  234. package/vendor/heyspex-mcp/capture-buffer-patches.mjs +46 -5
  235. package/vendor/heyspex-mcp/capture-channel.mjs +55 -5
  236. package/vendor/heyspex-mcp/capture-console-client.mjs +80 -1
  237. package/vendor/heyspex-mcp/capture-focus.mjs +1035 -29
  238. package/vendor/heyspex-mcp/capture-outbox.mjs +5 -1
  239. package/vendor/heyspex-mcp/capture-tools.mjs +1219 -0
  240. package/vendor/heyspex-mcp/claim-tools.mjs +1124 -0
  241. package/vendor/heyspex-mcp/cli-verbs.mjs +2076 -0
  242. package/vendor/heyspex-mcp/cli.mjs +201 -15524
  243. package/vendor/heyspex-mcp/cloud-tool-surface.mjs +128 -0
  244. package/vendor/heyspex-mcp/cloud-vault-writes.mjs +412 -0
  245. package/vendor/heyspex-mcp/config-seed.yaml +15 -0
  246. package/vendor/heyspex-mcp/config-settings.mjs +290 -7
  247. package/vendor/heyspex-mcp/console-fetch.mjs +657 -16
  248. package/vendor/heyspex-mcp/console-transport.mjs +166 -0
  249. package/vendor/heyspex-mcp/credentials.mjs +584 -0
  250. package/vendor/heyspex-mcp/defer-spec.mjs +44 -4
  251. package/vendor/heyspex-mcp/deferred-reclaim.mjs +29 -3
  252. package/vendor/heyspex-mcp/design-handlers.mjs +31 -0
  253. package/vendor/heyspex-mcp/design-tools.mjs +4 -1
  254. package/vendor/heyspex-mcp/dev-factory-bridge.mjs +4 -4
  255. package/vendor/heyspex-mcp/dev-mode-core.mjs +45 -0
  256. package/vendor/heyspex-mcp/dev-tools.mjs +124 -0
  257. package/vendor/heyspex-mcp/diagnose-handlers.mjs +54 -0
  258. package/vendor/heyspex-mcp/events-tools.mjs +207 -0
  259. package/vendor/heyspex-mcp/filing-tools.mjs +688 -0
  260. package/vendor/heyspex-mcp/fleet-handlers.mjs +37 -0
  261. package/vendor/heyspex-mcp/fleet-queue-tools.mjs +69 -14
  262. package/vendor/heyspex-mcp/focus-tools.mjs +190 -0
  263. package/vendor/heyspex-mcp/folder-trust-store.mjs +59 -0
  264. package/vendor/heyspex-mcp/http-transport.mjs +300 -0
  265. package/vendor/heyspex-mcp/list-tools.mjs +257 -0
  266. package/vendor/heyspex-mcp/login-handoff.mjs +15 -1
  267. package/vendor/heyspex-mcp/mcp-config.mjs +94 -0
  268. package/vendor/heyspex-mcp/memory-tools.mjs +523 -0
  269. package/vendor/heyspex-mcp/mvp-mode.mjs +53 -6
  270. package/vendor/heyspex-mcp/occupied-keys.mjs +141 -0
  271. package/vendor/heyspex-mcp/on-deck-brief.mjs +3360 -0
  272. package/vendor/heyspex-mcp/on-deck-scheduler.mjs +1708 -0
  273. package/vendor/heyspex-mcp/package-root.mjs +32 -0
  274. package/vendor/heyspex-mcp/peer-presence.mjs +8 -1
  275. package/vendor/heyspex-mcp/plan-ground.mjs +621 -652
  276. package/vendor/heyspex-mcp/plan-push.mjs +906 -21
  277. package/vendor/heyspex-mcp/plan-review.mjs +124 -30
  278. package/vendor/heyspex-mcp/preflight-gate.mjs +0 -0
  279. package/vendor/heyspex-mcp/procedure-handlers.mjs +325 -0
  280. package/vendor/heyspex-mcp/procedure-tools.mjs +540 -351
  281. package/vendor/heyspex-mcp/promote-capture.mjs +386 -69
  282. package/vendor/heyspex-mcp/promote-diagnose.mjs +74 -0
  283. package/vendor/heyspex-mcp/promote-research-to-diagnose.mjs +9 -2
  284. package/vendor/heyspex-mcp/promote-research.mjs +660 -53
  285. package/vendor/heyspex-mcp/promotion-helpers.mjs +251 -0
  286. package/vendor/heyspex-mcp/prompts.mjs +1460 -0
  287. package/vendor/heyspex-mcp/read-path.mjs +29 -9
  288. package/vendor/heyspex-mcp/receipt-shape.mjs +146 -0
  289. package/vendor/heyspex-mcp/recipe-handlers.mjs +117 -0
  290. package/vendor/heyspex-mcp/regen-tasks.mjs +210 -3
  291. package/vendor/heyspex-mcp/register-spec.mjs +266 -54
  292. package/vendor/heyspex-mcp/request-context.mjs +59 -0
  293. package/vendor/heyspex-mcp/research-focus.mjs +207 -4
  294. package/vendor/heyspex-mcp/research-handlers.mjs +623 -0
  295. package/vendor/heyspex-mcp/research-tools.mjs +4 -4
  296. package/vendor/heyspex-mcp/response-budget.mjs +348 -0
  297. package/vendor/heyspex-mcp/review-focus.mjs +25 -1
  298. package/vendor/heyspex-mcp/search-specs.mjs +280 -0
  299. package/vendor/heyspex-mcp/seat-block-ledger.mjs +113 -0
  300. package/vendor/heyspex-mcp/seat-identity.mjs +2 -6
  301. package/vendor/heyspex-mcp/session-owner.mjs +108 -0
  302. package/vendor/heyspex-mcp/session-tools.mjs +152 -0
  303. package/vendor/heyspex-mcp/settings-registry.mjs +232 -0
  304. package/vendor/heyspex-mcp/settings-tools.mjs +85 -12
  305. package/vendor/heyspex-mcp/spec-edit-tools.mjs +446 -0
  306. package/vendor/heyspex-mcp/spec-id-lib.mjs +93 -17
  307. package/vendor/heyspex-mcp/split-research.mjs +301 -56
  308. package/vendor/heyspex-mcp/stdio-rpc.mjs +22 -0
  309. package/vendor/heyspex-mcp/submit-for-review.mjs +132 -6
  310. package/vendor/heyspex-mcp/summary-contract.mjs +105 -0
  311. package/vendor/heyspex-mcp/summary-write-tools.mjs +224 -0
  312. package/vendor/heyspex-mcp/symptom-query.mjs +146 -0
  313. package/vendor/heyspex-mcp/test-helpers.mjs +108 -1
  314. package/vendor/heyspex-mcp/tool-catalog.mjs +2813 -0
  315. package/vendor/heyspex-mcp/tool-dispatch.mjs +639 -0
  316. package/vendor/heyspex-mcp/tool-helpers.mjs +325 -0
  317. package/vendor/heyspex-mcp/validate-linkage.mjs +414 -27
  318. package/vendor/heyspex-mcp/vault-io.mjs +724 -0
  319. package/vendor/heyspex-mcp/vault-less-endpoints.mjs +52 -0
  320. package/vendor/heyspex-mcp/vault-resolve.mjs +366 -68
  321. package/vendor/heyspex-mcp/verify-reproduction.mjs +270 -30
  322. package/vendor/heyspex-mcp/whoami.mjs +91 -0
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: hs-next
3
+ description: Pull the next on-deck execution prompt from the HeySpex roadmap (focus.yaml → in_progress → open).
4
+ ---
5
+
6
+ <!-- Generated by scripts/sync-skills.mjs from .claude/commands/hs-next.md — do not edit by hand. Run `npm run skills:sync`. -->
7
+
8
+ **Usage:** `/hs-next [handheld|assist|auto] [HS-XXXX-EPIC | HS-XXXX] [--include-horizon] [--ignore-focus] [--claim]`
9
+
10
+ > **SaaS-safety note:** this file is a thin shim — the workflow orchestration (claim question wording, reply→action mapping, failure-mode handling) lives in `vendor/heyspex-mcp/cli.mjs` (`composeAgentOrchestration`) and is delivered to you as the structured `agent_dispatch` object. **Do not add orchestration prose here.** If a workflow detail needs to change, change it in the MCP server so customer workspaces can't corrupt it. See [[HS-CCKM-J6CD-RES-migrate-slash-command-orchestration-from]] and [[workflow-orchestration-belongs-in-mcp-not-claude-commands]].
11
+
12
+ ## What to do
13
+
14
+ 1. **Parse `$ARGUMENTS`** (all optional, order-flexible):
15
+ - **Run front** (default `handheld`): `handheld` · `assist` | `assisted` · `auto` | `autonomous` → canonical `front` for MCP (`handheld` | `assisted` | `autonomous`; omit when handheld/default)
16
+ - bare token `HS-EPIC-*` or `HS-*` → `spec_id`
17
+ - bare token `HS-ROADMAP-*` → `roadmap_id`
18
+ - `--include-horizon` → `include_horizon: true`
19
+ - `--ignore-focus` → `ignore_focus: true`
20
+ - `--claim` | `--auto-claim` → `auto_claim: true`. Skips the yes/proceed/confirm handshake and claims immediately — same mechanism `autonomous` front already triggers automatically (`shouldAutoClaimOnDeck` in `run-front.mjs`), just usable standalone at any front. `/hs-next HS-IUQO --claim` claims and starts handheld work with no ask; `/hs-next HS-IUQO assisted --claim` does the same at assisted supervision. (Redundant, never conflicting, with `autonomous` front, which already implies it.)
21
+
22
+ 2. **Call** `heyspex_next_on_deck` with `summary: true` plus the parsed args (including `front` when not handheld/default, and `auto_claim: true` when `--claim`/`--auto-claim` was passed).
23
+
24
+ 3. **Output the `user_prompt_markdown` field verbatim** to the user. Do not summarize, paraphrase, or trim. **Do NOT echo the `agent_dispatch` field** — it is a structured routing object you decode, not prose you print. (The @deprecated `prompt_markdown` field mirrors `user_prompt_markdown`; either is safe to print, but prefer `user_prompt_markdown`.) Schema: `specs/schemas/agent-dispatch.schema.json`.
25
+
26
+ 4. **On the user's reply**, decode `agent_dispatch`:
27
+ - Match the reply against each entry's `tokens` array under `on_user_reply` (or `drift_resolution_menu`, when present).
28
+ - If the matching entry has `actions`, invoke each `{ tool, args }` in order. If `execute_after: true`, begin executing the work in the same turn — no second permission ask. All listed tools (`heyspex_claim_spec`, `heyspex_record_alignment`, `heyspex_next_on_deck`, `heyspex_release_spec`) are pre-allowlisted.
29
+ - If the matching entry has `reply`, respond with that string verbatim.
30
+ - If the `default` entry is `"respond_to_user_question"`, treat the reply as a redirect: answer the user's actual question instead of claiming.
31
+ - For any tool error, look up its code in `agent_dispatch.failure_modes` and apply the named `handling` only when that error code was **returned by the tool call** — failure_modes are conditional, not a statement that the console is down. Trust `console_status.reachable` on the brief. Never hand-write vault files when `heyspex_file_spec` fails.
32
+ - On session hand-off, run the `on_handoff` actions (typically `heyspex_release_spec`).
@@ -0,0 +1,73 @@
1
+ ---
2
+ name: hs-promote
3
+ description: Promote whatever doc you hand it to its next stage — a capture (HS-CAP-*) to research, or a research doc (HS-RES-*) to a milestone with AI-assisted epic stubs. One verb, inferred by id prefix. Native command (carries full $ARGUMENTS; the MCP prompt only gets the first token).
4
+ ---
5
+
6
+ <!-- Generated by scripts/sync-skills.mjs from .claude/commands/hs-promote.md — do not edit by hand. Run `npm run skills:sync`. -->
7
+
8
+ **Usage:** `/hs-promote <HS-CAP-XXXX[,HS-CAP-YYYY...] | HS-RES-XXXX> [rest of args depend on which — see below]`
9
+
10
+ > **Platform asymmetry — read this, it is load-bearing.** Claude Code delivers only the **first whitespace token** of an MCP prompt's argument (GitHub [#14210](https://github.com/anthropics/claude-code/issues/14210), closed *not planned*), so the namespaced MCP prompts (`/hs-promote-capture`, `/hs-promote-research`) can each carry at most a single token. This **native project command** is the only IDE surface that receives full `$ARGUMENTS`.
11
+ >
12
+ > **Why one command instead of two.** `/hs-promote-capture` and `/hs-promote-research` used to be separate commands — which meant typing the word "promote" twice (`/hs-promote-capture HS-CAP-XXXX promote`) when the command name already said what it does. There's exactly one verb here — *promote whatever doc you hand it to its next stage* — so there's one command. The **id prefix alone** tells you which flow applies (`HS-CAP-*` vs `HS-RES-*` are mutually exclusive and mechanical to detect); the two flows underneath are otherwise unrelated (different tools, different payload shapes, different two-phase mechanics) and stay fully separate below — only the entrypoint is shared.
13
+
14
+ ## Step 0 — identify the doc
15
+
16
+ Read the **leading token** of `$ARGUMENTS` (case-insensitive; captures may be a comma/whitespace-separated list):
17
+ - Contains `-CAP` as its type label (legacy `HS-CAP-XXXX` or era-3 `HS-<fileKey>-<familyKey>-CAP-<slug>`) → go to **§A. Capture → research**.
18
+ - Contains `-RES` the same way → go to **§A2. Research → milestone**.
19
+ - **Era-3 short/display forms carry NO type label** — `HS-XV4W` (short id) and `HS-XV4W-HV6H` (file key + family key, the form humans see rendered) name a spec without saying its kind. Resolve the kind by fetching it: `heyspex_active_capture({ spec_id })` succeeding → it's a capture, §A. Otherwise treat it as research and try §A2. The tools accept any of these forms and collapse them to the stored short id themselves — never tell the user their id is wrong just because it carries (or lacks) the family key.
20
+ - None of the above → ask the user which doc they mean (don't guess).
21
+
22
+ If the capture tools are not already available in this session, call `heyspex_load_tools` first so `heyspex_active_capture` / `heyspex_promote_capture` / `heyspex_promote_capture_to_diagnose` are callable.
23
+
24
+ ---
25
+
26
+ ## §A. Capture → research (`HS-CAP-*`)
27
+
28
+ **1. Parse the rest of `$ARGUMENTS`:**
29
+ - Leading token(s) matching `HS-CAP-[A-Z0-9-]{3,}` (comma- and/or whitespace-separated) → `capture_ids` (1 or more).
30
+ - Next token: `HS-RES-[A-Z0-9-]{3,}` → `target_research` = that id. Or the literal word `new`/`NEW` (also the default when this token is omitted entirely) → `target_research = "NEW"`; any remaining words up to an `enhances:` token → `new_research_name`.
31
+ - A token shaped `enhances:HS-MIL-XXXX` anywhere in the string → `enhances`.
32
+
33
+ **2. Route by kind:**
34
+ - For each `capture_id`, read its `kind:` via `heyspex_active_capture({ spec_id: capture_id })`.
35
+ - Exactly one capture_id AND its `kind: bug-fix` → `heyspex_promote_capture_to_diagnose({ capture_id })` (creates `HS-DIAG-*`). Never mix a bug-fix capture into a multi-capture research promote.
36
+ - Otherwise → `heyspex_promote_capture({ capture_ids, target_research, new_research_name?, enhances? })`:
37
+ - `target_research === "NEW"` is **two-phase**: first call **omits** `accepted_outline` — it returns a proposed `{ name, outline, tags, enhances_suggestion }`. **Show it to the user and confirm** before calling again with the same args plus `accepted_outline` (Phase 2 performs the writes). Never skip straight to Phase 2.
38
+ - An existing `target_research` id is single-phase (direct, idempotent append) — no outline confirm needed.
39
+ - A `CAPTURE_INSUFFICIENT` error names the missing elements (core-idea, example, done-criteria, kind, user-stories) — the correct response is to elicit that detail from the user and improve the capture, not to pass `force_promote: true` unless the human explicitly says to promote anyway.
40
+ - **Check the outline against the capture's own Notes before presenting it.** Before showing `proposed_outline` (AI-proposed or agent-authored) to the user, walk every verbatim quote in the capture's `## Notes` and state plainly whether the outline addresses it. If a quote asks for something the outline doesn't cover, add a section for it or say so before asking for confirm — a missed verbatim quote is exactly what got two real items dropped from a milestone in this vault's own history ([[HS-GDT5-F16L-DIAG-promote-flow-drafts-research-and-stubs]]).
41
+ - **Outline confirm ≠ research done.** Phase 2 only writes the research **stub** — every section body is the literal placeholder `_TBD — fill in this section._`. Confirming the outline approves its *shape* (section headings), not its findings. As the very next step after Phase 2 creates the file, fill in every section with real content **by running the `/hs-res` method** (SpexCrawl gather via the Companion + DeepSeek synthesis — see `.claude/commands/hs-res.md`); **never author the research yourself in the main session** — main-session self-research skips the routed research seats and burns the expensive model on work the fleet owns. Do not report the research as complete, and do not move on to `/hs-promote-research`, until the TBD placeholders are gone. (`heyspex_promote_research` mechanically refuses with `RESEARCH_STILL_STUB` while any remain, but don't rely on that gate — write the research because it's the point of the flow, not because a check will otherwise fail.)
42
+
43
+ **3. Report the result** — the research id (created or extended) or diagnose id created, and confirm the capture(s)' `promoted_to` now points at it.
44
+
45
+ ---
46
+
47
+ ## §A2. Research → milestone (`HS-RES-*`)
48
+
49
+ **1. Parse the rest of `$ARGUMENTS`:**
50
+ - `research_id` is the leading `HS-RES-*` token (already identified in Step 0).
51
+ - Next word matching `spawn|augment|both` → `intent`. Default `spawn` when omitted.
52
+ - Next token: `HS-MIL-[A-Z0-9-]{3,}` → `target_milestone` = that id. Or the literal word `new`/`NEW` (also the default when this token is omitted entirely) → `target_milestone = "NEW"`; remaining words → `new_milestone_name`.
53
+ - If `intent` includes `augment`, any remaining `HS-EPIC-[A-Z0-9-]{3,}` tokens → `augment_epic_ids` (required in that case — ask for them if `augment` was requested but none were given).
54
+
55
+ **2. Default policy:** `target_milestone: "NEW"` unless the user names an **existing `status: open`** milestone that clearly extends the same thesis. Spawning into an `in_progress` milestone is blocked unless the owner explicitly passes `attach_to_in_progress_milestone: true` + `attach_override_reason` (≥40 chars audit trail) — never default to this path or infer the override on the agent's own judgment.
56
+
57
+ **3. Phase 1 — proposal.** Call `heyspex_promote_research({ research_id, target_milestone, new_milestone_name?, intent, spawn_epic_count?, augment_epic_ids? })` **without** `accepted_stubs`. Show the user the returned `proposed_stubs[]` and let them edit/remove/approve.
58
+ - **If `ai_proposal.ok === false` (e.g. `reason: "no_api_key"`), `proposed_stubs` comes back empty — the agent must author the stubs itself.** This is NOT a shortcut to skip the confirm step; it makes the confirm step *more* necessary, not less, because nothing upstream has vetted these stubs yet. Author them from the research doc's actual content, present them to the user exactly as you would an AI proposal (name/kind/effort/rationale per stub), and wait for a real approval turn before calling Phase 2. **Do not call Phase 2 in the same turn you authored the stubs in** — that is precisely the failure this line exists to prevent (observed 2026-08-12: an agent self-authored 3 epic stubs and executed `accepted_stubs` in the same tool-call batch with no human turn in between).
59
+ - **Check the stubs against the SOURCE CAPTURE's own Notes before presenting them.** Before showing `proposed_stubs` (AI-proposed or agent-authored) to the user, walk every verbatim quote in the source capture's `## Notes` — the capture(s) named in the research doc's `sources_captures`, not just the research doc's own prose, since a two-hop drift can lose fidelity the research doc's text won't show — and confirm each is addressed by a stub or explicitly named as out of scope. This check caught two real gaps missed by an agent-authored stub list in this vault's own history ([[HS-GDT5-F16L-DIAG-promote-flow-drafts-research-and-stubs]]).
60
+
61
+ **4. Phase 2 — execute (after human confirms).** Call again with the same args plus `accepted_stubs: [...]` (the confirmed, possibly-edited subset) to perform the transactional write.
62
+
63
+ **5. Report the result** — the milestone id (new or existing) plus spawned epic ids, or the augmented epic ids. Note that research stays `status: open` (research is evergreen) — only its `enhances:`/`spawned_epics:` links change.
64
+
65
+ ---
66
+
67
+ ## Hard prohibitions
68
+
69
+ - **Never** execute a Phase-2 write (`accepted_outline` or `accepted_stubs`) without the human having seen and confirmed the Phase-1 proposal. For `accepted_stubs` the tool now refuses this mechanically: the proposal turn leaves a marker keyed on the research id, and an execute turn without one returns `STUB_REVIEW_REQUIRED`. If the human replaced every proposed stub, pass `stub_edit_note` (≥40 chars) saying what they changed — otherwise a fully-drifted execute returns `STUB_REVIEW_DRIFT`. As with `RESEARCH_STILL_STUB`, treat the mechanical refusal as the backstop, not the first line of defense.
70
+ - **Never** call `heyspex_promote_research` against a research doc that still carries `_TBD — fill in this section._` placeholders — fill it in via the `/hs-res` method first (§A step 2 above), never by authoring the research yourself in the main session. The tool refuses this mechanically (`RESEARCH_STILL_STUB`) but the agent should never rely on that as the first line of defense.
71
+ - **Never** route a bug-fix capture through `heyspex_promote_capture` — it goes to `heyspex_promote_capture_to_diagnose` instead.
72
+ - **Never** attach a research promote to an `in_progress` milestone without an explicit owner override (`attach_to_in_progress_milestone` + `attach_override_reason`).
73
+ - **Never** commit or push.
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: hs-push
3
+ description: Push an epic implementation plan into the HeySpex vault, optionally pinning it on deck in the same call. Native command (carries full $ARGUMENTS; the MCP prompt only gets the first token). Consolidates the former hs-push / hs-push-next split into one command + flag.
4
+ ---
5
+
6
+ <!-- Generated by scripts/sync-skills.mjs from .claude/commands/hs-push.md — do not edit by hand. Run `npm run skills:sync`. -->
7
+
8
+ **Usage:** `/hs-push [<epic name>] [--next] [--reason <focus reason>]`
9
+
10
+ > **Platform asymmetry — read this, it is load-bearing.** Claude Code delivers only the **first whitespace token** of an MCP prompt's argument (GitHub [#14210](https://github.com/anthropics/claude-code/issues/14210), closed *not planned*), so the namespaced MCP prompts `/hs-push` / `/hs-push-next` can each carry at most a single token — never an epic name plus a `--next` flag plus a focus reason together. This **native project command** is the only IDE surface that receives full `$ARGUMENTS`. It also **consolidates** the old two-prompt split (`hs-push` vs `hs-push-next`) into one command: both ultimately call the same `heyspex_push_plan` tool with only `on_deck` differing, so there is no behavior lost by merging them here — just one flag instead of two command names.
11
+
12
+ ## What to do
13
+
14
+ **1. Parse `$ARGUMENTS`:**
15
+ - `--next` (anywhere, case-insensitive) → `on_deck = true`. Absent → `on_deck = false` (file the epic without pinning focus).
16
+ - `--reason <text>` → `focus_reason` (only meaningful when `on_deck` is true; rest of that flag's value up to the next `--` flag or end of string).
17
+ - Remaining leading, non-flag text → an `epic_name` hint. Optional — if omitted, derive the title from the plan under discussion in chat.
18
+
19
+ **2. Gather the rest of the payload from the conversation** (a Cursor/proprietary `.plan.md` the user pasted or referenced, or a plan already discussed in chat):
20
+ - `summary` — required plain-language frontmatter summary (spec-summary-authoring contract).
21
+ - `plan_markdown` — epic body markdown (goal, phases, acceptance criteria).
22
+ - `milestone` — **required**: the parent `HS-MIL-*` wikilink. Ask the user if it isn't obvious from context; the tool call fails without it.
23
+ - `source_plan_paths` — any `.plan.md` file paths referenced (auto-detected from `plan_markdown` too).
24
+ - `kind` / `effort` / `tags` / `related` — optional scheduler/classification fields.
25
+
26
+ **3. Call** `heyspex_push_plan({ epic_name, summary, plan_markdown, milestone, on_deck, focus_reason?, source_plan_paths?, kind?, effort?, tags?, related? })`. This writes the epic **only** — `children: []`; tasks are never filed here, only later via `/hs-next` breakdown.
27
+
28
+ **4. After the call:**
29
+ - `on_deck: true` → the epic is set `in_progress`, `.heyspex/focus.yaml` is written, and a NEXT STEP block is added. Tell the user to run `/hs-next` next.
30
+ - `on_deck: false` → tell the user to re-run `/hs-push --next` (or `/hs-next <the new epic id>`) when ready to start work.
31
+
32
+ **5. Conflict handling:** if the tool returns a behavioral-conflict block against `related` specs and `on_deck` was requested, the write is blocked by default (no files written, no focus pinned). Surface the conflicts to the user — only pass `skip_conflict_check: true` on their explicit say-so, and note a `conflict_override` should be recorded afterward.
33
+
34
+ ## Hard prohibitions
35
+
36
+ - **Never** file tasks here — epics only (`children: []`); tasks are just-in-time via `/hs-next` breakdown.
37
+ - **Never** silently bypass a conflict block — surface it and let the human decide.
38
+ - **Never** commit or push git.
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: hs-qc
3
+ description: Post-plan QC gut-check — stress-test a drafted plan before executing it (the plan→execute gate). Reason through the gut-check questions, launch explorers to fill gaps, fold findings into the plan, then record Proof-of-Use.
4
+ ---
5
+
6
+ <!-- Generated by scripts/sync-skills.mjs from .claude/commands/hs-qc.md — do not edit by hand. Run `npm run skills:sync`. -->
7
+
8
+ **Usage:** `/hs-qc [--plan <path>] (defaults to the most recent plan)`
9
+
10
+ > **Where this sits.** `/hs-ground` (pre-plan) → draft → `heyspex_plan_review` → **`/hs-qc`** → `ExitPlanMode`. Both plan-review + QC markers required ([[HS-R4OY]]).
11
+
12
+ ## What to do
13
+
14
+ **0. Mandatory drift passes** — Axis A (as-built code) + Axis B (design supersession per [[drift-is-two-axes-as-built-and-design-supersession]]). Re-run `heyspex_plan_review`; read `axis_b_drift`. Do not trust parent epic AC over newer memory decisions.
15
+
16
+ **0b. When `axis_b_drift` is non-empty — ask the user before recording QC:**
17
+
18
+ Present each conflict. **Default (Recommended):** re-scope the plan (remove dead work). **Override:** user explicitly confirms proceed anyway → `heyspex_plan_qc({ axis_b_user_confirmed: true, axis_b_confirmation_note: "…" })`. Tool returns `QC_AXIS_B_DRIFT` until resolved or user-confirmed. **The override is currently broken** per [[HS-EP8E-C1L2-DIAG-heyspex-plan-qc-override-path-ignores-ax]] (reproduced twice) — until fixed, `HEYSPEX_PLAN_QC_GATE_OFF=1` is the only working escape, and its use should be reported to the owner.
19
+
20
+ **1. Run the gut-check (verbatim — the owner's standard).**
21
+
22
+ Wonderful work! Can you please do a quality check and a gut-check? … *(full questions unchanged)*
23
+
24
+ **2. Act on what you find.** Fold findings into the plan; re-run `heyspex_plan_review` if material.
25
+
26
+ **3. Record Proof-of-Use.** `heyspex_plan_qc` with substantive `findings_summary` including **`Axis B:`** line.
27
+
28
+ **4. Then `ExitPlanMode`.**
29
+
30
+ (Break-glass: `HEYSPEX_PLAN_QC_GATE_OFF=1`.)
@@ -0,0 +1,67 @@
1
+ ---
2
+ name: hs-res
3
+ description: Confidence-ladder research method's entrypoint — SpexCrawl via the Companion (search/gather) is PRIMARY + DeepSeek (synthesis); self-hosted Firecrawl is an AUTOMATIC fallback (no permission needed, owner ruling 2026-08-22), zero Claude/Anthropic involvement.
4
+ ---
5
+
6
+ <!-- Generated by scripts/sync-skills.mjs from .claude/commands/hs-res.md — do not edit by hand. Run `npm run skills:sync`. -->
7
+
8
+ **Usage:** `/hs-res [research question/topic]`
9
+
10
+ # Research (`/hs-res`)
11
+
12
+ > Parity: `.commandcode/skills/hs-res/SKILL.md` · `.cursor/skills/hs-res/SKILL.md` · `.agents/skills/hs-res/SKILL.md`
13
+
14
+ ## What to do
15
+
16
+ 1. **Take the question.** `$ARGUMENTS` is the research question/topic. If empty, load the
17
+ console doc-toolbar Promote pin via `heyspex_active_research`
18
+ (`.heyspex/research-focus.yaml` → `source_idea_id`, `scope`, `spec_path`) and read the source
19
+ capture body as the question. Either way, restate the scope and confirm with the user.
20
+
21
+ 2. **Gather via SpexCrawl (the Companion) — the PRIMARY method** (owner ruling 2026-08-14,
22
+ [[spexcrawl-through-the-companion-is-the]]: "Companion > SpexCrawl is now default method
23
+ for research"). Decompose into a few independent search angles, then per angle:
24
+ `node dev-factory/spexcrawl/spexcrawl-cli.mjs search "<query>" --json` — one call
25
+ searches AND returns the cleaned pages of the top results. Specific extra URLs:
26
+ `node dev-factory/spexcrawl/spexcrawl-cli.mjs scrape "<url>" --json`.
27
+ Prerequisites: the Companion running and paired to the console. LAN mode
28
+ (`npm run console:log:lan`) is needed ONLY when the Companion runs on a DIFFERENT
29
+ machine than the console — since HS-V9WH the Companion polls loopback consoles too
30
+ ([[a-queue-is-dead-if-its-only-consumer]]: the LAN line was a bug workaround
31
+ misdocumented as a requirement). When missing, the CLI exits 3 with
32
+ `SPEXCRAWL_UNAVAILABLE` naming the fix; a silent hang means the Companion is not
33
+ running or not polling this console.
34
+
35
+ **Fallback — self-hosted Firecrawl, AUTOMATIC, no permission needed (owner ruling
36
+ 2026-08-22).** When the SpexCrawl path malfunctions, times out, hits a gate, or is otherwise
37
+ unavailable, fall back immediately: `node dev-factory/spexcrawl/firecrawl-cli.mjs
38
+ search "<query>" --json` and `node dev-factory/spexcrawl/firecrawl-cli.mjs scrape
39
+ "<url>" --json`. May run on any fleet machine (coffee-geek, basement-geek, spec-ops) —
40
+ prefer other reachable machines over the one the orchestrating session runs on; check
41
+ `docker info`, start Docker/the stack if needed, poll the real endpoint for readiness before
42
+ use. If this task's changed/claimed files are SpexCrawl-related, skip SpexCrawl entirely and
43
+ go straight to Firecrawl. Hosted `api.firecrawl.dev` credits are unchanged — still
44
+ ask-before-spend every time. Full contract: `.commandcode/skills/hs-res/SKILL.md`.
45
+
46
+ 3. **Assemble a numbered sources block** (`[S1]`, `[S2]`, …) from the gathered
47
+ `{title, url, snippet, markdown}` results, write it plus the question and cite-only
48
+ instructions to a temp prompt file.
49
+
50
+ 4. **Synthesize via DeepSeek** —
51
+ `node dev-factory/spexcrawl/synthesize-cli.mjs --prompt-file <path> --json`
52
+ (defaults `--max-tokens` to 32000 and auto-escalates ×3 up to a 96000 ceiling if DeepSeek's
53
+ default-on "thinking" mode burns the whole budget on reasoning — never pass a lower
54
+ `--max-tokens` yourself; the CLI self-heals this failure mode. Exhausted escalation exits 3
55
+ with `SYNTHESIZE_UNAVAILABLE`).
56
+
57
+ 5. **Save** via `heyspex_save_research` (or `heyspex_complete_research` under the console pin
58
+ pipeline), with `sources` populated from the gathered URLs.
59
+
60
+ **Never fall back** to `deep-research`/`deep-research-quick|medium|thorough`, the
61
+ `Workflow({ scriptPath: '.claude/workflows/deep-research-*.js' })` launch, or native
62
+ `WebSearch`/`WebFetch` for this method. Self-hosted Firecrawl fallback is automatic (no
63
+ permission needed, 2026-08-22 ruling); hosted `api.firecrawl.dev` credits still need the
64
+ user's explicit per-run permission, every time. If a CLI reports unavailable
65
+ (`SPEXCRAWL_UNAVAILABLE` / `FIRECRAWL_UNAVAILABLE` / `SYNTHESIZE_UNAVAILABLE`, exit 3),
66
+ **stop** and tell the user — never silently substitute another backend. Full method,
67
+ escalation rule, and hard prohibitions: `.commandcode/skills/hs-res/SKILL.md`.
@@ -0,0 +1,26 @@
1
+ ---
2
+ name: hs-resolve
3
+ description: Pull the top open item from the HeySpex Resolution lane (conflicts, dangling refs, cycles, prerequisites, validation/stale-index) with a fix brief. Replaces the old conflict-only prompt.
4
+ ---
5
+
6
+ <!-- Generated by scripts/sync-skills.mjs from .claude/commands/hs-resolve.md — do not edit by hand. Run `npm run skills:sync`. -->
7
+
8
+ **Usage:** `/hs-resolve [HS-XXXX-EPIC | <item-key> | --ignore-focus]`
9
+
10
+ Invoke the `heyspex_next_resolution` MCP tool to fetch the top open resolution item from the HeySpex vault, then paste the returned `prompt_markdown` verbatim so the user can act on the fix brief.
11
+
12
+ Argument parsing for `$ARGUMENTS` (all optional; if empty, call the tool with no parameters):
13
+
14
+ - A token containing `:` (e.g. `dangling_ref:hs-epic-x:hs-task-y`) → pass as `item_key` (fetch that specific item's brief; bypasses the focus pin).
15
+ - A bare spec id matching `HS-EPIC-*` / `HS-TASK-*` / `HS-MIL-*` / `HS-*-*` → pass as `scope` (deck-aware: restrict detection to that spec so its gating prerequisite/conflicts surface). This is what the On-Deck `resolve_command: /hs-resolve <epic-id>` passes.
16
+ - `--ignore-focus` → set `ignore_focus: true` (skip the Neon resolution focus pin; lead with the top-ranked open item).
17
+
18
+ Resolution precedence (built into the tool — do not re-implement): `item_key` → `scope`/`ignore_focus` (top-ranked of the open list) → the Neon focus pin (server-applied) → top-ranked open item. Items are ordered with **gating** and **errors first** (`orderResolutionItems`).
19
+
20
+ After the tool returns, output the `prompt_markdown` field as-is, then on a final line state the source: `_Source: {source} · {item.kind} · {item.key}_`. Do not summarize, paraphrase, or start executing actions from the brief without the user's go-ahead.
21
+
22
+ This is the surviving `/hs-resolve` (the legacy conflict-only prompt that errored **"Not an Epic"** on a milestone has been retired — the resolver is item-centric and never type-checks the target). Authority from the brief's resolution menu: **Re-scan / clear** is agent-autonomous; **Switch to this**, **Defer**, **edge removal**, and **override** require explicit user confirmation. `stale_index` items expose **only** re-scan/clear — never an edge-mutating action.
23
+
24
+ Detection is HTTP-only (the tool reads the console aggregator — the one detection path — it does not re-detect). If the tool errors with `CONSOLE_UNREACHABLE`, tell the user to **start the console dev server (port 3000, or run `hs server status` to see which port it actually bound)** — this only happens on a dev machine; SaaS console is always up. On `CONSOLE_TIMEOUT`, suggest retrying shortly (the server may be cold-compiling). On `ITEM_NOT_FOUND`, the `item_key` is not in the open set — list items with `/hs-resolve` (no args).
25
+
26
+ This skill does NOT claim or build anything; it presents the fix brief. Sibling skills: `/hs-next` (build pipeline), `/hs-review` (review pipeline), `/hs-resolve` (this — resolution lane). See [[HS-0EJ6-RMCP-EPIC-hs-resolve-mcp-tool-and-skill]] and [[HS-I8FM-RSRF-EPIC-resolution-surface-api-and-pin]].
@@ -0,0 +1,26 @@
1
+ ---
2
+ name: hs-review
3
+ description: Pull the next review-ready spec from the HeySpex review queue (review-focus.yaml → manifest traversal of `status: in_review` with HS-REV companion → folder scan).
4
+ ---
5
+
6
+ <!-- Generated by scripts/sync-skills.mjs from .claude/commands/hs-review.md — do not edit by hand. Run `npm run skills:sync`. -->
7
+
8
+ **Usage:** `/hs-review [HS-XXXX-TASK | HS-XXXX-EPIC] [--ignore-focus]`
9
+
10
+ Invoke the `heyspex_next_review` MCP tool to fetch the next review-ready spec from the HeySpex vault, then paste the returned `prompt_markdown` verbatim so the user (reviewer) can walk acceptance against the parent spec + HS-REV companion.
11
+
12
+ Argument parsing for `$ARGUMENTS` (all optional; if `$ARGUMENTS` is empty, call the tool with no parameters):
13
+
14
+ - A bare token matching `HS-TASK-*` / `HS-EPIC-*` / `HS-*-*` → pass as `spec_id`.
15
+ - A bare token matching `HS-ROADMAP-*` → pass as `roadmap_id`.
16
+ - `--ignore-focus` → set `ignore_focus: true`.
17
+
18
+ Resolution precedence (built into the tool, do not re-implement here): `args.spec_id` → `.heyspex/review-focus.yaml` pin → manifest traversal for `status: in_review` specs with an `HS-REV-<suffix>-*.md` companion → folder scan as fallback. Sorted by `updated:` ascending (oldest first).
19
+
20
+ After the tool returns, output the `prompt_markdown` field as-is, then on a final line state the source: `_Source: {source_kind} · {spec_id} · phase {phase_id} · age {age_in_review_days}d_`. Do not summarize, paraphrase, or start executing the returned prompt.
21
+
22
+ This skill does NOT claim the spec. Reviewing is a human-in-loop activity by design (CLAUDE.md §Session Completion); the reviewer walks the four sections of the HS-REV companion (`## Acceptance verification`, `## Reviewer notes`, `## Memory candidates`, `## Decision: close or reopen`) and decides pass/reopen. Memory candidates are scored against the four-axis rubric (non-derivability / reusability / surprise-cost / concreteness, 0–3 each, threshold ≥ 7/12) — the prompt body includes the rubric and the conflict-check instruction.
23
+
24
+ If the tool errors with `NO_REVIEW_READY`, tell the user the review queue is empty (no specs at `status: in_review` with an HS-REV companion) and suggest checking `specs/reviews/` for stale companions or filing the missing review doc. If `SPEC_NOT_IN_REVIEW`, surface the spec's actual status so the user can pick the right `/hs-review HS-XXXX` target. If `NO_REVIEW_DOC`, the parent spec is `in_review` but has no `HS-REV-<suffix>-*.md` companion — point the user at CLAUDE.md §Session Completion §3 for the four-section template.
25
+
26
+ Cross-reference: [[HS-XRO1-RVDC-TASK-heyspex-review-on-deck-mcp-and-hs-review]] (spec), [[HS-UKD6-CLR4-RES-close-out-review-screen-jtbd-architecture]] §J17 (downstream Review surface that will call this tool from the "Copy `/hs-review`" affordance).
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: hs-view
3
+ description: Open one console surface in a chromeless app-mode browser window (solo console gauge) — pipeline funnel first; follows the focus pin when no doc id is given. Thin wrapper over `hs view`.
4
+ ---
5
+
6
+ <!-- Generated by scripts/sync-skills.mjs from .claude/commands/hs-view.md — do not edit by hand. Run `npm run skills:sync`. -->
7
+
8
+ **Usage:** `/hs-view [surface] [doc id] [--width N] [--height N] [--browser edge|chrome]`
9
+
10
+ # HeySpex solo-surface viewer (`/hs-view`)
11
+
12
+ > Parity: `.commandcode/skills/hs-view/SKILL.md` · `.cursor/skills/hs-view/SKILL.md` · `.agents/skills/hs-view/SKILL.md`
13
+
14
+ Optional macro over the one core ([[capability-three-faces-no-per-capability-slash]]): shell to `hs view`, never reimplement it. Design: [[HS-RU2R-I87U-RES-solo-surface-cli-launcher-single]].
15
+
16
+ ## What to do
17
+
18
+ 1. **Resolve `$ARGUMENTS` by smart first-token detection** — grammar is positional, token-identical with the CLI:
19
+ - First token looks like a spec id (`HS-…`) → doc id; surface defaults to `pipeline`.
20
+ - First token is a surface slug (`pipeline`, `docs`, `whats-next`, `captures`, `session-log`, `settings`) → second token, if present, is the doc id (anchors `pipeline` and `docs` only).
21
+ - No arguments → `pipeline`, anchored on the focus pin (live-follow).
22
+ - Pass `--width` / `--height` / `--browser edge|chrome` through unchanged.
23
+ 2. **Run it yourself** from the repo root:
24
+ ```bash
25
+ node bin/hs.mjs view <surface> [<doc-id>] [flags]
26
+ ```
27
+ 3. The verb probes ground-truth dev-server status first — if the console is down, relay its message and offer `npm run dev` (don't start the server unprompted).
28
+ 4. Relay the one-line result (URL + window size); closing the window closes it, re-running reopens it.
29
+
30
+ Never hand-build `msedge --app=…` invocations — the CLI verb owns server probing, URL resolution, and browser mechanics.
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: kill-ports
3
+ description: Kill every process listening on a TCP port in the range 3000–5999 (clears stuck dev servers).
4
+ ---
5
+
6
+ <!-- Generated by scripts/sync-skills.mjs from .claude/commands/kill-ports.md — do not edit by hand. Run `npm run skills:sync`. -->
7
+
8
+ **Usage:** `/kill-ports (no arguments)`
9
+
10
+ **Always use the PowerShell tool for this command — never the Bash tool.** Bash routes to a POSIX shell in this environment and the PowerShell syntax below will fail there.
11
+
12
+ Kill all processes that are **listening** on TCP ports in the range **3000–5999** inclusive. This clears orphaned dev servers (Next.js, console, companion bridges, etc.) that are holding ports.
13
+
14
+ Run this single command via the **PowerShell** tool. It discovers the listening connections in range, reports each `port → pid (process name)` it is about to kill, then force-kills the unique owning PIDs and confirms:
15
+
16
+ ```powershell
17
+ $conns = Get-NetTCPConnection -State Listen -ErrorAction SilentlyContinue |
18
+ Where-Object { $_.LocalPort -ge 3000 -and $_.LocalPort -le 5999 }
19
+ if (-not $conns) { Write-Output 'No listeners on ports 3000-5999. Nothing to kill.'; return }
20
+ $pids = $conns | Select-Object -ExpandProperty OwningProcess -Unique
21
+ foreach ($c in $conns) {
22
+ $p = Get-Process -Id $c.OwningProcess -ErrorAction SilentlyContinue
23
+ $name = if ($p) { $p.ProcessName } else { '?' }
24
+ Write-Output ("port {0,-5} -> pid {1} ({2})" -f $c.LocalPort, $c.OwningProcess, $name)
25
+ }
26
+ foreach ($procId in $pids) {
27
+ try { Stop-Process -Id $procId -Force -ErrorAction Stop; Write-Output ("killed pid {0}" -f $procId) }
28
+ catch { Write-Output ("could not kill pid {0}: {1}" -f $procId, $_.Exception.Message) }
29
+ }
30
+ ```
31
+
32
+ Notes:
33
+ - Only TCP **listeners** are targeted, so client/outbound connections in that range are left alone.
34
+ - If `Stop-Process` fails on a PID (e.g. a Windows system process like `svchost`, which needs admin and shouldn't be killed anyway, or a process that already exited), report the `Access is denied` / error and continue with the rest — do not abort the whole run.
35
+ - After running, briefly summarize how many ports were freed.
@@ -0,0 +1,95 @@
1
+ ---
2
+ name: prototype
3
+ description: Build an HTML/frontend prototype for the HeySpex Console. Files MUST land in spex-console/public/design-previews/<slug>-v<N>[-<variant>].html with a sibling .meta.json that validates against specs/schemas/prototype-meta.schema.json. Use this any time the user asks to "build a prototype", "mock up a UI", or invokes /frontend-design in this repo.
4
+ ---
5
+
6
+ <!-- Generated by scripts/sync-skills.mjs from .claude/commands/prototype.md — do not edit by hand. Run `npm run skills:sync`. -->
7
+
8
+ **Usage:** `/prototype <slug> [--from-spec HS-XXXX] [--bump] [--variant <name>]`
9
+
10
+ This skill is the **implementation** of `specs/protocols/prototype-lifecycle-protocol.md`. The protocol is the SSOT — when they conflict, the protocol wins and this skill is the bug. Fetch it with `heyspex_get_procedure({ name: "prototype-lifecycle-protocol" })` when you need the full rules.
11
+
12
+ It applies to:
13
+
14
+ - explicit `/prototype` invocation
15
+ - any natural-language "build me an HTML prototype / mock / preview / canvas" ask
16
+ - `/frontend-design` invocations in this repo (the plugin builds the artifact; this skill governs placement)
17
+
18
+ ## The contract — no exceptions
19
+
20
+ **Required output paths** (both files, same commit):
21
+
22
+ 1. `spex-console/public/design-previews/<slug>-v<N>[-<variant>].html` — the self-contained prototype.
23
+ 2. `spex-console/public/design-previews/<slug>-v<N>[-<variant>].meta.json` — the sidecar.
24
+
25
+ Anything outside this folder — including a stray top-level `prototypes/` directory — is **invisible** to the console. The route at `spex-console/src/app/api/ui-design/prototypes/route.ts` reads this folder flat (no recursion, no nested folders). A prototype that doesn't show up in the Prototypes surface does not exist for the user.
26
+
27
+ ## Naming
28
+
29
+ - **`<slug>`** (lineage slug) — kebab-case, describes the surface (`capture-canvas`, `shipped-surface`, `review-inbox`). May contain hyphens. **Match an existing lineage if you're iterating on a known surface** — grep `spex-console/public/design-previews/` before inventing a new slug.
30
+ - **`-v<N>`** — version, starts at `-v1`. **Bump rather than overwrite.** The console groups versions into a lineage with full history. If `--bump`, increment from the highest existing `-v<N>` for that slug.
31
+ - **`-<variant>`** (optional) — sibling variant within a version (e.g. `-v2-alt`, `-v2-minimal`, `-v2-terminal`). May contain hyphens. The console nests variants under their parent version and shows a `+N variants at vK` chip on the lineage card. Variants are for "A/B explorations of the same version", not new lineages.
32
+ - **No `index.html`, no nested folders, no dated filenames.** Just `<slug>-v<N>[-<variant>].html`.
33
+
34
+ ## meta.json schema
35
+
36
+ Validate against `specs/schemas/prototype-meta.schema.json`. Required: `title` + `status`. Always set `surface_area` and 1–4 `tags` on new sidecars (the console's filter rail depends on them — leaving them empty makes the prototype harder to find).
37
+
38
+ ```json
39
+ {
40
+ "title": "Human-readable name (e.g. 'Capture canvas v2')",
41
+ "description": "One-paragraph summary: what it demonstrates, key interactions, aesthetic direction, technical notes. The console hides this on the card and shows it in the drawer Notes tab — write for that context.",
42
+ "status": "draft",
43
+ "surface_area": "capture | on-deck | preloader | shell | review | roadmap | other",
44
+ "tags": ["kebab-case", "1-to-4"],
45
+ "updated_at": "2026-06-03T18:17:00.000Z",
46
+ "design_doc": "specs/ui/<slug>-design.md (optional but required for promotion to accepted)",
47
+ "linked_specs": [
48
+ "HS-XXXX-CAP-...",
49
+ "HS-XXXX-EPIC-..."
50
+ ],
51
+ "parent": "<slug>-v<N-1>.html (optional, when this iterates on a prior version)",
52
+ "embeds": ["other-prototype-slug (optional)"]
53
+ }
54
+ ```
55
+
56
+ - **`status` MUST be `"draft"` at create time.** Promotion to `"accepted"` runs through the console's `/api/ui-design/prototypes/<slug>/promote` route and requires both a linked `design_doc` AND a review entry under `specs/reviews/`. The skill does not write `accepted` — refuse if the user asks. (`"archived"` is for superseded versions; usually set later, not at create time.)
57
+ - **Compute `updated_at` as `new Date().toISOString()`** at write time.
58
+ - **`linked_specs`** accepts vault basenames (no `.md` extension) and `HS-*` IDs. Always include the capture/epic/task the prototype embodies. Pull from `--from-spec` if provided. Never invent IDs.
59
+ - Reference siblings in this folder for examples — `shipped-surface-v1.meta.json` (thorough) or `on-deck-v2.meta.json` (minimal).
60
+
61
+ ## Workflow
62
+
63
+ When this skill is invoked or matched:
64
+
65
+ 1. **Resolve lineage slug.** Match an existing slug if iterating on a known surface; otherwise pick a new kebab-case slug.
66
+ 2. **Resolve version.** Default `-v1`. If a file with the same slug already exists, default to bumping to the next integer; honour explicit `--bump`. **Never silently overwrite** — if the target file exists and `--bump` was not passed, surface the conflict and ask.
67
+ 3. **Resolve variant.** `--variant <name>` produces `<slug>-v<N>-<name>.html`. Without it, you produce the base variant.
68
+ 4. **Pull source spec context.** If `--from-spec HS-XXXX` is passed or the user references a spec, Read it first so the prototype reflects real content, not invented filler.
69
+ 5. **Aesthetic.** Defer to the user's brief (e.g. "Claude-in-PowerShell terminal aesthetic" overrides defaults). Otherwise honour console design-system tokens — fetch via `heyspex_design_*` MCP tools, do not grep `spex-console/DESIGN.md`. Recall UI memories first: `heyspex_recall_memories({ tags: ["ui", "console", "design-system"] })`.
70
+ 6. **Decide `surface_area` and `tags`.** Pick `surface_area` from the enum based on what the prototype shows. Pick 1–4 lowercase kebab-case `tags` covering the dominant patterns (e.g. `empty-state`, `dark-mode`, `keyboard-nav`).
71
+ 7. **Write both files in the same commit.** HTML at `spex-console/public/design-previews/<slug>-v<N>[-<variant>].html`, sidecar at the matching `.meta.json` path. Single self-contained HTML file (inline CSS/JS).
72
+ 8. **Validate the sidecar shape** against the schema before saving. Required: `title` + `status`. `status` MUST be `"draft"`. `tags` MUST match `^[a-z0-9-]+$`. `surface_area` MUST be in the enum. `linked_specs[]` items MUST match `^HS-[A-Z0-9]+-` (family keys contain digits, e.g. `HS-9HVY-CAP`). Fix and re-write if any fail.
73
+ 9. **Confirm.** After writing, report the gallery URL (`/design-previews/<slug>-v<N>[-<variant>].html`). The console's UI-Design → Prototypes surface picks it up via `/api/ui-design/prototypes` and groups it into the matching lineage automatically.
74
+
75
+ ## Anti-patterns — do not do these
76
+
77
+ - Do **not** create a new `prototypes/` folder at the repo root.
78
+ - Do **not** nest as `<slug>/index.html`.
79
+ - Do **not** overwrite an existing `<slug>-v<N>[-<variant>].html` — bump or use a new variant.
80
+ - Do **not** ship without a sibling sidecar.
81
+ - Do **not** write `status: "accepted"` from this skill — promotion runs through the console's `/promote` route only.
82
+ - Do **not** invent linked specs. Only reference `HS-*` IDs that exist in the vault.
83
+ - Do **not** leave `surface_area` and `tags` empty on new sidecars — the console's filter rail depends on them.
84
+ - Do **not** Read `spex-console/DESIGN.md` for token lookups; use `heyspex_design_get_token` / `heyspex_design_get_pattern` MCP tools.
85
+
86
+ ## Reference
87
+
88
+ - **Protocol (SSOT):** `specs/protocols/prototype-lifecycle-protocol.md` — fetch with `heyspex_get_procedure({ name: "prototype-lifecycle-protocol" })`
89
+ - **Schema (SSOT):** `specs/schemas/prototype-meta.schema.json`
90
+ - **Discovery route:** `spex-console/src/app/api/ui-design/prototypes/route.ts`
91
+ - **Surface component:** `spex-console/src/components/surfaces/ui-design-surface.tsx`
92
+ - **Lineage parser:** `spex-console/src/lib/prototype-lineage.ts`
93
+ - **Folder:** `spex-console/public/design-previews/`
94
+ - **Thorough sidecar example:** `shipped-surface-v1.meta.json`
95
+ - **Minimal sidecar example:** `on-deck-v2.meta.json`