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,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Thin shell over the spexharness engine port of this gate (wave 6 of
|
|
3
|
+
// [[HS-AZ61-NYPR]]). Same shape as the twelve shells
|
|
4
|
+
// scripts/generate-hook-shells.mjs writes; this one is authored rather than
|
|
5
|
+
// generated only because it is not part of that generator's frozen twelve.
|
|
6
|
+
// To change what this gate DECIDES, edit
|
|
7
|
+
// spexharness/src/gates/dev-server-task-reminder.mjs. The classification, the
|
|
8
|
+
// worktree bypass, the front read and the fleet-queue claim wrapper live in
|
|
9
|
+
// spexharness/src/dev-server-control.mjs — one copy in the tree, shared by the
|
|
10
|
+
// gate, this shell, and ./dev-server-task-reminder.smoke.mjs.
|
|
11
|
+
|
|
12
|
+
import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
|
|
13
|
+
import gate from '../../spexharness/src/gates/dev-server-task-reminder.mjs';
|
|
14
|
+
|
|
15
|
+
await runGateAsHook(gate);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// GENERATED by scripts/generate-hook-shells.mjs (HS-IQBF) — do not hand-edit.
|
|
3
|
+
// This file only wires Claude Code's hook stdin/stdout contract to the
|
|
4
|
+
// spexharness engine port of this gate. To change what this gate DECIDES,
|
|
5
|
+
// edit spexharness/src/gates/diagnose-capture-reminder.mjs. To change the SHAPE of this shell,
|
|
6
|
+
// edit the generator, then rerun: node scripts/generate-hook-shells.mjs
|
|
7
|
+
|
|
8
|
+
import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
|
|
9
|
+
import gate from '../../spexharness/src/gates/diagnose-capture-reminder.mjs';
|
|
10
|
+
|
|
11
|
+
await runGateAsHook(gate);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// GENERATED by scripts/generate-hook-shells.mjs (HS-IQBF) — do not hand-edit.
|
|
3
|
+
// This file only wires Claude Code's hook stdin/stdout contract to the
|
|
4
|
+
// spexharness engine port of this gate. To change what this gate DECIDES,
|
|
5
|
+
// edit spexharness/src/gates/directive-obligation-gate.mjs. To change the SHAPE of this shell,
|
|
6
|
+
// edit the generator, then rerun: node scripts/generate-hook-shells.mjs
|
|
7
|
+
|
|
8
|
+
import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
|
|
9
|
+
import { hookGate as gate } from '../../spexharness/src/gates/directive-obligation-gate.mjs';
|
|
10
|
+
|
|
11
|
+
await runGateAsHook(gate);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Claude Code + Cursor CLI hook → console claim-status / heartbeat emitter.
|
|
3
|
+
// ([[HS-TASK-P89W]] / [[HS-EPIC-2BKX]] / [[HS-TASK-A3FE]] producer path)
|
|
4
|
+
//
|
|
5
|
+
// Resolves the agent session id from stdin payload + host env, then PATCHes
|
|
6
|
+
// `/api/control/active-claims/heartbeat` (tier-dispatched — works on Neon and
|
|
7
|
+
// free-file tiers). Does NOT read `.heyspex/active-claims.json`.
|
|
8
|
+
//
|
|
9
|
+
// MUST exit 0 on every failure path — a hook that breaks the agent is worse
|
|
10
|
+
// than a hook that silently does nothing.
|
|
11
|
+
//
|
|
12
|
+
// CLI: emit-claim-status.mjs [--event=PreToolUse|preToolUse|Stop|stop|PostToolUse|postToolUse]
|
|
13
|
+
// --event is optional; falls back to stdin.hook_event_name.
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
emitClaimLivenessFromHook,
|
|
17
|
+
parseArgs,
|
|
18
|
+
readStdin,
|
|
19
|
+
} from './claim-liveness-shared.mjs';
|
|
20
|
+
|
|
21
|
+
async function main() {
|
|
22
|
+
const args = parseArgs(process.argv);
|
|
23
|
+
const stdinRaw = await readStdin();
|
|
24
|
+
let payload = null;
|
|
25
|
+
if (stdinRaw) {
|
|
26
|
+
try {
|
|
27
|
+
payload = JSON.parse(stdinRaw);
|
|
28
|
+
} catch {
|
|
29
|
+
// Non-JSON stdin — proceed with null payload; event must come from --event.
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
await emitClaimLivenessFromHook({
|
|
34
|
+
eventArg: args.event,
|
|
35
|
+
payload,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
main().catch(() => {
|
|
40
|
+
// Swallow — never break the host agent on a hook failure.
|
|
41
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// GENERATED by scripts/generate-hook-shells.mjs (HS-IQBF) — do not hand-edit.
|
|
3
|
+
// This file only wires Claude Code's hook stdin/stdout contract to the
|
|
4
|
+
// spexharness engine port of this gate. To change what this gate DECIDES,
|
|
5
|
+
// edit spexharness/src/gates/enforce-session-sequence.mjs. To change the SHAPE of this shell,
|
|
6
|
+
// edit the generator, then rerun: node scripts/generate-hook-shells.mjs
|
|
7
|
+
|
|
8
|
+
import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
|
|
9
|
+
import gate from '../../spexharness/src/gates/enforce-session-sequence.mjs';
|
|
10
|
+
|
|
11
|
+
await runGateAsHook(gate);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// GENERATED by scripts/generate-hook-shells.mjs (HS-IQBF) — do not hand-edit.
|
|
3
|
+
// This file only wires Claude Code's hook stdin/stdout contract to the
|
|
4
|
+
// spexharness engine port of this gate. To change what this gate DECIDES,
|
|
5
|
+
// edit spexharness/src/gates/enforce-vault-naming.mjs. To change the SHAPE of this shell,
|
|
6
|
+
// edit the generator, then rerun: node scripts/generate-hook-shells.mjs
|
|
7
|
+
|
|
8
|
+
import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
|
|
9
|
+
import gate from '../../spexharness/src/gates/enforce-vault-naming.mjs';
|
|
10
|
+
|
|
11
|
+
await runGateAsHook(gate);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// GENERATED by scripts/generate-hook-shells.mjs (HS-IQBF) — do not hand-edit.
|
|
3
|
+
// This file only wires Claude Code's hook stdin/stdout contract to the
|
|
4
|
+
// spexharness engine port of this gate. To change what this gate DECIDES,
|
|
5
|
+
// edit spexharness/src/gates/env-vault-guard.mjs. To change the SHAPE of this shell,
|
|
6
|
+
// edit the generator, then rerun: node scripts/generate-hook-shells.mjs
|
|
7
|
+
|
|
8
|
+
import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
|
|
9
|
+
import gate from '../../spexharness/src/gates/env-vault-guard.mjs';
|
|
10
|
+
|
|
11
|
+
await runGateAsHook(gate);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// GENERATED by scripts/generate-hook-shells.mjs (HS-IQBF) — do not hand-edit.
|
|
3
|
+
// This file only wires Claude Code's hook stdin/stdout contract to the
|
|
4
|
+
// spexharness engine port of this gate. To change what this gate DECIDES,
|
|
5
|
+
// edit spexharness/src/gates/epic-milestone-phrasing-gate.mjs. To change the SHAPE of this shell,
|
|
6
|
+
// edit the generator, then rerun: node scripts/generate-hook-shells.mjs
|
|
7
|
+
|
|
8
|
+
import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
|
|
9
|
+
import gate from '../../spexharness/src/gates/epic-milestone-phrasing-gate.mjs';
|
|
10
|
+
|
|
11
|
+
await runGateAsHook(gate);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// GENERATED by scripts/generate-hook-shells.mjs (HS-IQBF) — do not hand-edit.
|
|
3
|
+
// This file only wires Claude Code's hook stdin/stdout contract to the
|
|
4
|
+
// spexharness engine port of this gate. To change what this gate DECIDES,
|
|
5
|
+
// edit spexharness/src/gates/git-identity-guard.mjs. To change the SHAPE of this shell,
|
|
6
|
+
// edit the generator, then rerun: node scripts/generate-hook-shells.mjs
|
|
7
|
+
|
|
8
|
+
import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
|
|
9
|
+
import gate from '../../spexharness/src/gates/git-identity-guard.mjs';
|
|
10
|
+
|
|
11
|
+
await runGateAsHook(gate);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Thin shell over the spexharness engine port of this gate (wave 6 of
|
|
3
|
+
// [[HS-AZ61-NYPR]]). `.claude/settings.json` wires this ONE script to BOTH
|
|
4
|
+
// SessionStart and Stop, so it uses `runGatesAsHook` — read stdin once, run
|
|
5
|
+
// whichever of the pair is registered for the incoming event.
|
|
6
|
+
//
|
|
7
|
+
// To change what this gate DECIDES, edit
|
|
8
|
+
// spexharness/src/gates/git-reflog-audit.mjs. The reflog/stash audit logic
|
|
9
|
+
// itself lives in spexharness/src/git-reflog-audit.mjs — one copy in the tree,
|
|
10
|
+
// shared by the gate, this shell, and ./git-reflog-audit.test.mjs.
|
|
11
|
+
|
|
12
|
+
import { runGatesAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
|
|
13
|
+
import gate, { snapshotGate } from '../../spexharness/src/gates/git-reflog-audit.mjs';
|
|
14
|
+
|
|
15
|
+
await runGatesAsHook([snapshotGate, gate]);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// GENERATED by scripts/generate-hook-shells.mjs (HS-IQBF) — do not hand-edit.
|
|
3
|
+
// This file only wires Claude Code's hook stdin/stdout contract to the
|
|
4
|
+
// spexharness engine port of this gate. To change what this gate DECIDES,
|
|
5
|
+
// edit spexharness/src/gates/git-stash-gate.mjs. To change the SHAPE of this shell,
|
|
6
|
+
// edit the generator, then rerun: node scripts/generate-hook-shells.mjs
|
|
7
|
+
|
|
8
|
+
import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
|
|
9
|
+
import gate from '../../spexharness/src/gates/git-stash-gate.mjs';
|
|
10
|
+
|
|
11
|
+
await runGateAsHook(gate);
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Claude Code PreToolUse hook → keeps the Claude Code auto-memory directory thin by
|
|
3
|
+
// blocking NEW topic-file creation there, redirecting durable HeySpex knowledge to
|
|
4
|
+
// the vault.
|
|
5
|
+
//
|
|
6
|
+
// Per the retention policy ([[auto-memory-index-hygiene]] / [[HS-VN9W-RES]]) the
|
|
7
|
+
// auto-memory index (~/.claude/projects/<repo>/memory/) is a curated working-set +
|
|
8
|
+
// ROUTER over the vault — NOT a store. Durable HeySpex facts belong in the vault
|
|
9
|
+
// (specs/memory/, via heyspex_file_spec), which is served dynamically by
|
|
10
|
+
// heyspex_recall_memories. Writing new `<slug>.md` topic files into the auto-memory
|
|
11
|
+
// dir is what re-bloats the always-loaded index over time (each new topic file earns
|
|
12
|
+
// an index line). This hook is the prevention half; the self-heal pass in
|
|
13
|
+
// check-auto-memory-budget.mjs is the cure half.
|
|
14
|
+
//
|
|
15
|
+
// What is blocked: creating a NEW `.md` topic file (anything other than MEMORY.md)
|
|
16
|
+
// under `…/.claude/projects/<repo>/memory/`.
|
|
17
|
+
// What is allowed: writing MEMORY.md itself (the router line + sanctioned pinned
|
|
18
|
+
// working set), and Edit on any existing file (migrations, pinned-set tweaks).
|
|
19
|
+
//
|
|
20
|
+
// Env:
|
|
21
|
+
// HEYSPEX_AUTO_MEMORY_WRITE_GUARD_OFF=1 kill switch — never blocks.
|
|
22
|
+
//
|
|
23
|
+
// Stdin: Claude Code hook JSON ({tool_name, tool_input, ...}).
|
|
24
|
+
// Exit 0 = allow. Exit 2 = block (stderr surfaces back to the model).
|
|
25
|
+
// FAIL-SAFE: any internal error → exit 0 (never strand the agent).
|
|
26
|
+
|
|
27
|
+
import path from 'node:path';
|
|
28
|
+
|
|
29
|
+
// Matches a path inside a Claude Code auto-memory dir: `…/.claude/projects/<repo>/memory/`.
|
|
30
|
+
// Tolerant of either path separator (Windows or POSIX) in the raw tool input.
|
|
31
|
+
const AUTO_MEMORY_DIR_RE = /[\\/]\.claude[\\/]projects[\\/][^\\/]+[\\/]memory[\\/]/i;
|
|
32
|
+
|
|
33
|
+
function isGuardedTopicFile(p) {
|
|
34
|
+
if (!p || typeof p !== 'string') return false;
|
|
35
|
+
if (!AUTO_MEMORY_DIR_RE.test(p)) return false;
|
|
36
|
+
const base = path.basename(p);
|
|
37
|
+
if (!/\.md$/i.test(base)) return false; // only markdown topic files
|
|
38
|
+
if (base.toUpperCase() === 'MEMORY.MD') return false; // the index itself is allowed
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Heuristic shell scanner — pulls file-creation targets out of common Bash /
|
|
43
|
+
// PowerShell idioms so a topic file written via `echo > slug.md` or `New-Item`
|
|
44
|
+
// can't sneak past the Write|NotebookEdit guard. Mirrors the conservative scanner
|
|
45
|
+
// in enforce-vault-naming.mjs. Conservative by design: a missed target only means
|
|
46
|
+
// the guard stays silent (fail-open), never a false block of legitimate work.
|
|
47
|
+
function extractShellTargets(command) {
|
|
48
|
+
if (!command || typeof command !== 'string') return [];
|
|
49
|
+
const targets = new Set();
|
|
50
|
+
|
|
51
|
+
// 1. Redirects: `> path` / `>> path` / `| tee path` / `| tee -a path`.
|
|
52
|
+
const redirectRe = /(?:>>?|\|\s*tee(?:\s+-a)?)\s+("([^"]+)"|'([^']+)'|(\S+))/g;
|
|
53
|
+
for (const m of command.matchAll(redirectRe)) targets.add(m[2] ?? m[3] ?? m[4]);
|
|
54
|
+
|
|
55
|
+
// 2. mv / cp / touch / install / Set-Content / New-Item etc. — destination args.
|
|
56
|
+
const cmdRe =
|
|
57
|
+
/\b(?:mv|cp|touch|install|rename|tee|Move-Item|Copy-Item|New-Item|Set-Content|Out-File|Add-Content)\s+([^|;&\n]+)/g;
|
|
58
|
+
for (const m of command.matchAll(cmdRe)) {
|
|
59
|
+
const head = m[0].split(/\s/)[0];
|
|
60
|
+
const args = m[1]
|
|
61
|
+
.trim()
|
|
62
|
+
.split(/\s+/)
|
|
63
|
+
.filter((a) => a && !a.startsWith('-'));
|
|
64
|
+
if (args.length === 0) continue;
|
|
65
|
+
if (/^(?:mv|cp|install|rename|Move-Item|Copy-Item)$/.test(head)) {
|
|
66
|
+
targets.add(args[args.length - 1]); // last arg is the destination
|
|
67
|
+
} else {
|
|
68
|
+
for (const a of args) targets.add(a); // touch / New-Item / *-Content: each is a target
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return [...targets]
|
|
73
|
+
.map((t) => t.replace(/^['"]|['"]$/g, ''))
|
|
74
|
+
.filter(Boolean)
|
|
75
|
+
.filter((t) => !/[$`(){}]/.test(t)); // skip command substitutions / non-paths
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function reason(p) {
|
|
79
|
+
return [
|
|
80
|
+
`HeySpex auto-memory guard: ${p}`,
|
|
81
|
+
` The Claude Code auto-memory directory is a thin curated index + router over the`,
|
|
82
|
+
` vault — not a knowledge store. Do NOT create new topic files here; durable HeySpex`,
|
|
83
|
+
` facts belong in the vault and load on demand via heyspex_recall_memories.`,
|
|
84
|
+
` → File this as a vault memory instead: heyspex_file_spec`,
|
|
85
|
+
` (memory-lesson / memory-decision / memory-reference / memory-ui-pattern).`,
|
|
86
|
+
` → A genuinely machine-local fact (this physical box's hardware, a per-machine path)`,
|
|
87
|
+
` goes to the vault as a memory-reference tagged 'machine-local'.`,
|
|
88
|
+
` Only MEMORY.md (the router line + sanctioned [pinned] working set) lives here.`,
|
|
89
|
+
` See specs/protocols/auto-memory-index-hygiene.md.`,
|
|
90
|
+
].join('\n');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async function readStdinJson() {
|
|
94
|
+
if (process.stdin.isTTY) return null;
|
|
95
|
+
let buf = '';
|
|
96
|
+
process.stdin.setEncoding('utf8');
|
|
97
|
+
for await (const chunk of process.stdin) buf += chunk;
|
|
98
|
+
if (!buf.trim()) return null;
|
|
99
|
+
try {
|
|
100
|
+
return JSON.parse(buf);
|
|
101
|
+
} catch {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function block(msg) {
|
|
107
|
+
process.stderr.write(`\n[HeySpex auto-memory guard]\n${msg}\n`);
|
|
108
|
+
process.exit(2);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async function main() {
|
|
112
|
+
if (process.env.HEYSPEX_AUTO_MEMORY_WRITE_GUARD_OFF === '1') return;
|
|
113
|
+
|
|
114
|
+
const payload = await readStdinJson();
|
|
115
|
+
if (!payload) return;
|
|
116
|
+
|
|
117
|
+
const toolName = payload.tool_name;
|
|
118
|
+
const input = payload.tool_input ?? {};
|
|
119
|
+
|
|
120
|
+
// Only guard file CREATION. Edit/MultiEdit on existing files is fine (migrations,
|
|
121
|
+
// pinned-set tweaks); the file already exists, so it is not new re-bloat.
|
|
122
|
+
let targets = [];
|
|
123
|
+
if (toolName === 'Write') targets = [input.file_path];
|
|
124
|
+
else if (toolName === 'NotebookEdit') targets = [input.notebook_path];
|
|
125
|
+
else if (toolName === 'Bash' || toolName === 'PowerShell')
|
|
126
|
+
targets = extractShellTargets(input.command); // close the shell-redirect bypass
|
|
127
|
+
else return; // unrelated tool
|
|
128
|
+
|
|
129
|
+
for (const target of targets) {
|
|
130
|
+
if (isGuardedTopicFile(target)) block(reason(target)); // block() exits on first hit
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
main().catch(() => {
|
|
135
|
+
// Fail-open: never block legitimate work on a hook crash.
|
|
136
|
+
process.exit(0);
|
|
137
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// GENERATED by scripts/generate-hook-shells.mjs (HS-IQBF) — do not hand-edit.
|
|
3
|
+
// This file only wires Claude Code's hook stdin/stdout contract to the
|
|
4
|
+
// spexharness engine port of this gate. To change what this gate DECIDES,
|
|
5
|
+
// edit spexharness/src/gates/id-display-format-gate.mjs. To change the SHAPE of this shell,
|
|
6
|
+
// edit the generator, then rerun: node scripts/generate-hook-shells.mjs
|
|
7
|
+
|
|
8
|
+
import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
|
|
9
|
+
import gate from '../../spexharness/src/gates/id-display-format-gate.mjs';
|
|
10
|
+
|
|
11
|
+
await runGateAsHook(gate);
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Claude Code hook → RETIRED UserPromptSubmit injection of the OWNER COMMUNICATION STYLE rules.
|
|
3
|
+
//
|
|
4
|
+
// RETIRED (HS-XIYJ, epic HS-1YDJ, 2026-09-09).
|
|
5
|
+
//
|
|
6
|
+
// WHY THIS EXISTED
|
|
7
|
+
// -----------------
|
|
8
|
+
// This hook used to inject the compiled `communication-style-prime` rule's full prose
|
|
9
|
+
// (specs/protocols/communication-style-protocol.md, ~3.0 KB) into EVERY UserPromptSubmit
|
|
10
|
+
// turn, unconditionally — added after the owner asked for plain English twice (2026-08-11,
|
|
11
|
+
// 2026-08-14; see git history for the full rationale) because a memory lesson and a
|
|
12
|
+
// preflight reminder both failed to reach an ordinary interactive turn.
|
|
13
|
+
//
|
|
14
|
+
// WHY IT IS RETIRED NOW
|
|
15
|
+
// ----------------------
|
|
16
|
+
// The epic measured this hook as ~3.0 KB of every single prompt's budget, on top of the
|
|
17
|
+
// intent classifier's own per-prompt cost (HS-5ISS) — together the largest mechanical, non-
|
|
18
|
+
// content share of a seat's context window. The voice epic's first profile is the intended
|
|
19
|
+
// replacement mechanism for carrying writing-style behavior across turns without re-teaching
|
|
20
|
+
// it every one; this task's job is narrower — make the injection actually stop, and prove it
|
|
21
|
+
// stopped via measurement (spexharness/src/context-budget.mjs, HS-7UAQ) rather than just
|
|
22
|
+
// trusting a diff.
|
|
23
|
+
//
|
|
24
|
+
// THIS FILE IS KEPT, NOT DELETED
|
|
25
|
+
// -------------------------------
|
|
26
|
+
// `.claude/settings.json` still names `inject-communication-style` as the UserPromptSubmit
|
|
27
|
+
// hook and scripts/claude-hooks/_run.mjs dispatches to it by that name on every prompt —
|
|
28
|
+
// deleting the file would turn a silent no-op into a "hook not found" stderr line on every
|
|
29
|
+
// turn instead. `main()` below now ALWAYS returns without emitting anything; the decision
|
|
30
|
+
// lives in {@link shouldInject}, a one-line function kept separate from `main()` so a test
|
|
31
|
+
// can assert the retirement directly instead of only inferring it from captured stdout, and
|
|
32
|
+
// so any future un-retirement is a one-line change here rather than a rewrite.
|
|
33
|
+
//
|
|
34
|
+
// HEYSPEX_COMMUNICATION_STYLE_OFF=1 Historical kill switch — still honored
|
|
35
|
+
// (checked first, same as before), though
|
|
36
|
+
// shouldInject() already returns false
|
|
37
|
+
// unconditionally regardless of its value.
|
|
38
|
+
// agent_behaviors.communication_style.enabled Historical config toggle — no longer read;
|
|
39
|
+
// the registry lookup this hook used to do
|
|
40
|
+
// is gone, so a stale/missing/corrupt
|
|
41
|
+
// .heyspex/guardrails.json can no longer
|
|
42
|
+
// affect this hook either way.
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Should this hook inject the communication-style prose? Retired: always false. Kept as a
|
|
46
|
+
* named export (rather than inlined into `main()`) so this is the ONE place the retirement
|
|
47
|
+
* decision lives, and a test asserts it directly.
|
|
48
|
+
* @returns {boolean}
|
|
49
|
+
*/
|
|
50
|
+
export function shouldInject() {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The static communication-style prose, for the ONE surface that can still carry it: GitHub Copilot's
|
|
56
|
+
* `sessionStart` additionalContext (Copilot drops UserPromptSubmit output, and per-prompt injection stays
|
|
57
|
+
* retired on Claude Code). Called ONLY by scripts/claude-hooks/_run.mjs's Copilot branch, once per session.
|
|
58
|
+
* Honors the historical kill switch and the `agent_behaviors.communication_style.enabled` config key; returns
|
|
59
|
+
* '' on any failure (never throws).
|
|
60
|
+
* @returns {Promise<string>}
|
|
61
|
+
*/
|
|
62
|
+
export async function copilotSessionStartText() {
|
|
63
|
+
try {
|
|
64
|
+
if (process.env.HEYSPEX_COMMUNICATION_STYLE_OFF === '1') return '';
|
|
65
|
+
const { loadGuardrails, rulesForSurface, isRuleEnabled } = await import('./_guardrail-loader.mjs');
|
|
66
|
+
const rule = rulesForSurface(loadGuardrails(), 'userpromptsubmit', 'prime').find((r) => r && r.rule === 'communication-style-prime');
|
|
67
|
+
if (!rule || !isRuleEnabled(rule)) return '';
|
|
68
|
+
return typeof rule.inject === 'string' ? rule.inject.trim() : '';
|
|
69
|
+
} catch {
|
|
70
|
+
return '';
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The hook body. Reads nothing and writes nothing — retirement means there is no longer
|
|
76
|
+
* anything for it to read the payload FOR. Exported so a test can call it directly and
|
|
77
|
+
* capture stdout around it.
|
|
78
|
+
* @returns {Promise<void>}
|
|
79
|
+
*/
|
|
80
|
+
export async function main() {
|
|
81
|
+
if (!shouldInject()) return; // retired — see module header.
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
main().catch(() => {
|
|
85
|
+
// Never break Claude Code on a hook failure.
|
|
86
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Claude Code hook → SessionStart injection of dev-factory seat mandates.
|
|
3
|
+
//
|
|
4
|
+
// Reads the seats registry at dev-factory/seats.json. When settings.cooMode is
|
|
5
|
+
// true, injects one line per ACTIVE seat so every new session opens already
|
|
6
|
+
// holding its seat (delegate-first COO orchestration) without being told:
|
|
7
|
+
//
|
|
8
|
+
// DEV-FACTORY SEAT: <title> — <mandate>
|
|
9
|
+
//
|
|
10
|
+
// Toggle lives in the console at Settings > ADMIN > Dev-Factory (persisted via
|
|
11
|
+
// PATCH /api/admin/factory/seats). Hard requirements honored here:
|
|
12
|
+
// - additive: registered as its OWN SessionStart hook entry; the existing
|
|
13
|
+
// dev-server awareness injection (inject-dev-server-awareness.mjs) is untouched.
|
|
14
|
+
// - non-fatal: missing/corrupt seats.json, cooMode false, or no active seats
|
|
15
|
+
// → inject nothing and exit 0 (the fail-silent hook contract).
|
|
16
|
+
// - fast: one local file read; no network calls.
|
|
17
|
+
// HEYSPEX_COO_SEAT_OFF=1 Kill switch — exits silently.
|
|
18
|
+
//
|
|
19
|
+
// Output shape (same as the sibling SessionStart hooks):
|
|
20
|
+
// { hookSpecificOutput: { hookEventName, additionalContext } }
|
|
21
|
+
|
|
22
|
+
// buildSeatContext + repoRoot moved to the shared lib so Command Code
|
|
23
|
+
// (sync into COMMANDCODE.md) and Cursor (sync into a .cursor rule) inject the
|
|
24
|
+
// byte-identical seat context — see dev-factory/lib/seat-context.mjs.
|
|
25
|
+
import { buildSeatContext } from '../../dev-factory/lib/seat-context.mjs';
|
|
26
|
+
|
|
27
|
+
async function readStdinJson() {
|
|
28
|
+
if (process.stdin.isTTY) return null;
|
|
29
|
+
return new Promise((resolve) => {
|
|
30
|
+
let buf = '';
|
|
31
|
+
let settled = false;
|
|
32
|
+
const finish = (value) => {
|
|
33
|
+
if (settled) return;
|
|
34
|
+
settled = true;
|
|
35
|
+
resolve(value);
|
|
36
|
+
};
|
|
37
|
+
const timer = setTimeout(() => finish(buf || ''), 200);
|
|
38
|
+
process.stdin.setEncoding('utf8');
|
|
39
|
+
process.stdin.on('data', (chunk) => {
|
|
40
|
+
buf += chunk;
|
|
41
|
+
});
|
|
42
|
+
process.stdin.on('end', () => {
|
|
43
|
+
clearTimeout(timer);
|
|
44
|
+
finish(buf);
|
|
45
|
+
});
|
|
46
|
+
process.stdin.on('error', () => {
|
|
47
|
+
clearTimeout(timer);
|
|
48
|
+
finish(buf);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function emit(eventName, additionalContext) {
|
|
54
|
+
process.stdout.write(
|
|
55
|
+
JSON.stringify({ hookSpecificOutput: { hookEventName: eventName, additionalContext } }),
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function main() {
|
|
60
|
+
if (process.env.HEYSPEX_COO_SEAT_OFF === '1') return;
|
|
61
|
+
const context = buildSeatContext();
|
|
62
|
+
if (!context) return; // cooMode off / no registry / no active seats
|
|
63
|
+
const raw = await readStdinJson();
|
|
64
|
+
let event = 'SessionStart';
|
|
65
|
+
if (raw) {
|
|
66
|
+
try {
|
|
67
|
+
const payload = JSON.parse(raw);
|
|
68
|
+
if (payload?.hook_event_name) event = payload.hook_event_name;
|
|
69
|
+
} catch {
|
|
70
|
+
// Non-JSON stdin — default to SessionStart and emit anyway.
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
emit(event, context);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
main().catch(() => {
|
|
77
|
+
// Never break Claude Code on a hook failure.
|
|
78
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// GENERATED by scripts/generate-hook-shells.mjs (HS-IQBF) — do not hand-edit.
|
|
3
|
+
// This file only wires Claude Code's hook stdin/stdout contract to the
|
|
4
|
+
// spexharness engine port of this gate. To change what this gate DECIDES,
|
|
5
|
+
// edit spexharness/src/gates/dev-server-awareness-gate.mjs. To change the SHAPE of this shell,
|
|
6
|
+
// edit the generator, then rerun: node scripts/generate-hook-shells.mjs
|
|
7
|
+
|
|
8
|
+
import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
|
|
9
|
+
import gate from '../../spexharness/src/gates/dev-server-awareness-gate.mjs';
|
|
10
|
+
|
|
11
|
+
await runGateAsHook(gate);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Thin shell over the spexharness engine gate (HS-X3S1, DR3). Same shape as
|
|
3
|
+
// inject-vault-context.mjs's own shell — this one is authored rather than
|
|
4
|
+
// generated (like that one) because it is not part of
|
|
5
|
+
// scripts/generate-hook-shells.mjs's frozen twelve. To change what this
|
|
6
|
+
// injection DECIDES, edit spexharness/src/gates/inject-doctrine-gate.mjs
|
|
7
|
+
// (the rendering itself lives in spexharness/src/doctrine/inject.mjs, shared
|
|
8
|
+
// with every SpexCode seat's own bootstrap — session-bootstrap.mjs).
|
|
9
|
+
|
|
10
|
+
import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
|
|
11
|
+
import gate from '../../spexharness/src/gates/inject-doctrine-gate.mjs';
|
|
12
|
+
|
|
13
|
+
await runGateAsHook(gate);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Thin shell over the spexharness engine port of this gate (wave 6 of
|
|
3
|
+
// [[HS-AZ61-NYPR]]). Same shape as the twelve shells
|
|
4
|
+
// scripts/generate-hook-shells.mjs writes; this one is authored rather than
|
|
5
|
+
// generated only because it is not part of that generator's frozen twelve.
|
|
6
|
+
// To change what this gate DECIDES, edit
|
|
7
|
+
// spexharness/src/gates/inject-vault-context.mjs (the scoring stays in
|
|
8
|
+
// ./_vault-retrieval.mjs; the byte accounting in
|
|
9
|
+
// spexharness/src/context-budget.mjs).
|
|
10
|
+
|
|
11
|
+
import { runGateAsHook } from '../../spexharness/src/adapters/claude-code.mjs';
|
|
12
|
+
import gate from '../../spexharness/src/gates/inject-vault-context.mjs';
|
|
13
|
+
|
|
14
|
+
await runGateAsHook(gate);
|