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
|
@@ -11,10 +11,27 @@ import {
|
|
|
11
11
|
rmSync,
|
|
12
12
|
readdirSync,
|
|
13
13
|
} from 'node:fs';
|
|
14
|
-
import { join } from 'node:path';
|
|
14
|
+
import { join, isAbsolute, resolve, sep } from 'node:path';
|
|
15
15
|
import { parseSimpleFocusYaml } from './capture-focus.mjs';
|
|
16
16
|
import { yamlScalar } from './yaml-scalar.mjs';
|
|
17
|
-
import {
|
|
17
|
+
import { ownerFrontmatterEntry, resolveSessionOwner } from './session-owner.mjs';
|
|
18
|
+
import { collectOccupiedKeysEitherKind, familyOf, mintFamilyKey, mintFileKey, parseSpecId } from './spec-id-lib.mjs';
|
|
19
|
+
import { assertPathUnderRoot } from '../../scripts/lib/shared-path-helpers.mjs';
|
|
20
|
+
// Cloud-mode vault WRITES ([[HS-BYU4-CWPX-TASK-promotion-writes-go-through-the-console]]).
|
|
21
|
+
// `heyspex_complete_research` is a promotion in the same shape as the others:
|
|
22
|
+
// it CREATES a research doc and then LINKS the source idea/capture to it via
|
|
23
|
+
// `promoted_to:` — a basename the console only mints when the POST answers.
|
|
24
|
+
import {
|
|
25
|
+
createSpecViaConsole,
|
|
26
|
+
updateSpecViaConsole,
|
|
27
|
+
} from './cloud-vault-writes.mjs';
|
|
28
|
+
import {
|
|
29
|
+
fetchSpecRecordViaConsole,
|
|
30
|
+
resolveWriteModeFromDeps,
|
|
31
|
+
splitRawSpecForConsole,
|
|
32
|
+
cloudWriteFailureResult,
|
|
33
|
+
} from './promotion-helpers.mjs';
|
|
34
|
+
|
|
18
35
|
|
|
19
36
|
export function researchFocusPath(vaultRoot) {
|
|
20
37
|
return join(vaultRoot, '.heyspex', 'research-focus.yaml');
|
|
@@ -42,6 +59,11 @@ export function writeResearchFocus(vaultRoot, { specPath, sourceIdeaId, scope, r
|
|
|
42
59
|
return { error: 'INVALID_SCOPE', message: `scope must be one of ${[...VALID_SCOPES].join('|')}` };
|
|
43
60
|
}
|
|
44
61
|
const dir = join(vaultRoot, '.heyspex');
|
|
62
|
+
try {
|
|
63
|
+
assertPathUnderRoot(vaultRoot, dir, 'research-focus write');
|
|
64
|
+
} catch (err) {
|
|
65
|
+
return { error: 'BAD_VAULT_ROOT', message: err.message };
|
|
66
|
+
}
|
|
45
67
|
mkdirSync(dir, { recursive: true });
|
|
46
68
|
const lines = [
|
|
47
69
|
'# HeySpex research-on-deck — MCP /hs-res ([[idea-capture-guardrails]])',
|
|
@@ -189,6 +211,161 @@ function collectOccupiedResearchIds(vaultRoot) {
|
|
|
189
211
|
return occupied;
|
|
190
212
|
}
|
|
191
213
|
|
|
214
|
+
/**
|
|
215
|
+
* Cloud write mode ([[HS-BYU4-CWPX-TASK-promotion-writes-go-through-the-console]]):
|
|
216
|
+
* the same two-step promotion the disk path performs, reordered CREATE FIRST /
|
|
217
|
+
* LINK SECOND because the console mints the research doc's id, family and
|
|
218
|
+
* filename — so the `promoted_to:` wikilink the source idea gets can only be
|
|
219
|
+
* built after `POST /api/specs` returns.
|
|
220
|
+
*
|
|
221
|
+
* Nothing is minted locally: `mintFileKey` / `mintFamilyKey` /
|
|
222
|
+
* `allocateRandomVaultId` all draw against a vault scan, which in a file-less
|
|
223
|
+
* vault is empty and can therefore collide with a key the cloud vault already
|
|
224
|
+
* holds. An INHERITED family (read off the source idea, never minted) is still
|
|
225
|
+
* passed through, matching the disk path's precedence.
|
|
226
|
+
*
|
|
227
|
+
* The research-focus PIN stays on local disk: it is per-workstation machine
|
|
228
|
+
* state under the local dot-directory, not vault content, and nothing indexes
|
|
229
|
+
* it (same call HS-KR16 made for the promote-research review-gate markers).
|
|
230
|
+
*/
|
|
231
|
+
async function completeResearchViaConsole(vaultRoot, args, deps, { sourceIdeaId, scope }) {
|
|
232
|
+
const cloudDeps = { consoleFetch: deps?.consoleFetch, consoleUrl: deps?.consoleUrl };
|
|
233
|
+
const completed = [];
|
|
234
|
+
|
|
235
|
+
// 1. The source idea/capture, through the console — there is no local file.
|
|
236
|
+
let ideaRecord;
|
|
237
|
+
try {
|
|
238
|
+
ideaRecord = await fetchSpecRecordViaConsole(deps?.consoleFetch, sourceIdeaId);
|
|
239
|
+
} catch (err) {
|
|
240
|
+
return cloudWriteFailureResult(err, {
|
|
241
|
+
step: { kind: 'read', type: 'source_idea', spec_id: sourceIdeaId },
|
|
242
|
+
completed,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
if (!ideaRecord) {
|
|
246
|
+
return {
|
|
247
|
+
error: 'IDEA_NOT_FOUND',
|
|
248
|
+
message: `Source idea ${sourceIdeaId} was not found through the console (cloud write mode — no local vault is consulted).`,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const ideaFmId =
|
|
253
|
+
ideaRecord.raw.match(/^id:\s*(\S+)/m)?.[1]?.replace(/^['"]|['"]$/g, '') ?? null;
|
|
254
|
+
const ideaFamilyValue =
|
|
255
|
+
ideaRecord.raw.match(/^family:\s*(\S+)/m)?.[1]?.replace(/^['"]|['"]$/g, '') ?? null;
|
|
256
|
+
const familyKey = familyOf({
|
|
257
|
+
id: ideaFmId ?? sourceIdeaId,
|
|
258
|
+
basename: ideaRecord.basename,
|
|
259
|
+
frontmatter: { family: ideaFamilyValue },
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
263
|
+
const tags = Array.isArray(args.tags) ? args.tags : ['research'];
|
|
264
|
+
const related = Array.isArray(args.related) ? [...args.related] : [];
|
|
265
|
+
const sourceLink = `[[${ideaRecord.basename}]]`;
|
|
266
|
+
if (!related.some((r) => String(r).includes(sourceIdeaId))) {
|
|
267
|
+
related.unshift(sourceLink);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// 2. CREATE FIRST. `id`/`file_id`/`created`/`updated` are all server-minted
|
|
271
|
+
// and therefore absent from the request by construction — and so is
|
|
272
|
+
// `status` ([[HS-ISZP]]): the console seeds `open` and refuses an
|
|
273
|
+
// out-of-band status on create.
|
|
274
|
+
const frontmatter = {
|
|
275
|
+
...(familyKey ? { family: familyKey } : {}),
|
|
276
|
+
// An explicit `args.owner` wins; else the paired session account; else the
|
|
277
|
+
// key is OMITTED ([[HS-WE87-WW9R-TASK-thread-the-gated-caller-through-every]]).
|
|
278
|
+
...ownerFrontmatterEntry({
|
|
279
|
+
explicit: args.owner,
|
|
280
|
+
resolve: deps?.resolveSessionOwner ?? resolveSessionOwner,
|
|
281
|
+
}),
|
|
282
|
+
tags,
|
|
283
|
+
related,
|
|
284
|
+
source_idea: sourceLink,
|
|
285
|
+
scope,
|
|
286
|
+
};
|
|
287
|
+
let created;
|
|
288
|
+
try {
|
|
289
|
+
created = await createSpecViaConsole({
|
|
290
|
+
...cloudDeps,
|
|
291
|
+
type: 'research',
|
|
292
|
+
name: args.title,
|
|
293
|
+
summary: args.executive_summary?.trim() || args.summary?.trim() || null,
|
|
294
|
+
frontmatter,
|
|
295
|
+
body: buildResearchBody(args, { sourceIdeaId, scope }),
|
|
296
|
+
actingAgent: deps?.actingAgent ?? null,
|
|
297
|
+
});
|
|
298
|
+
} catch (err) {
|
|
299
|
+
return cloudWriteFailureResult(err, {
|
|
300
|
+
step: { kind: 'create', type: 'research', name: args.title },
|
|
301
|
+
completed,
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
completed.push({
|
|
305
|
+
kind: 'create',
|
|
306
|
+
type: 'research',
|
|
307
|
+
spec_id: created.specId,
|
|
308
|
+
basename: created.basename,
|
|
309
|
+
rel_path: created.relPath,
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
// 3. …LINK SECOND: the idea's `promoted_to:` names the basename the POST
|
|
313
|
+
// returned, so this could not have been built any earlier.
|
|
314
|
+
const ideaSplit = splitRawSpecForConsole(ideaRecord.raw);
|
|
315
|
+
const ideaFrontmatter = {
|
|
316
|
+
...ideaSplit.frontmatter,
|
|
317
|
+
promoted_to: `[[${created.basename}]]`,
|
|
318
|
+
updated: today,
|
|
319
|
+
};
|
|
320
|
+
try {
|
|
321
|
+
const res = await updateSpecViaConsole({
|
|
322
|
+
...cloudDeps,
|
|
323
|
+
specId: ideaFmId ?? sourceIdeaId,
|
|
324
|
+
frontmatter: ideaFrontmatter,
|
|
325
|
+
body: ideaSplit.body,
|
|
326
|
+
});
|
|
327
|
+
completed.push({
|
|
328
|
+
kind: 'update',
|
|
329
|
+
type: 'source_idea',
|
|
330
|
+
spec_id: res.specId,
|
|
331
|
+
basename: res.basename ?? ideaRecord.basename,
|
|
332
|
+
rel_path: res.relPath,
|
|
333
|
+
});
|
|
334
|
+
} catch (err) {
|
|
335
|
+
return {
|
|
336
|
+
error: 'IDEA_UPDATE_FAILED',
|
|
337
|
+
message:
|
|
338
|
+
`Research ${created.specId} was created through the console at ${created.relPath}, but linking ` +
|
|
339
|
+
`${sourceIdeaId} back to it failed: ${String(err?.message ?? err)}`,
|
|
340
|
+
research_id: created.specId,
|
|
341
|
+
research_path: created.relPath,
|
|
342
|
+
write_mode: 'cloud',
|
|
343
|
+
completed_steps: completed,
|
|
344
|
+
partial: true,
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const pinResult = clearResearchFocus(vaultRoot);
|
|
349
|
+
|
|
350
|
+
return {
|
|
351
|
+
success: true,
|
|
352
|
+
write_mode: 'cloud',
|
|
353
|
+
research_id: created.specId,
|
|
354
|
+
research_path: created.relPath,
|
|
355
|
+
research_basename: created.basename,
|
|
356
|
+
source_idea_id: sourceIdeaId,
|
|
357
|
+
source_idea_path: ideaRecord.relPath,
|
|
358
|
+
scope,
|
|
359
|
+
pin_cleared: pinResult.existed,
|
|
360
|
+
writes: completed.map((w) => ({ kind: w.kind, path: w.rel_path ?? null, spec_id: w.spec_id })),
|
|
361
|
+
next_steps: [
|
|
362
|
+
`Open ${created.specId} in console to review the draft research`,
|
|
363
|
+
'Add wikilinks back to related specs',
|
|
364
|
+
'Add `enhances:` to bind this research to a milestone, or `bound_epic:` when an epic is filed from it',
|
|
365
|
+
],
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
|
|
192
369
|
/**
|
|
193
370
|
* Atomically write the research file, update the source idea's `promoted_to`,
|
|
194
371
|
* and clear the research-focus pin. Returns the new research id + path.
|
|
@@ -237,6 +414,20 @@ export function executeCompleteResearch(vaultRoot, args = {}, deps = {}) {
|
|
|
237
414
|
};
|
|
238
415
|
}
|
|
239
416
|
}
|
|
417
|
+
// ── Vault WRITE mode ([[HS-BYU4-CWPX-TASK-promotion-writes-go-through-the-console]]) ──
|
|
418
|
+
//
|
|
419
|
+
// Resolved ONCE here from `deps.writeMode` (the caller's single
|
|
420
|
+
// `resolveVaultWriteMode()` call) and defaulting to `local`, so every
|
|
421
|
+
// pre-existing caller keeps the SYNCHRONOUS disk path below — this function
|
|
422
|
+
// is deliberately NOT declared `async`: `handleCompleteResearch` consumes
|
|
423
|
+
// its return value synchronously, and making it async would turn that into
|
|
424
|
+
// an unawaited Promise. The cloud branch returns a Promise instead, which a
|
|
425
|
+
// cloud-aware caller awaits (and `await` on the plain object the disk branch
|
|
426
|
+
// returns is a no-op, so one call site can serve both).
|
|
427
|
+
if (resolveWriteModeFromDeps(deps) === 'cloud') {
|
|
428
|
+
return completeResearchViaConsole(vaultRoot, args, deps, { sourceIdeaId, scope });
|
|
429
|
+
}
|
|
430
|
+
|
|
240
431
|
if (!deps.allocateRandomVaultId) {
|
|
241
432
|
return { error: 'MISSING_DEPS', message: 'allocateRandomVaultId is required' };
|
|
242
433
|
}
|
|
@@ -284,11 +475,19 @@ export function executeCompleteResearch(vaultRoot, args = {}, deps = {}) {
|
|
|
284
475
|
mintFamilyKey(vaultRoot);
|
|
285
476
|
// Per-file FILE KEY (owner ruling 2026-07-10) — filename + `file_id:` SSOT,
|
|
286
477
|
// and (V3) the anchor for `id:` itself.
|
|
287
|
-
|
|
478
|
+
// Disk occupancy ([[HS-FJWL]]): this writer commits through the disk-only
|
|
479
|
+
// `commitWrites`, and the caller resolves `deps.writeMode` before reaching
|
|
480
|
+
// it, so the vault walk is complete on every path that gets here.
|
|
481
|
+
const fileKey = mintFileKey(collectOccupiedKeysEitherKind(vaultRoot));
|
|
288
482
|
const newId = `HS-${fileKey}`;
|
|
289
483
|
const slug = slugify(args.title);
|
|
290
484
|
const filename = `${newId}-${familyKey}-RES-${slug}.md`;
|
|
291
485
|
const researchDir = join(vaultRoot, 'specs', 'research');
|
|
486
|
+
try {
|
|
487
|
+
assertPathUnderRoot(vaultRoot, researchDir, 'research-focus write');
|
|
488
|
+
} catch (err) {
|
|
489
|
+
return { error: 'BAD_VAULT_ROOT', message: err.message };
|
|
490
|
+
}
|
|
292
491
|
mkdirSync(researchDir, { recursive: true });
|
|
293
492
|
const absResearchPath = join(researchDir, filename);
|
|
294
493
|
|
|
@@ -307,7 +506,11 @@ export function executeCompleteResearch(vaultRoot, args = {}, deps = {}) {
|
|
|
307
506
|
name: args.title,
|
|
308
507
|
type: 'research',
|
|
309
508
|
status: 'open',
|
|
310
|
-
|
|
509
|
+
// Same owner rule as the cloud twin above.
|
|
510
|
+
...ownerFrontmatterEntry({
|
|
511
|
+
explicit: args.owner,
|
|
512
|
+
resolve: deps?.resolveSessionOwner ?? resolveSessionOwner,
|
|
513
|
+
}),
|
|
311
514
|
created: today,
|
|
312
515
|
updated: today,
|
|
313
516
|
tags,
|