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.
- package/.claude-plugin/marketplace.json +14 -0
- package/README.md +21 -0
- package/bin/hs.mjs +1089 -104
- package/bin/spexcode.mjs +262 -0
- package/dev-factory/engine/worktree.mjs +740 -0
- package/dev-factory/lib/code-repo-root.mjs +67 -0
- package/dev-factory/lib/context-budget.mjs +84 -0
- package/dev-factory/lib/epic-detect.mjs +190 -0
- package/dev-factory/lib/fleet-queue-file.mjs +846 -0
- package/dev-factory/lib/fleet-queue.mjs +426 -0
- package/dev-factory/lib/fleet-state.mjs +14 -18
- package/dev-factory/lib/model-catalog.mjs +338 -0
- package/dev-factory/lib/seat-context.mjs +199 -0
- package/dev-factory/lib/spec-io.mjs +93 -0
- package/dev-factory/lib/sufficiency-score.mjs +8 -2
- package/dev-factory/lib/worktree-allocator.mjs +744 -0
- package/dev-factory/model-catalog.json +222 -0
- package/dist/cli/hs-check.mjs +1127 -103
- package/dist/cli/hs-claim.mjs +981 -63
- package/dist/cli/hs-connect.mjs +10059 -1729
- package/dist/cli/hs-defer.mjs +5507 -3072
- package/dist/cli/hs-dev.mjs +576 -0
- package/dist/cli/hs-env.mjs +416 -302
- package/dist/cli/hs-index-rebuild.mjs +7334 -0
- package/dist/cli/hs-index-reconcile.mjs +8138 -0
- package/dist/cli/hs-init.mjs +2840 -149
- package/dist/cli/hs-install.mjs +7214 -594
- package/dist/cli/hs-join.mjs +10640 -2421
- package/dist/cli/hs-vault-pull.mjs +8157 -6370
- package/dist/cli/hs-vault-push.mjs +6433 -0
- package/dist/cli/hs-vault.mjs +4029 -1555
- package/dist/cli/hs-workspace.mjs +2702 -538
- package/dist/cli-templates/customer-vault/specs/entity-model.md +594 -601
- package/dist/cli-templates/customer-vault/specs/protocols/canonical-frontmatter-templates.md +110 -177
- package/dist/cli-templates/customer-vault/specs/protocols/destructive-action-checklist.md +122 -0
- package/dist/cli-templates/customer-vault/specs/protocols/memory-protocol.md +13 -15
- package/dist/cli-templates/customer-vault/specs/protocols/session-close-protocol.md +91 -0
- package/dist/cli-templates/customer-vault/specs/protocols/spec-hierarchy.md +150 -168
- package/dist/cli-templates/customer-vault/specs/protocols/spec-summary-authoring.md +83 -0
- package/dist/cli-templates/harness-commands/claude/hs-auto.md +36 -0
- package/dist/cli-templates/harness-commands/claude/hs-backfill.md +28 -0
- package/dist/cli-templates/harness-commands/claude/hs-capture.md +62 -0
- package/dist/cli-templates/harness-commands/claude/hs-defer.md +29 -0
- package/dist/cli-templates/harness-commands/claude/hs-dev.md +20 -0
- package/dist/cli-templates/harness-commands/claude/hs-doctor.md +32 -0
- package/dist/cli-templates/harness-commands/claude/hs-ground.md +30 -0
- package/dist/cli-templates/harness-commands/claude/hs-handoff.md +33 -0
- package/dist/cli-templates/harness-commands/claude/hs-log.md +27 -0
- package/dist/cli-templates/harness-commands/claude/hs-next.md +29 -0
- package/dist/cli-templates/harness-commands/claude/hs-promote.md +70 -0
- package/dist/cli-templates/harness-commands/claude/hs-push.md +35 -0
- package/dist/cli-templates/harness-commands/claude/hs-qc.md +27 -0
- package/dist/cli-templates/harness-commands/claude/hs-res.md +63 -0
- package/dist/cli-templates/harness-commands/claude/hs-resolve.md +23 -0
- package/dist/cli-templates/harness-commands/claude/hs-review.md +23 -0
- package/dist/cli-templates/harness-commands/claude/hs-view.md +28 -0
- package/dist/cli-templates/harness-commands/claude/kill-ports.md +32 -0
- package/dist/cli-templates/harness-commands/claude/prototype.md +91 -0
- package/dist/cli-templates/harness-commands/cursor/hs-auto.md +40 -0
- package/dist/cli-templates/harness-commands/cursor/hs-backfill.md +31 -0
- package/dist/cli-templates/harness-commands/cursor/hs-capture.md +65 -0
- package/dist/cli-templates/harness-commands/cursor/hs-defer.md +32 -0
- package/dist/cli-templates/harness-commands/cursor/hs-dev.md +24 -0
- package/dist/cli-templates/harness-commands/cursor/hs-doctor.md +36 -0
- package/dist/cli-templates/harness-commands/cursor/hs-ground.md +33 -0
- package/dist/cli-templates/harness-commands/cursor/hs-handoff.md +37 -0
- package/dist/cli-templates/harness-commands/cursor/hs-log.md +31 -0
- package/dist/cli-templates/harness-commands/cursor/hs-next.md +32 -0
- package/dist/cli-templates/harness-commands/cursor/hs-promote.md +73 -0
- package/dist/cli-templates/harness-commands/cursor/hs-push.md +38 -0
- package/dist/cli-templates/harness-commands/cursor/hs-qc.md +30 -0
- package/dist/cli-templates/harness-commands/cursor/hs-res.md +67 -0
- package/dist/cli-templates/harness-commands/cursor/hs-resolve.md +26 -0
- package/dist/cli-templates/harness-commands/cursor/hs-review.md +26 -0
- package/dist/cli-templates/harness-commands/cursor/hs-view.md +32 -0
- package/dist/cli-templates/harness-commands/cursor/kill-ports.md +35 -0
- package/dist/cli-templates/harness-commands/cursor/prototype.md +95 -0
- package/docs/copilot-plugin-install.md +162 -0
- package/docs/driving-heyspex-from-copilot.md +165 -0
- package/docs/mcp-client-config.md +259 -6
- package/package.json +249 -124
- package/plugins/heyspex/.claude-plugin/plugin.json +12 -0
- package/plugins/heyspex/.cursor-plugin/plugin.json +15 -0
- package/plugins/heyspex/.mcp.json +12 -0
- package/plugins/heyspex/README.md +309 -0
- package/plugins/heyspex/bin/launch-mcp.mjs +95 -0
- package/plugins/heyspex/bin/run-hook.mjs +80 -0
- package/plugins/heyspex/hooks/cursor-hooks.json +308 -0
- package/plugins/heyspex/hooks/hooks.json +418 -0
- package/plugins/heyspex/mcp.json +13 -0
- package/scripts/check-mcp-freshness.mjs +17 -9
- package/scripts/claude-hooks/_env-vault-events.mjs +68 -0
- package/scripts/claude-hooks/_guardrail-events.mjs +96 -0
- package/scripts/claude-hooks/_guardrail-loader.mjs +494 -0
- package/scripts/claude-hooks/_intent-classifier-router.mjs +456 -0
- package/scripts/claude-hooks/_intent-classifier-semantic.mjs +356 -0
- package/scripts/claude-hooks/_run.mjs +413 -0
- package/scripts/claude-hooks/_transcript-text.mjs +60 -0
- package/scripts/claude-hooks/_vault-retrieval.mjs +322 -0
- package/scripts/claude-hooks/agent-spawn-delegation-gate.mjs +133 -0
- package/scripts/claude-hooks/capture-execution-gate.mjs +51 -0
- package/scripts/claude-hooks/capture-workflow-gate.mjs +11 -0
- package/scripts/claude-hooks/check-auto-memory-budget.mjs +396 -0
- package/scripts/claude-hooks/check-claude-md-budget.mjs +327 -0
- package/scripts/claude-hooks/check-mcp-freshness-hook.mjs +14 -0
- package/scripts/claude-hooks/claim-before-code-gate.mjs +11 -0
- package/scripts/claude-hooks/claim-liveness-shared.mjs +577 -0
- package/scripts/claude-hooks/close-terminal-on-ship.mjs +64 -0
- package/scripts/claude-hooks/coo-denylist-gate.mjs +11 -0
- package/scripts/claude-hooks/coo-guard-check.mjs +11 -0
- package/scripts/claude-hooks/deep-research-cost-gate.mjs +11 -0
- package/scripts/claude-hooks/dev-server-task-reminder.mjs +15 -0
- package/scripts/claude-hooks/diagnose-capture-reminder.mjs +11 -0
- package/scripts/claude-hooks/directive-obligation-gate.mjs +11 -0
- package/scripts/claude-hooks/emit-claim-status.mjs +41 -0
- package/scripts/claude-hooks/enforce-session-sequence.mjs +11 -0
- package/scripts/claude-hooks/enforce-vault-naming.mjs +11 -0
- package/scripts/claude-hooks/env-vault-guard.mjs +11 -0
- package/scripts/claude-hooks/epic-milestone-phrasing-gate.mjs +11 -0
- package/scripts/claude-hooks/git-identity-guard.mjs +11 -0
- package/scripts/claude-hooks/git-reflog-audit.mjs +15 -0
- package/scripts/claude-hooks/git-stash-gate.mjs +11 -0
- package/scripts/claude-hooks/guard-auto-memory-writes.mjs +137 -0
- package/scripts/claude-hooks/id-display-format-gate.mjs +11 -0
- package/scripts/claude-hooks/inject-communication-style.mjs +86 -0
- package/scripts/claude-hooks/inject-coo-seat.mjs +78 -0
- package/scripts/claude-hooks/inject-dev-server-awareness.mjs +11 -0
- package/scripts/claude-hooks/inject-doctrine.mjs +13 -0
- package/scripts/claude-hooks/inject-vault-context.mjs +14 -0
- package/scripts/claude-hooks/intent-classifier-trigger.mjs +279 -0
- package/scripts/claude-hooks/log-session-activity.mjs +341 -0
- package/scripts/claude-hooks/naughty-list-gate.mjs +11 -0
- package/scripts/claude-hooks/notify-status-flip.mjs +72 -0
- package/scripts/claude-hooks/plan-exit-ingest-gate.mjs +170 -0
- package/scripts/claude-hooks/plan-ingest-close-reminder.mjs +66 -0
- package/scripts/claude-hooks/plan-review-gate.mjs +11 -0
- package/scripts/claude-hooks/preflight-reminder.mjs +262 -0
- package/scripts/claude-hooks/protected-action-intent.mjs +221 -0
- package/scripts/claude-hooks/research-method-guard.mjs +398 -0
- package/scripts/claude-hooks/research-protocol-gate.mjs +11 -0
- package/scripts/claude-hooks/session-end.mjs +451 -0
- package/scripts/claude-hooks/settings-write-gate.mjs +11 -0
- package/scripts/claude-hooks/settlement-check-gate.mjs +39 -0
- package/scripts/claude-hooks/status-flip-detect.mjs +17 -0
- package/scripts/claude-hooks/terminal-close-shared.mjs +426 -0
- package/scripts/claude-hooks/terminal-close-watcher.mjs +122 -0
- package/scripts/claude-hooks/vault-mirror-catchup.mjs +11 -0
- package/scripts/claude-hooks/vault-write-tier-guard.mjs +11 -0
- package/scripts/claude-hooks/wip-checkpoint.mjs +302 -0
- package/scripts/cursor-hooks/manifest.mjs +281 -0
- package/scripts/dev-server-status.mjs +34 -13
- package/scripts/dev-server-stop.mjs +313 -0
- package/scripts/heyspex-mode.mjs +288 -0
- package/scripts/hs-auto-resolve.mjs +240 -0
- package/scripts/hs-auto-source.mjs +398 -0
- package/scripts/hs-auto.mjs +134 -0
- package/scripts/hs-capture-cli.mjs +326 -0
- package/scripts/hs-classifier.mjs +136 -0
- package/scripts/hs-companion.mjs +88 -0
- package/scripts/hs-gateway.mjs +115 -0
- package/scripts/hs-mode.mjs +125 -0
- package/scripts/hs-next.mjs +441 -0
- package/scripts/hs-settings.mjs +338 -0
- package/scripts/hs-view.mjs +496 -0
- package/scripts/hs-worktree.mjs +201 -0
- package/scripts/install-claude-code-hooks.mjs +272 -0
- package/scripts/install-cursor-hooks.mjs +471 -0
- package/scripts/lib/agent-env-markers.mjs +38 -0
- package/scripts/lib/console-url-resolver.mjs +199 -61
- package/scripts/lib/customer-kit.mjs +1203 -0
- package/scripts/lib/dev-mode.mjs +249 -32
- package/scripts/lib/directive-obligations.mjs +349 -0
- package/scripts/lib/heyspex-home.mjs +72 -0
- package/scripts/lib/hook-dispositions.mjs +210 -0
- package/scripts/lib/hook-vault-header.mjs +30 -0
- package/scripts/lib/hs-command.mjs +277 -0
- package/scripts/lib/hs-companion-settings.mjs +472 -0
- package/scripts/lib/hs-source-branch.mjs +196 -0
- package/scripts/lib/hs-source-commit.mjs +59 -5
- package/scripts/lib/hs-source-identity.mjs +526 -0
- package/scripts/lib/hs-source-log.mjs +13 -22
- package/scripts/lib/hs-source-preflight.mjs +18 -4
- package/scripts/lib/hs-source-push.mjs +386 -307
- package/scripts/lib/hs-worktree-args.mjs +115 -0
- package/scripts/lib/shared-path-helpers.mjs +134 -0
- package/scripts/lib/standalone-doctor.mjs +540 -3
- package/scripts/lib/subagent-git-lock.mjs +109 -0
- package/scripts/lib/template-pin.mjs +34 -0
- package/scripts/lib/window-placement.mjs +109 -0
- package/scripts/provenance-lib.mjs +91 -0
- package/scripts/stamp-provenance-on-edit.mjs +222 -0
- package/scripts/wip-ledger-health.mjs +653 -0
- package/spexharness/doctrine/baseline/SPEXCODE-DOCTRINE.baseline.json +29 -0
- package/spexharness/src/adapters/audit.mjs +197 -0
- package/spexharness/src/adapters/claude-code.mjs +449 -0
- package/spexharness/src/adapters/copilot.mjs +236 -0
- package/spexharness/src/adapters/detect-harness.mjs +34 -0
- package/spexharness/src/chat/tui/ansi.mjs +448 -0
- package/spexharness/src/chat/tui/palette.mjs +22 -0
- package/spexharness/src/chat/tui/select.mjs +208 -0
- package/spexharness/src/config-root.mjs +54 -0
- package/spexharness/src/context-budget.mjs +141 -0
- package/spexharness/src/dev-server-control.mjs +389 -0
- package/spexharness/src/doctrine/behaviour.mjs +371 -0
- package/spexharness/src/doctrine/corpus.mjs +733 -0
- package/spexharness/src/doctrine/inject.mjs +338 -0
- package/spexharness/src/doctrine/merge.mjs +184 -0
- package/spexharness/src/doctrine/sources.mjs +252 -0
- package/spexharness/src/doctrine/synthesize.mjs +401 -0
- package/spexharness/src/doctrine/vault-source.mjs +574 -0
- package/spexharness/src/doctrine/writer.mjs +176 -0
- package/spexharness/src/events.mjs +84 -0
- package/spexharness/src/gates/_shell-write-targets.mjs +77 -0
- package/spexharness/src/gates/capture-workflow-gate.mjs +202 -0
- package/spexharness/src/gates/claim-before-code-gate.decide.mjs +33 -0
- package/spexharness/src/gates/claim-before-code-gate.mjs +129 -0
- package/spexharness/src/gates/deep-research-cost-gate.mjs +275 -0
- package/spexharness/src/gates/diagnose-capture-reminder.mjs +112 -0
- package/spexharness/src/gates/directive-obligation-gate.decide.mjs +132 -0
- package/spexharness/src/gates/directive-obligation-gate.mjs +183 -0
- package/spexharness/src/gates/enforce-session-sequence.mjs +895 -0
- package/spexharness/src/gates/enforce-vault-naming.mjs +215 -0
- package/spexharness/src/gates/epic-milestone-phrasing-gate.mjs +233 -0
- package/spexharness/src/gates/git-identity-guard.decide.mjs +436 -0
- package/spexharness/src/gates/git-identity-guard.mjs +61 -0
- package/spexharness/src/gates/git-reflog-audit.mjs +151 -0
- package/spexharness/src/gates/git-stash-gate.decide.mjs +361 -0
- package/spexharness/src/gates/git-stash-gate.mjs +159 -0
- package/spexharness/src/gates/id-display-format-gate.mjs +190 -0
- package/spexharness/src/gates/inject-doctrine-gate.mjs +89 -0
- package/spexharness/src/gates/inject-vault-context.mjs +239 -0
- package/spexharness/src/gates/naughty-list-gate.mjs +213 -0
- package/spexharness/src/gates/plan-review-gate.mjs +233 -0
- package/spexharness/src/gates/preflight-reminder-gate.mjs +265 -0
- package/spexharness/src/gates/research-protocol-gate.mjs +175 -0
- package/spexharness/src/gates/settings-write-gate.decide.mjs +96 -0
- package/spexharness/src/gates/settings-write-gate.mjs +104 -0
- package/spexharness/src/gates/vault-mirror-catchup.mjs +124 -0
- package/spexharness/src/gates/vault-write-tier-guard.decide.mjs +125 -0
- package/spexharness/src/gates/vault-write-tier-guard.mjs +42 -0
- package/spexharness/src/git-reflog-audit.mjs +294 -0
- package/spexharness/src/intent-classifier.mjs +196 -0
- package/spexharness/src/intent-directive.mjs +626 -0
- package/spexharness/src/profile/learn.mjs +551 -0
- package/spexharness/src/profile/proposals.mjs +357 -0
- package/spexharness/src/profile/vault-inclusion.mjs +386 -0
- package/spexharness/src/redact.mjs +151 -0
- package/spexharness/src/rule-table.mjs +849 -0
- package/spexharness/src/seat-context.mjs +122 -0
- package/spexharness/src/session-bootstrap.mjs +512 -0
- package/spexharness/src/session-record.mjs +815 -0
- package/spexharness/src/token-inventory.mjs +207 -0
- package/vendor/heyspex-mcp/account-switch.mjs +96 -0
- package/vendor/heyspex-mcp/alignment-gate.mjs +315 -1
- package/vendor/heyspex-mcp/blocker-resolver.mjs +37 -2
- package/vendor/heyspex-mcp/breakdown-ladder.mjs +119 -4
- package/vendor/heyspex-mcp/breakdown-source.mjs +271 -0
- package/vendor/heyspex-mcp/breakdown-writer.mjs +23 -3
- package/vendor/heyspex-mcp/capture-buffer-patches.mjs +77 -8
- package/vendor/heyspex-mcp/capture-channel.mjs +55 -5
- package/vendor/heyspex-mcp/capture-console-client.mjs +117 -3
- package/vendor/heyspex-mcp/capture-focus.mjs +1061 -31
- package/vendor/heyspex-mcp/capture-outbox.mjs +15 -5
- package/vendor/heyspex-mcp/capture-sources.mjs +195 -0
- package/vendor/heyspex-mcp/capture-tools.mjs +1264 -0
- package/vendor/heyspex-mcp/claim-tools.mjs +1147 -0
- package/vendor/heyspex-mcp/cli-verbs.mjs +2074 -0
- package/vendor/heyspex-mcp/cli.mjs +207 -15524
- package/vendor/heyspex-mcp/close-branch-report.mjs +102 -0
- package/vendor/heyspex-mcp/cloud-tool-surface.mjs +128 -0
- package/vendor/heyspex-mcp/cloud-vault-writes.mjs +602 -0
- package/vendor/heyspex-mcp/config-seed.yaml +15 -0
- package/vendor/heyspex-mcp/config-settings.mjs +290 -7
- package/vendor/heyspex-mcp/console-fetch.mjs +822 -17
- package/vendor/heyspex-mcp/console-transport.mjs +172 -0
- package/vendor/heyspex-mcp/credentials.mjs +585 -0
- package/vendor/heyspex-mcp/defer-spec.mjs +44 -4
- package/vendor/heyspex-mcp/deferred-reclaim.mjs +29 -3
- package/vendor/heyspex-mcp/design-handlers.mjs +31 -0
- package/vendor/heyspex-mcp/design-tools.mjs +4 -1
- package/vendor/heyspex-mcp/dev-factory-bridge.mjs +4 -4
- package/vendor/heyspex-mcp/dev-mode-core.mjs +45 -0
- package/vendor/heyspex-mcp/dev-tools.mjs +131 -0
- package/vendor/heyspex-mcp/diagnose-handlers.mjs +54 -0
- package/vendor/heyspex-mcp/events-tools.mjs +207 -0
- package/vendor/heyspex-mcp/filing-tools.mjs +723 -0
- package/vendor/heyspex-mcp/fleet-handlers.mjs +37 -0
- package/vendor/heyspex-mcp/fleet-queue-tools.mjs +71 -15
- package/vendor/heyspex-mcp/focus-tools.mjs +190 -0
- package/vendor/heyspex-mcp/folder-trust-store.mjs +60 -0
- package/vendor/heyspex-mcp/http-transport.mjs +302 -0
- package/vendor/heyspex-mcp/list-tools.mjs +257 -0
- package/vendor/heyspex-mcp/login-handoff.mjs +15 -1
- package/vendor/heyspex-mcp/mcp-config.mjs +107 -0
- package/vendor/heyspex-mcp/memory-tools.mjs +523 -0
- package/vendor/heyspex-mcp/mvp-mode.mjs +53 -6
- package/vendor/heyspex-mcp/obligation-backstop.mjs +103 -0
- package/vendor/heyspex-mcp/occupied-keys.mjs +142 -0
- package/vendor/heyspex-mcp/on-deck-brief.mjs +3377 -0
- package/vendor/heyspex-mcp/on-deck-scheduler.mjs +1708 -0
- package/vendor/heyspex-mcp/package-root.mjs +32 -0
- package/vendor/heyspex-mcp/peer-presence.mjs +8 -1
- package/vendor/heyspex-mcp/plan-ground.mjs +621 -652
- package/vendor/heyspex-mcp/plan-push.mjs +908 -22
- package/vendor/heyspex-mcp/plan-review.mjs +124 -30
- package/vendor/heyspex-mcp/preflight-gate.mjs +0 -0
- package/vendor/heyspex-mcp/procedure-handlers.mjs +327 -0
- package/vendor/heyspex-mcp/procedure-tools.mjs +1181 -970
- package/vendor/heyspex-mcp/promote-capture.mjs +388 -69
- package/vendor/heyspex-mcp/promote-diagnose.mjs +74 -0
- package/vendor/heyspex-mcp/promote-research-to-diagnose.mjs +9 -2
- package/vendor/heyspex-mcp/promote-research.mjs +666 -53
- package/vendor/heyspex-mcp/promotion-helpers.mjs +251 -0
- package/vendor/heyspex-mcp/prompts.mjs +1460 -0
- package/vendor/heyspex-mcp/read-path.mjs +191 -15
- package/vendor/heyspex-mcp/receipt-shape.mjs +146 -0
- package/vendor/heyspex-mcp/recipe-handlers.mjs +117 -0
- package/vendor/heyspex-mcp/regen-tasks.mjs +210 -3
- package/vendor/heyspex-mcp/register-spec.mjs +266 -54
- package/vendor/heyspex-mcp/request-context.mjs +83 -0
- package/vendor/heyspex-mcp/research-focus.mjs +207 -4
- package/vendor/heyspex-mcp/research-handlers.mjs +625 -0
- package/vendor/heyspex-mcp/research-tools.mjs +4 -4
- package/vendor/heyspex-mcp/response-budget.mjs +348 -0
- package/vendor/heyspex-mcp/review-focus.mjs +25 -1
- package/vendor/heyspex-mcp/roadmap-default.mjs +70 -0
- package/vendor/heyspex-mcp/search-specs.mjs +280 -0
- package/vendor/heyspex-mcp/seat-block-ledger.mjs +113 -0
- package/vendor/heyspex-mcp/seat-identity.mjs +2 -6
- package/vendor/heyspex-mcp/session-owner.mjs +109 -0
- package/vendor/heyspex-mcp/session-tools.mjs +162 -0
- package/vendor/heyspex-mcp/settings-registry.mjs +232 -0
- package/vendor/heyspex-mcp/settings-tools.mjs +85 -12
- package/vendor/heyspex-mcp/spec-edit-tools.mjs +453 -0
- package/vendor/heyspex-mcp/spec-id-lib.mjs +93 -17
- package/vendor/heyspex-mcp/split-research.mjs +304 -56
- package/vendor/heyspex-mcp/stdio-rpc.mjs +22 -0
- package/vendor/heyspex-mcp/submit-for-review.mjs +150 -7
- package/vendor/heyspex-mcp/summary-contract.mjs +105 -0
- package/vendor/heyspex-mcp/summary-write-tools.mjs +228 -0
- package/vendor/heyspex-mcp/symptom-query.mjs +146 -0
- package/vendor/heyspex-mcp/test-helpers.mjs +123 -1
- package/vendor/heyspex-mcp/tool-catalog.mjs +2819 -0
- package/vendor/heyspex-mcp/tool-dispatch.mjs +657 -0
- package/vendor/heyspex-mcp/tool-helpers.mjs +325 -0
- package/vendor/heyspex-mcp/validate-linkage.mjs +414 -27
- package/vendor/heyspex-mcp/vault-io.mjs +720 -0
- package/vendor/heyspex-mcp/vault-less-endpoints.mjs +52 -0
- package/vendor/heyspex-mcp/vault-resolve.mjs +554 -68
- package/vendor/heyspex-mcp/verify-reproduction.mjs +270 -30
- package/vendor/heyspex-mcp/whoami.mjs +92 -0
- 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
|
+
}
|