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
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
// spexharness/src/intent-classifier.mjs
|
|
2
|
+
//
|
|
3
|
+
// Intent classification as an engine module on the prompt_submit event (HS-5ISS, epic
|
|
4
|
+
// HS-1YDJ), replacing scripts/claude-hooks/_intent-classifier-router.mjs's per-prompt prose
|
|
5
|
+
// injection with a mechanical lexical check against the engine's own compiled rule table
|
|
6
|
+
// (./rule-table.mjs's loadRuleTable — the same registry _guardrail-loader.mjs reads, so this
|
|
7
|
+
// module and the Claude Code hook agree about what a rule's pattern set and inject text are;
|
|
8
|
+
// neither re-derives the other's regex).
|
|
9
|
+
//
|
|
10
|
+
// THE COST FIX (why this task exists): the original hook's Layer 2 ("self_check" semantic
|
|
11
|
+
// mode) injects a multi-behavior "gate" block — one section per classifier behavior, several
|
|
12
|
+
// KB of behavior descriptions — on every prompt that MISSES every lexical pattern and is at
|
|
13
|
+
// least 12 characters long. That fires on almost every substantive prompt (an ordinary work
|
|
14
|
+
// order matches none of the five behaviors' regex), which is the ~6.5 KB/prompt the epic
|
|
15
|
+
// measured. This module drops that speculative layer entirely: classification here is
|
|
16
|
+
// LEXICAL ONLY. A rule's `inject` text is resolved and returned only when one of its own
|
|
17
|
+
// compiled patterns actually matches the prompt (AC2, "the directive is fetched only when a
|
|
18
|
+
// gate fires") — a prompt that matches nothing produces `{ decision: 'allow' }` with no
|
|
19
|
+
// injected text at all, which is the <500-byte target on a plain prompt (AC3).
|
|
20
|
+
//
|
|
21
|
+
// SCOPE NOTE: `classifyPrompt` is the LEXICAL core and stays pure — it returns the matched
|
|
22
|
+
// rule's raw inject, nothing more. The per-behavior enrichment the plugin applies on top —
|
|
23
|
+
// capture-on-idea's {{CONFIRM_MODE}} substitution, the capture-kind and thread-split-mode
|
|
24
|
+
// hints, research-before-decision's appended source hint, the env/config kill switches, the
|
|
25
|
+
// injected-content guard and the CONFIRMED MATCH marker — used to live only in
|
|
26
|
+
// scripts/claude-hooks/_intent-classifier-router.mjs, so a SpexCode seat saw a different
|
|
27
|
+
// (and, with the literal `{{CONFIRM_MODE}}` token, visibly unfinished) directive from the
|
|
28
|
+
// one Claude Code injects for the same prompt. HS-N01T moved that assembly into
|
|
29
|
+
// ./intent-directive.mjs, which BOTH the router and this gate's `run()` call — so the inject
|
|
30
|
+
// this gate returns is now byte-identical to the plugin's. The semantic (Layer 2 self-check /
|
|
31
|
+
// opt-in model-classify) layer stays in the router, unported.
|
|
32
|
+
//
|
|
33
|
+
// Pure: no I/O of its own beyond loadRuleTable's fs.readFileSync (itself fail-safe — see
|
|
34
|
+
// rule-table.mjs's header). No process.stdin/stdout/exit.
|
|
35
|
+
|
|
36
|
+
import { loadRuleTable } from './rule-table.mjs';
|
|
37
|
+
import { buildIntentDirective, ruleMatchesPrompt } from './intent-directive.mjs';
|
|
38
|
+
|
|
39
|
+
/** This gate's id, for a registry or an audit row. */
|
|
40
|
+
export const GATE_ID = 'intent-classifier';
|
|
41
|
+
/** Runs on the prompt-submit event, mirroring the retired hook's UserPromptSubmit wiring. */
|
|
42
|
+
export const EVENT = 'prompt_submit';
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The rule table carries every `userpromptsubmit` rule, including
|
|
46
|
+
* `communication-style-prime` (HS-XIYJ's rule — an unconditional `[\s\S]` pattern that would
|
|
47
|
+
* "match" every prompt) and severity `prime` rules with no patterns at all. Intent
|
|
48
|
+
* classification is specifically the five mutually-exclusive INTENT rules the original
|
|
49
|
+
* router's `CLASSIFIER_BEHAVIORS` catalog named — restricting to these ids is what keeps
|
|
50
|
+
* this module from reinventing the always-on communication-style injection XIYJ retires
|
|
51
|
+
* separately.
|
|
52
|
+
* @type {ReadonlyArray<string>}
|
|
53
|
+
*/
|
|
54
|
+
export const CLASSIFIER_RULE_IDS = Object.freeze([
|
|
55
|
+
'capture-on-idea',
|
|
56
|
+
'research-before-decision',
|
|
57
|
+
'settings-intent',
|
|
58
|
+
'defer-intent',
|
|
59
|
+
'handoff-intent',
|
|
60
|
+
'spec-reference-lookup',
|
|
61
|
+
]);
|
|
62
|
+
|
|
63
|
+
/** Compile a rule's string patterns into case-insensitive RegExps, skipping any that fail
|
|
64
|
+
* to compile (a corrupt pattern degrades to "never matches", never a throw). */
|
|
65
|
+
function compilePatterns(rule) {
|
|
66
|
+
const patterns = Array.isArray(rule?.patterns) ? rule.patterns : [];
|
|
67
|
+
const compiled = [];
|
|
68
|
+
for (const source of patterns) {
|
|
69
|
+
try {
|
|
70
|
+
compiled.push(new RegExp(source, 'i'));
|
|
71
|
+
} catch {
|
|
72
|
+
// corrupt pattern in the table — skip it, fail-safe.
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return compiled;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** The classifier rules eligible to fire, in {@link CLASSIFIER_RULE_IDS} order (the
|
|
79
|
+
* deterministic lexical tiebreak, mirroring the original router's BEHAVIOR_ORDER). */
|
|
80
|
+
function classifierRules(table) {
|
|
81
|
+
const byId = new Map((table?.rules ?? []).map((r) => [r?.rule, r]));
|
|
82
|
+
const rules = [];
|
|
83
|
+
for (const id of CLASSIFIER_RULE_IDS) {
|
|
84
|
+
const rule = byId.get(id);
|
|
85
|
+
if (rule && typeof rule.inject === 'string' && rule.inject.trim() && rule.surfaces?.includes('userpromptsubmit')) {
|
|
86
|
+
rules.push(rule);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return rules;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @typedef {object} IntentClassification
|
|
94
|
+
* @property {string} rule the matched rule's id (e.g. 'capture-on-idea').
|
|
95
|
+
* @property {string} sourceProtocol the protocol that authored the rule.
|
|
96
|
+
* @property {string} inject the rule's raw inject text (unmodified — see the
|
|
97
|
+
* SCOPE NOTE above; per-behavior enrichment/substitution is not applied here).
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Classify a prompt against the engine's compiled rule table. First matching rule (in
|
|
102
|
+
* {@link CLASSIFIER_RULE_IDS} order) wins; a full miss returns null — no directive is
|
|
103
|
+
* resolved, matching AC2/AC3.
|
|
104
|
+
*
|
|
105
|
+
* @param {string} prompt
|
|
106
|
+
* @param {{ vaultRoot?: string, ruleTable?: { rules: object[] } }} [opts]
|
|
107
|
+
* `ruleTable` is injectable so a test never depends on the live
|
|
108
|
+
* `.heyspex/guardrails.json`/built-in table; omitted, it loads the real one via
|
|
109
|
+
* {@link loadRuleTable}.
|
|
110
|
+
* @returns {IntentClassification|null}
|
|
111
|
+
*/
|
|
112
|
+
export function classifyPrompt(prompt, { vaultRoot, ruleTable } = {}) {
|
|
113
|
+
if (typeof prompt !== 'string' || !prompt.trim()) return null;
|
|
114
|
+
const table = ruleTable ?? loadRuleTable({ vaultRoot });
|
|
115
|
+
for (const rule of classifierRules(table)) {
|
|
116
|
+
const patterns = compilePatterns(rule);
|
|
117
|
+
// HS-XDH8: a negation-guarded rule (defer-intent) needs an un-negated occurrence.
|
|
118
|
+
if (ruleMatchesPrompt(rule, patterns, prompt)) {
|
|
119
|
+
return { rule: rule.rule, sourceProtocol: rule.sourceProtocol ?? null, inject: rule.inject };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* The engine gate: runs on `prompt_submit`, classifies the prompt, and only when a rule
|
|
127
|
+
* actually fires does it return an `inject` decision carrying that rule's directive. A miss
|
|
128
|
+
* — including the common "plain prompt, matches nothing" case — is a plain `allow` with no
|
|
129
|
+
* injected text, satisfying AC3's <500-byte-on-a-plain-prompt target by construction (an
|
|
130
|
+
* `allow` decision carries no `inject` field at all).
|
|
131
|
+
*
|
|
132
|
+
* HS-N01T: a hit is then run through ./intent-directive.mjs's `buildIntentDirective` — the
|
|
133
|
+
* SAME eligibility check (env kill switch, config toggle, injected-content guard) and the
|
|
134
|
+
* SAME directive assembly (confirm-mode substitution, kind/routing hints, CONFIRMED MATCH
|
|
135
|
+
* marker) the Claude Code hook applies — so `inject.additionalContext` is what the plugin
|
|
136
|
+
* would have injected, never the raw inject with a literal `{{CONFIRM_MODE}}`. An
|
|
137
|
+
* ineligible behavior is an `allow`. A rule the behavior catalog does not know (or a row
|
|
138
|
+
* the plugin router would never fire) keeps the pre-N01T raw passthrough.
|
|
139
|
+
*
|
|
140
|
+
* `ctx` (all optional): `vaultRoot`/`repoRoot` — the app root holding `.heyspex/`;
|
|
141
|
+
* `ruleTable` — an injected table (tests); `env` — env overrides instead of `process.env`;
|
|
142
|
+
* `getSetting(repoRoot, key)` — an injected settings reader so a test never reads the real
|
|
143
|
+
* config (see ./intent-directive.mjs's header for the accepted shapes).
|
|
144
|
+
*
|
|
145
|
+
* @param {{ point: string, prompt?: string }} evt
|
|
146
|
+
* @param {{ vaultRoot?: string, repoRoot?: string, ruleTable?: object, env?: object, getSetting?: Function }} [ctx]
|
|
147
|
+
* @returns {{ decision: 'allow' }|{ decision: 'inject', reason: string, inject: { additionalContext: string, rule: string, behavior: string|null } }}
|
|
148
|
+
*/
|
|
149
|
+
export function run(evt, ctx = {}) {
|
|
150
|
+
const repoRoot = ctx.repoRoot ?? ctx.vaultRoot;
|
|
151
|
+
// One table load for both the lexical match and the directive resolution.
|
|
152
|
+
const ruleTable = ctx.ruleTable ?? loadRuleTable({ vaultRoot: repoRoot });
|
|
153
|
+
const hit = classifyPrompt(evt?.prompt, { ruleTable });
|
|
154
|
+
if (!hit) return { decision: 'allow' };
|
|
155
|
+
let built;
|
|
156
|
+
try {
|
|
157
|
+
built = buildIntentDirective(hit.rule, evt.prompt, {
|
|
158
|
+
repoRoot,
|
|
159
|
+
ruleTable,
|
|
160
|
+
env: ctx.env,
|
|
161
|
+
getSetting: ctx.getSetting,
|
|
162
|
+
});
|
|
163
|
+
} catch {
|
|
164
|
+
// The directive assembly is best-effort enrichment; a crash in it must never turn a
|
|
165
|
+
// confirmed lexical fire into silence. Degrade to the raw inject.
|
|
166
|
+
built = { behavior: null, additionalContext: null };
|
|
167
|
+
}
|
|
168
|
+
if (built === null) return { decision: 'allow' }; // killed by env/config/injected-content guard
|
|
169
|
+
return {
|
|
170
|
+
decision: 'inject',
|
|
171
|
+
reason: `intent-classifier: ${hit.rule} fired`,
|
|
172
|
+
inject: {
|
|
173
|
+
additionalContext: built.additionalContext ?? hit.inject,
|
|
174
|
+
rule: hit.rule,
|
|
175
|
+
behavior: built.behavior,
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Caller-defined severity label. `prime` is the severity every rule in
|
|
182
|
+
* {@link CLASSIFIER_RULE_IDS} carries in the compiled registry — this gate never
|
|
183
|
+
* denies, it only primes a turn with the matched rule's directive.
|
|
184
|
+
*
|
|
185
|
+
* Added in wave 6 of [[HS-AZ61-NYPR]]: the module was written as a gate but was
|
|
186
|
+
* registered by nothing, so the classification it owns ran on no front at all.
|
|
187
|
+
* spexharness/src/gates/index.mjs now registers it (a registry row needs a
|
|
188
|
+
* severity for `hs harness gates` to print, hence this export), and
|
|
189
|
+
* spexharness/src/plugin-hook-coverage.test.mjs pins that registration so the
|
|
190
|
+
* Claude Code `intent-classifier-trigger` hook's coverage cannot silently lapse
|
|
191
|
+
* again.
|
|
192
|
+
*/
|
|
193
|
+
export const SEVERITY = 'prime';
|
|
194
|
+
|
|
195
|
+
const gate = { id: GATE_ID, event: EVENT, severity: SEVERITY, run };
|
|
196
|
+
export default gate;
|