spexcode 0.6.1 → 0.6.5
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/README.md +99 -149
- package/bin/spex.mjs +4 -0
- package/node_modules/@spexcode/spec-cli/bin/spex.mjs +76 -0
- package/node_modules/@spexcode/spec-cli/dist/attach.d.ts +2 -0
- package/node_modules/@spexcode/spec-cli/dist/attach.js +48 -0
- package/node_modules/@spexcode/spec-cli/dist/claude-headless.d.ts +33 -0
- package/node_modules/@spexcode/spec-cli/dist/claude-headless.js +307 -0
- package/node_modules/@spexcode/spec-cli/dist/cli.d.ts +1 -0
- package/node_modules/@spexcode/spec-cli/dist/cli.js +1859 -0
- package/node_modules/@spexcode/spec-cli/dist/client.d.ts +111 -0
- package/node_modules/@spexcode/spec-cli/dist/client.js +476 -0
- package/node_modules/@spexcode/spec-cli/dist/cockpit.d.ts +7 -0
- package/node_modules/@spexcode/spec-cli/dist/cockpit.js +26 -0
- package/node_modules/@spexcode/spec-cli/dist/codex-headless.d.ts +1 -0
- package/{spec-cli/src/codex-headless.ts → node_modules/@spexcode/spec-cli/dist/codex-headless.js} +3 -9
- package/node_modules/@spexcode/spec-cli/dist/codex-runtime-generations.d.ts +53 -0
- package/node_modules/@spexcode/spec-cli/dist/codex-runtime-generations.js +686 -0
- package/node_modules/@spexcode/spec-cli/dist/commit-surgery.d.ts +1 -0
- package/node_modules/@spexcode/spec-cli/dist/commit-surgery.js +90 -0
- package/node_modules/@spexcode/spec-cli/dist/contract-filter.d.ts +14 -0
- package/node_modules/@spexcode/spec-cli/dist/contract-filter.js +219 -0
- package/node_modules/@spexcode/spec-cli/dist/dashboard-assets.d.ts +6 -0
- package/node_modules/@spexcode/spec-cli/dist/dashboard-assets.js +50 -0
- package/node_modules/@spexcode/spec-cli/dist/delivery-queue.d.ts +23 -0
- package/node_modules/@spexcode/spec-cli/dist/delivery-queue.js +179 -0
- package/node_modules/@spexcode/spec-cli/dist/doctor.d.ts +9 -0
- package/node_modules/@spexcode/spec-cli/dist/doctor.js +547 -0
- package/node_modules/@spexcode/spec-cli/dist/eval-host.d.ts +1 -0
- package/node_modules/@spexcode/spec-cli/dist/eval-host.js +19 -0
- package/node_modules/@spexcode/spec-cli/dist/execution-trace.d.ts +26 -0
- package/node_modules/@spexcode/spec-cli/dist/execution-trace.js +475 -0
- package/node_modules/@spexcode/spec-cli/dist/file-write.d.ts +2 -0
- package/node_modules/@spexcode/spec-cli/dist/file-write.js +26 -0
- package/node_modules/@spexcode/spec-cli/dist/flat.d.ts +89 -0
- package/node_modules/@spexcode/spec-cli/dist/flat.js +1076 -0
- package/node_modules/@spexcode/spec-cli/dist/gateway-auth.d.ts +56 -0
- package/node_modules/@spexcode/spec-cli/dist/gateway-auth.js +168 -0
- package/node_modules/@spexcode/spec-cli/dist/gateway-hub.d.ts +28 -0
- package/node_modules/@spexcode/spec-cli/dist/gateway-hub.js +361 -0
- package/node_modules/@spexcode/spec-cli/dist/gateway.d.ts +37 -0
- package/node_modules/@spexcode/spec-cli/dist/gateway.js +503 -0
- package/node_modules/@spexcode/spec-cli/dist/graphCache.d.ts +27 -0
- package/node_modules/@spexcode/spec-cli/dist/graphCache.js +716 -0
- package/node_modules/@spexcode/spec-cli/dist/graphSnapshot.d.ts +14 -0
- package/node_modules/@spexcode/spec-cli/dist/graphSnapshot.js +35 -0
- package/node_modules/@spexcode/spec-cli/dist/graphStream.d.ts +85 -0
- package/node_modules/@spexcode/spec-cli/dist/graphStream.js +1195 -0
- package/node_modules/@spexcode/spec-cli/dist/guidance-catalog.d.ts +64 -0
- package/node_modules/@spexcode/spec-cli/dist/guidance-catalog.js +166 -0
- package/node_modules/@spexcode/spec-cli/dist/guide.d.ts +8 -0
- package/{spec-cli/src/guide.ts → node_modules/@spexcode/spec-cli/dist/guide.js} +115 -22
- package/node_modules/@spexcode/spec-cli/dist/harness-select.d.ts +18 -0
- package/node_modules/@spexcode/spec-cli/dist/harness-select.js +62 -0
- package/node_modules/@spexcode/spec-cli/dist/harness.d.ts +325 -0
- package/node_modules/@spexcode/spec-cli/dist/harness.js +3026 -0
- package/node_modules/@spexcode/spec-cli/dist/headless-controller.d.ts +9 -0
- package/node_modules/@spexcode/spec-cli/dist/headless-controller.js +47 -0
- package/node_modules/@spexcode/spec-cli/dist/help.d.ts +10 -0
- package/node_modules/@spexcode/spec-cli/dist/help.js +574 -0
- package/node_modules/@spexcode/spec-cli/dist/hook-prompts.d.ts +18 -0
- package/node_modules/@spexcode/spec-cli/dist/hook-prompts.js +122 -0
- package/node_modules/@spexcode/spec-cli/dist/hooks.d.ts +1 -0
- package/{spec-cli/src/hooks.ts → node_modules/@spexcode/spec-cli/dist/hooks.js} +15 -15
- package/node_modules/@spexcode/spec-cli/dist/host-resources.d.ts +97 -0
- package/node_modules/@spexcode/spec-cli/dist/host-resources.js +795 -0
- package/node_modules/@spexcode/spec-cli/dist/host.d.ts +88 -0
- package/node_modules/@spexcode/spec-cli/dist/host.js +663 -0
- package/node_modules/@spexcode/spec-cli/dist/index.d.ts +1 -0
- package/node_modules/@spexcode/spec-cli/dist/index.js +899 -0
- package/node_modules/@spexcode/spec-cli/dist/init.d.ts +1 -0
- package/node_modules/@spexcode/spec-cli/dist/init.js +284 -0
- package/node_modules/@spexcode/spec-cli/dist/issues-cli.d.ts +6 -0
- package/node_modules/@spexcode/spec-cli/dist/issues-cli.js +334 -0
- package/node_modules/@spexcode/spec-cli/dist/issues.d.ts +69 -0
- package/node_modules/@spexcode/spec-cli/dist/issues.js +189 -0
- package/node_modules/@spexcode/spec-cli/dist/lint.d.ts +34 -0
- package/node_modules/@spexcode/spec-cli/dist/lint.js +476 -0
- package/node_modules/@spexcode/spec-cli/dist/listen.d.ts +7 -0
- package/{spec-cli/src/listen.ts → node_modules/@spexcode/spec-cli/dist/listen.js} +13 -17
- package/node_modules/@spexcode/spec-cli/dist/localIssues.d.ts +65 -0
- package/node_modules/@spexcode/spec-cli/dist/localIssues.js +582 -0
- package/node_modules/@spexcode/spec-cli/dist/login-page.d.ts +5 -0
- package/{spec-cli/src/login-page.ts → node_modules/@spexcode/spec-cli/dist/login-page.js} +7 -7
- package/node_modules/@spexcode/spec-cli/dist/loop-in.d.ts +23 -0
- package/{spec-cli/src/loop-in.ts → node_modules/@spexcode/spec-cli/dist/loop-in.js} +35 -45
- package/node_modules/@spexcode/spec-cli/dist/machine-peer.d.ts +69 -0
- package/node_modules/@spexcode/spec-cli/dist/machine-peer.js +603 -0
- package/node_modules/@spexcode/spec-cli/dist/materialize.d.ts +18 -0
- package/node_modules/@spexcode/spec-cli/dist/materialize.js +468 -0
- package/node_modules/@spexcode/spec-cli/dist/mentions.d.ts +50 -0
- package/node_modules/@spexcode/spec-cli/dist/mentions.js +117 -0
- package/node_modules/@spexcode/spec-cli/dist/opencode-headless.d.ts +4 -0
- package/node_modules/@spexcode/spec-cli/dist/opencode-headless.js +208 -0
- package/node_modules/@spexcode/spec-cli/dist/opencode.d.ts +3 -0
- package/{spec-cli/src/opencode.ts → node_modules/@spexcode/spec-cli/dist/opencode.js} +9 -13
- package/node_modules/@spexcode/spec-cli/dist/pi-harness.d.ts +3 -0
- package/{spec-cli/src/pi-harness.ts → node_modules/@spexcode/spec-cli/dist/pi-harness.js} +45 -40
- package/node_modules/@spexcode/spec-cli/dist/pi-headless.d.ts +25 -0
- package/node_modules/@spexcode/spec-cli/dist/pi-headless.js +196 -0
- package/node_modules/@spexcode/spec-cli/dist/plugin-harness.d.ts +21 -0
- package/node_modules/@spexcode/spec-cli/dist/plugin-harness.js +146 -0
- package/node_modules/@spexcode/spec-cli/dist/pty-bridge.d.ts +10 -0
- package/node_modules/@spexcode/spec-cli/dist/pty-bridge.js +404 -0
- package/node_modules/@spexcode/spec-cli/dist/pty-helper.d.mts +1 -0
- package/node_modules/@spexcode/spec-cli/dist/pty-helper.mjs +101 -0
- package/node_modules/@spexcode/spec-cli/dist/pty-native-helper.d.mts +2 -0
- package/node_modules/@spexcode/spec-cli/dist/pty-native-helper.mjs +23 -0
- package/node_modules/@spexcode/spec-cli/dist/public-graph.d.ts +46 -0
- package/node_modules/@spexcode/spec-cli/dist/public-graph.js +56 -0
- package/node_modules/@spexcode/spec-cli/dist/ranker.d.ts +15 -0
- package/node_modules/@spexcode/spec-cli/dist/ranker.js +188 -0
- package/node_modules/@spexcode/spec-cli/dist/reaper.d.ts +6 -0
- package/node_modules/@spexcode/spec-cli/dist/reaper.js +81 -0
- package/node_modules/@spexcode/spec-cli/dist/reviews.d.ts +189 -0
- package/node_modules/@spexcode/spec-cli/dist/reviews.js +350 -0
- package/node_modules/@spexcode/spec-cli/dist/runtime-guard.d.ts +6 -0
- package/node_modules/@spexcode/spec-cli/dist/runtime-guard.js +37 -0
- package/node_modules/@spexcode/spec-cli/dist/runtime-ownership.d.ts +21 -0
- package/node_modules/@spexcode/spec-cli/dist/runtime-ownership.js +84 -0
- package/node_modules/@spexcode/spec-cli/dist/search.bench.d.mts +1 -0
- package/node_modules/@spexcode/spec-cli/dist/search.bench.mjs +75 -0
- package/node_modules/@spexcode/spec-cli/dist/search.d.ts +20 -0
- package/node_modules/@spexcode/spec-cli/dist/search.js +61 -0
- package/node_modules/@spexcode/spec-cli/dist/session-cursors.d.ts +14 -0
- package/node_modules/@spexcode/spec-cli/dist/session-cursors.js +82 -0
- package/node_modules/@spexcode/spec-cli/dist/session-declarations.d.ts +13 -0
- package/node_modules/@spexcode/spec-cli/dist/session-declarations.js +126 -0
- package/node_modules/@spexcode/spec-cli/dist/session-execution.d.ts +10 -0
- package/node_modules/@spexcode/spec-cli/dist/session-execution.js +70 -0
- package/node_modules/@spexcode/spec-cli/dist/session-files.d.ts +28 -0
- package/node_modules/@spexcode/spec-cli/dist/session-files.js +130 -0
- package/node_modules/@spexcode/spec-cli/dist/session-follow.d.ts +31 -0
- package/node_modules/@spexcode/spec-cli/dist/session-follow.js +179 -0
- package/node_modules/@spexcode/spec-cli/dist/session-reparent.d.ts +10 -0
- package/node_modules/@spexcode/spec-cli/dist/session-reparent.js +33 -0
- package/node_modules/@spexcode/spec-cli/dist/session-timeline.d.ts +51 -0
- package/node_modules/@spexcode/spec-cli/dist/session-timeline.js +233 -0
- package/node_modules/@spexcode/spec-cli/dist/session-web.d.ts +24 -0
- package/node_modules/@spexcode/spec-cli/dist/session-web.js +141 -0
- package/node_modules/@spexcode/spec-cli/dist/sessions.d.ts +412 -0
- package/node_modules/@spexcode/spec-cli/dist/sessions.js +4239 -0
- package/node_modules/@spexcode/spec-cli/dist/sh.d.ts +1 -0
- package/node_modules/@spexcode/spec-cli/dist/sh.js +3 -0
- package/node_modules/@spexcode/spec-cli/dist/shim-runtime.d.ts +1 -0
- package/{spec-cli/src/shim-runtime.ts → node_modules/@spexcode/spec-cli/dist/shim-runtime.js} +3 -4
- package/node_modules/@spexcode/spec-cli/dist/slash-commands.d.ts +9 -0
- package/node_modules/@spexcode/spec-cli/dist/slash-commands.js +307 -0
- package/node_modules/@spexcode/spec-cli/dist/source-files.d.ts +9 -0
- package/node_modules/@spexcode/spec-cli/dist/source-files.js +113 -0
- package/node_modules/@spexcode/spec-cli/dist/supervise.d.ts +1 -0
- package/node_modules/@spexcode/spec-cli/dist/supervise.js +308 -0
- package/node_modules/@spexcode/spec-cli/dist/tree.d.ts +25 -0
- package/node_modules/@spexcode/spec-cli/dist/tree.js +98 -0
- package/node_modules/@spexcode/spec-cli/dist/tsx-bin.d.ts +3 -0
- package/node_modules/@spexcode/spec-cli/dist/tsx-bin.js +41 -0
- package/node_modules/@spexcode/spec-cli/dist/uninstall.d.ts +3 -0
- package/node_modules/@spexcode/spec-cli/dist/uninstall.js +177 -0
- package/node_modules/@spexcode/spec-cli/dist/uploads.d.ts +36 -0
- package/node_modules/@spexcode/spec-cli/dist/uploads.js +243 -0
- package/node_modules/@spexcode/spec-cli/dist/worktree-sources.d.ts +1 -0
- package/node_modules/@spexcode/spec-cli/dist/worktree-sources.js +47 -0
- package/{spec-cli → node_modules/@spexcode/spec-cli}/hooks/dispatch.sh +5 -5
- package/{spec-cli → node_modules/@spexcode/spec-cli}/hooks/harness.sh +27 -7
- package/node_modules/@spexcode/spec-cli/package.json +47 -0
- package/node_modules/@spexcode/spec-cli/templates/spec/project/.plugins/commands/supervisor/spec.md +8 -0
- package/node_modules/@spexcode/spec-cli/templates/spec/project/.plugins/core/comment-altitude/spec.md +9 -0
- package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec-first/spec-first.sh +1 -1
- package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec-of-file/spec-of-file.sh +1 -0
- package/node_modules/@spexcode/spec-cli/templates/spec/project/.plugins/core/spec.md +22 -0
- package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/stop-gate/spec.md +2 -2
- package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/stop-gate/stop-gate.sh +31 -29
- package/node_modules/@spexcode/spec-cli/templates/spec/project/.plugins/prompts/atomic-landing/spec.md +15 -0
- package/node_modules/@spexcode/spec-cli/templates/spec/project/.plugins/prompts/forge-link/spec.md +10 -0
- package/node_modules/@spexcode/spec-cli/templates/spec/project/.plugins/prompts/memory-hygiene/spec.md +13 -0
- package/node_modules/@spexcode/spec-cli/templates/spec/project/.plugins/prompts/reproduce-before-fix/spec.md +12 -0
- package/node_modules/@spexcode/spec-core/dist/anchors.d.ts +94 -0
- package/node_modules/@spexcode/spec-core/dist/anchors.js +730 -0
- package/node_modules/@spexcode/spec-core/dist/git.d.ts +166 -0
- package/node_modules/@spexcode/spec-core/dist/git.js +2736 -0
- package/node_modules/@spexcode/spec-core/dist/graph-delta.d.ts +44 -0
- package/node_modules/@spexcode/spec-core/dist/graph-delta.js +72 -0
- package/node_modules/@spexcode/spec-core/dist/graph.d.ts +34 -0
- package/node_modules/@spexcode/spec-core/dist/graph.js +237 -0
- package/node_modules/@spexcode/spec-core/dist/graphDelta.d.ts +3 -0
- package/node_modules/@spexcode/spec-core/dist/graphDelta.js +13 -0
- package/node_modules/@spexcode/spec-core/dist/harness-identity.d.ts +31 -0
- package/node_modules/@spexcode/spec-core/dist/harness-identity.js +20 -0
- package/node_modules/@spexcode/spec-core/dist/identity-presets.d.ts +152 -0
- package/node_modules/@spexcode/spec-core/dist/identity-presets.js +132 -0
- package/node_modules/@spexcode/spec-core/dist/index.d.ts +45 -0
- package/node_modules/@spexcode/spec-core/dist/index.js +19 -0
- package/node_modules/@spexcode/spec-core/dist/layout.d.ts +183 -0
- package/node_modules/@spexcode/spec-core/dist/layout.js +548 -0
- package/node_modules/@spexcode/spec-core/dist/process-identity.d.ts +37 -0
- package/node_modules/@spexcode/spec-core/dist/process-identity.js +214 -0
- package/node_modules/@spexcode/spec-core/dist/project-identity.d.ts +12 -0
- package/node_modules/@spexcode/spec-core/dist/project-identity.js +71 -0
- package/node_modules/@spexcode/spec-core/dist/project-store.d.ts +3 -0
- package/node_modules/@spexcode/spec-core/dist/project-store.js +14 -0
- package/node_modules/@spexcode/spec-core/dist/resilience.d.ts +2 -0
- package/node_modules/@spexcode/spec-core/dist/resilience.js +40 -0
- package/node_modules/@spexcode/spec-core/dist/review/index.d.ts +3 -0
- package/node_modules/@spexcode/spec-core/dist/review/index.js +5 -0
- package/node_modules/@spexcode/spec-core/dist/review/reviewFilters.d.ts +77 -0
- package/node_modules/@spexcode/spec-core/dist/review/reviewFilters.js +308 -0
- package/node_modules/@spexcode/spec-core/dist/review/reviewQuery.d.ts +66 -0
- package/node_modules/@spexcode/spec-core/dist/review/reviewQuery.js +180 -0
- package/node_modules/@spexcode/spec-core/dist/review/session.d.ts +4 -0
- package/node_modules/@spexcode/spec-core/dist/review/session.js +8 -0
- package/node_modules/@spexcode/spec-core/dist/reviewSnapshot.d.ts +15 -0
- package/node_modules/@spexcode/spec-core/dist/reviewSnapshot.js +12 -0
- package/node_modules/@spexcode/spec-core/dist/root-lru.d.ts +4 -0
- package/{spec-cli/src/root-lru.ts → node_modules/@spexcode/spec-core/dist/root-lru.js} +26 -30
- package/node_modules/@spexcode/spec-core/dist/specs.d.ts +117 -0
- package/node_modules/@spexcode/spec-core/dist/specs.js +489 -0
- package/node_modules/@spexcode/spec-core/package.json +28 -0
- package/node_modules/@spexcode/spec-eval/dist/cache.d.ts +10 -0
- package/node_modules/@spexcode/spec-eval/dist/cache.js +50 -0
- package/node_modules/@spexcode/spec-eval/dist/cli.d.ts +22 -0
- package/node_modules/@spexcode/spec-eval/dist/cli.js +981 -0
- package/node_modules/@spexcode/spec-eval/dist/evaltab.d.ts +98 -0
- package/node_modules/@spexcode/spec-eval/dist/evaltab.js +176 -0
- package/node_modules/@spexcode/spec-eval/dist/filing.d.ts +16 -0
- package/node_modules/@spexcode/spec-eval/dist/filing.js +36 -0
- package/node_modules/@spexcode/spec-eval/dist/freshness.d.ts +48 -0
- package/node_modules/@spexcode/spec-eval/dist/freshness.js +799 -0
- package/node_modules/@spexcode/spec-eval/dist/host.d.ts +46 -0
- package/node_modules/@spexcode/spec-eval/dist/host.js +53 -0
- package/node_modules/@spexcode/spec-eval/dist/humanok.d.ts +11 -0
- package/node_modules/@spexcode/spec-eval/dist/humanok.js +27 -0
- package/node_modules/@spexcode/spec-eval/dist/index.d.ts +4 -0
- package/node_modules/@spexcode/spec-eval/dist/index.js +4 -0
- package/node_modules/@spexcode/spec-eval/dist/remarks.d.ts +31 -0
- package/node_modules/@spexcode/spec-eval/dist/remarks.js +1 -0
- package/node_modules/@spexcode/spec-eval/dist/scenariofresh.d.ts +13 -0
- package/node_modules/@spexcode/spec-eval/dist/scenariofresh.js +303 -0
- package/node_modules/@spexcode/spec-eval/dist/scenarios.d.ts +99 -0
- package/node_modules/@spexcode/spec-eval/dist/scenarios.js +650 -0
- package/node_modules/@spexcode/spec-eval/dist/sessioneval.d.ts +307 -0
- package/node_modules/@spexcode/spec-eval/dist/sessioneval.js +1883 -0
- package/node_modules/@spexcode/spec-eval/dist/sidecar.d.ts +55 -0
- package/node_modules/@spexcode/spec-eval/dist/sidecar.js +82 -0
- package/node_modules/@spexcode/spec-eval/dist/timeline.d.ts +25 -0
- package/node_modules/@spexcode/spec-eval/dist/timeline.js +65 -0
- package/node_modules/@spexcode/spec-eval/dist/ui-path.d.ts +1 -0
- package/node_modules/@spexcode/spec-eval/dist/ui-path.js +2 -0
- package/node_modules/@spexcode/spec-eval/package.json +36 -0
- package/node_modules/@spexcode/spec-forge/dist/cache.d.ts +29 -0
- package/node_modules/@spexcode/spec-forge/dist/cache.js +59 -0
- package/node_modules/@spexcode/spec-forge/dist/cli.d.ts +1 -0
- package/node_modules/@spexcode/spec-forge/dist/cli.js +100 -0
- package/node_modules/@spexcode/spec-forge/dist/drivers/github.d.ts +2 -0
- package/node_modules/@spexcode/spec-forge/dist/drivers/github.js +116 -0
- package/node_modules/@spexcode/spec-forge/dist/drivers/gitlab.d.ts +7 -0
- package/node_modules/@spexcode/spec-forge/dist/drivers/gitlab.js +144 -0
- package/node_modules/@spexcode/spec-forge/dist/drivers.d.ts +10 -0
- package/node_modules/@spexcode/spec-forge/dist/drivers.js +83 -0
- package/node_modules/@spexcode/spec-forge/dist/index.d.ts +4 -0
- package/node_modules/@spexcode/spec-forge/dist/index.js +4 -0
- package/node_modules/@spexcode/spec-forge/dist/links.d.ts +15 -0
- package/node_modules/@spexcode/spec-forge/dist/links.js +65 -0
- package/node_modules/@spexcode/spec-forge/dist/needs-eval.d.ts +10 -0
- package/node_modules/@spexcode/spec-forge/dist/needs-eval.js +20 -0
- package/node_modules/@spexcode/spec-forge/dist/port.d.ts +53 -0
- package/node_modules/@spexcode/spec-forge/dist/port.js +1 -0
- package/node_modules/@spexcode/spec-forge/dist/resident.d.ts +7 -0
- package/node_modules/@spexcode/spec-forge/dist/resident.js +43 -0
- package/node_modules/@spexcode/spec-forge/package.json +32 -0
- package/package.json +33 -19
- package/spec-cli/bin/spex.mjs +0 -69
- package/spec-cli/src/anchors.ts +0 -706
- package/spec-cli/src/attach.ts +0 -43
- package/spec-cli/src/claude-headless.ts +0 -321
- package/spec-cli/src/cli.ts +0 -1115
- package/spec-cli/src/client.ts +0 -315
- package/spec-cli/src/cockpit.ts +0 -43
- package/spec-cli/src/codex-runtime-generations.ts +0 -646
- package/spec-cli/src/commit-surgery.ts +0 -68
- package/spec-cli/src/contract-filter.ts +0 -202
- package/spec-cli/src/delivery-queue.ts +0 -107
- package/spec-cli/src/doctor.ts +0 -516
- package/spec-cli/src/file-write.ts +0 -22
- package/spec-cli/src/gateway-auth.ts +0 -181
- package/spec-cli/src/gateway-hub.ts +0 -356
- package/spec-cli/src/gateway.ts +0 -368
- package/spec-cli/src/git.ts +0 -2180
- package/spec-cli/src/graph.ts +0 -221
- package/spec-cli/src/graphCache.ts +0 -641
- package/spec-cli/src/graphDelta.ts +0 -77
- package/spec-cli/src/graphStream.ts +0 -1019
- package/spec-cli/src/harness-select.ts +0 -77
- package/spec-cli/src/harness.ts +0 -2747
- package/spec-cli/src/headless-controller.ts +0 -63
- package/spec-cli/src/help.ts +0 -480
- package/spec-cli/src/host-resources.ts +0 -707
- package/spec-cli/src/host.ts +0 -611
- package/spec-cli/src/identity-presets.d.ts +0 -13
- package/spec-cli/src/identity-presets.js +0 -128
- package/spec-cli/src/index.ts +0 -730
- package/spec-cli/src/init.ts +0 -258
- package/spec-cli/src/issues-cli.ts +0 -276
- package/spec-cli/src/issues.ts +0 -237
- package/spec-cli/src/layout.ts +0 -557
- package/spec-cli/src/lint.ts +0 -458
- package/spec-cli/src/localIssues.ts +0 -538
- package/spec-cli/src/materialize.ts +0 -412
- package/spec-cli/src/mentions.ts +0 -81
- package/spec-cli/src/opencode-headless.ts +0 -205
- package/spec-cli/src/pi-headless.ts +0 -153
- package/spec-cli/src/plugin-harness.ts +0 -157
- package/spec-cli/src/process-identity.ts +0 -207
- package/spec-cli/src/project-identity.ts +0 -73
- package/spec-cli/src/project-store.ts +0 -17
- package/spec-cli/src/pty-bridge.ts +0 -396
- package/spec-cli/src/pty-helper.mjs +0 -96
- package/spec-cli/src/pty-native-helper.mjs +0 -22
- package/spec-cli/src/ranker.ts +0 -191
- package/spec-cli/src/reaper.ts +0 -125
- package/spec-cli/src/resilience.ts +0 -41
- package/spec-cli/src/reviewSnapshot.ts +0 -28
- package/spec-cli/src/reviews.ts +0 -405
- package/spec-cli/src/runtime-guard.ts +0 -35
- package/spec-cli/src/runtime-ownership.ts +0 -88
- package/spec-cli/src/search.bench.mjs +0 -80
- package/spec-cli/src/search.ts +0 -63
- package/spec-cli/src/session-cursors.ts +0 -91
- package/spec-cli/src/session-follow.ts +0 -182
- package/spec-cli/src/session-timeline.ts +0 -98
- package/spec-cli/src/sessions.ts +0 -3403
- package/spec-cli/src/sh.ts +0 -3
- package/spec-cli/src/slash-commands.ts +0 -318
- package/spec-cli/src/source-files.ts +0 -104
- package/spec-cli/src/specs.ts +0 -498
- package/spec-cli/src/supervise.ts +0 -245
- package/spec-cli/src/tree.ts +0 -118
- package/spec-cli/src/tsx-bin.ts +0 -18
- package/spec-cli/src/uninstall.ts +0 -171
- package/spec-cli/src/uploads.ts +0 -253
- package/spec-cli/src/worktree-sources.ts +0 -42
- package/spec-cli/templates/spec/project/.plugins/commands/supervisor/spec.md +0 -8
- package/spec-cli/templates/spec/project/.plugins/core/comment-altitude/spec.md +0 -28
- package/spec-cli/templates/spec/project/.plugins/core/spec.md +0 -23
- package/spec-cli/templates/spec/project/.plugins/prompts/atomic-landing/spec.md +0 -32
- package/spec-cli/templates/spec/project/.plugins/prompts/forge-link/spec.md +0 -9
- package/spec-cli/templates/spec/project/.plugins/prompts/memory-hygiene/spec.md +0 -15
- package/spec-cli/templates/spec/project/.plugins/prompts/reproduce-before-fix/spec.md +0 -18
- package/spec-dashboard/dist/assets/App-F9uaAVcH.js +0 -2
- package/spec-dashboard/dist/assets/Dashboard-Ba_jhxp1.js +0 -27
- package/spec-dashboard/dist/assets/Dashboard-C5ap-Sga.css +0 -1
- package/spec-dashboard/dist/assets/EvalsPage-FixoOg_n.js +0 -2
- package/spec-dashboard/dist/assets/IssuesPage-CuKLFhH3.js +0 -1
- package/spec-dashboard/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/spec-dashboard/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/spec-dashboard/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/spec-dashboard/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/spec-dashboard/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/spec-dashboard/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/spec-dashboard/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/spec-dashboard/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/spec-dashboard/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/spec-dashboard/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/spec-dashboard/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/spec-dashboard/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/spec-dashboard/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/spec-dashboard/dist/assets/MobileApp-CHgEHORJ.js +0 -2
- package/spec-dashboard/dist/assets/Modal-CQgYymmr.js +0 -1
- package/spec-dashboard/dist/assets/PageScroll-hT7UTLvD.js +0 -1
- package/spec-dashboard/dist/assets/ProjectsPage-CtXxakF9.js +0 -1
- package/spec-dashboard/dist/assets/SessionInterface-6GBZ9nXN.css +0 -32
- package/spec-dashboard/dist/assets/SessionInterface-Bpie-9fs.js +0 -39
- package/spec-dashboard/dist/assets/SessionWindow-CixDi4PI.js +0 -1
- package/spec-dashboard/dist/assets/Settings-C2MsucfE.js +0 -1
- package/spec-dashboard/dist/assets/Thread-C6Go8HRh.js +0 -13
- package/spec-dashboard/dist/assets/bindings-BC9vqpYU.js +0 -1
- package/spec-dashboard/dist/assets/data-B-RQmit6.js +0 -1
- package/spec-dashboard/dist/assets/index-CsI8DElI.css +0 -1
- package/spec-dashboard/dist/assets/index-DrVao0Ep.js +0 -41
- package/spec-dashboard/dist/assets/launch-BBH02b1v.js +0 -276
- package/spec-dashboard/dist/assets/launch-Cp579UoJ.css +0 -1
- package/spec-dashboard/dist/assets/terminalFont-C6oGNKrf.js +0 -1
- package/spec-dashboard/dist/index.html +0 -29
- package/spec-dashboard/src/reviewFilters.js +0 -322
- package/spec-dashboard/src/reviewQuery.js +0 -174
- package/spec-dashboard/src/session.js +0 -199
- package/spec-eval/src/cache.ts +0 -57
- package/spec-eval/src/cli.ts +0 -889
- package/spec-eval/src/evaltab.ts +0 -262
- package/spec-eval/src/filing.ts +0 -39
- package/spec-eval/src/freshness.ts +0 -557
- package/spec-eval/src/humanok.ts +0 -28
- package/spec-eval/src/scenariofresh.ts +0 -244
- package/spec-eval/src/scenarios.ts +0 -672
- package/spec-eval/src/sessioneval.ts +0 -2226
- package/spec-eval/src/sidecar.ts +0 -93
- package/spec-eval/src/timeline.ts +0 -54
- package/spec-forge/src/__fixtures__/github-forge.json +0 -63
- package/spec-forge/src/cache.ts +0 -66
- package/spec-forge/src/cli.ts +0 -99
- package/spec-forge/src/drivers/github.ts +0 -132
- package/spec-forge/src/drivers/gitlab.ts +0 -153
- package/spec-forge/src/drivers.ts +0 -73
- package/spec-forge/src/links.ts +0 -72
- package/spec-forge/src/needs-eval.ts +0 -29
- package/spec-forge/src/port.ts +0 -36
- package/spec-forge/src/resident.ts +0 -46
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/README.md +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/hooks/compat/mark-active-0.5.2-eef1.fixture +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/hooks/compat/mark-active-sed-v0.fixture +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/commit-msg +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/post-checkout +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/post-merge +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/pre-commit +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/prepare-commit-msg +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/reference-transaction +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/extract/spec.md +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/regroup/spec.md +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/rename/spec.md +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/spec.md +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/tidy/spec.md +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/idle/idle.sh +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/idle/spec.md +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/mark-active/mark-active.sh +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/mark-active/spec.md +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/session-fail/fail.sh +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/session-fail/spec.md +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec-first/spec.md +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec-of-file/spec.md +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/spec.md +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/skills/distill/digest.mjs +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/skills/distill/spec.md +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/skills/spec.md +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/spec.md +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/spec.md +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-core}/templates/spexcode.json +0 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export declare const GUIDANCE_SCHEMA_VERSION: 1;
|
|
2
|
+
export declare const GUIDANCE_CATALOG_SCHEMA: "spexcode.guidance-catalog/v1";
|
|
3
|
+
export declare const GUIDANCE_PAYLOAD_NAME: "guidance-catalog.json";
|
|
4
|
+
export type GuidanceKind = 'plugin' | 'help' | 'guide';
|
|
5
|
+
export type GuidanceSurface = 'system' | 'command' | 'hook' | 'skill' | 'agent' | 'review';
|
|
6
|
+
export type GuidanceContentRole = 'prompt' | 'help' | 'guide' | 'signal';
|
|
7
|
+
export type GuidanceSource = Readonly<{
|
|
8
|
+
path: string;
|
|
9
|
+
contentHash: string;
|
|
10
|
+
revision: string;
|
|
11
|
+
}>;
|
|
12
|
+
export type GuidanceEntry = Readonly<{
|
|
13
|
+
id: string;
|
|
14
|
+
kind: GuidanceKind;
|
|
15
|
+
surface?: GuidanceSurface;
|
|
16
|
+
title: string;
|
|
17
|
+
description: string;
|
|
18
|
+
contentRole: GuidanceContentRole;
|
|
19
|
+
content: string;
|
|
20
|
+
source: GuidanceSource;
|
|
21
|
+
runtime?: Readonly<{
|
|
22
|
+
path: string;
|
|
23
|
+
revision: string;
|
|
24
|
+
events: readonly string[];
|
|
25
|
+
order: number;
|
|
26
|
+
block: boolean;
|
|
27
|
+
}>;
|
|
28
|
+
}>;
|
|
29
|
+
export type EffectiveSystemContract = Readonly<{
|
|
30
|
+
content: string;
|
|
31
|
+
contentHash: string;
|
|
32
|
+
sourceEntryIds: readonly string[];
|
|
33
|
+
}>;
|
|
34
|
+
export type GuidanceBundle = Readonly<{
|
|
35
|
+
schemaVersion: typeof GUIDANCE_SCHEMA_VERSION;
|
|
36
|
+
revision: string;
|
|
37
|
+
entries: readonly GuidanceEntry[];
|
|
38
|
+
bundleHash: string;
|
|
39
|
+
catalogSchema: typeof GUIDANCE_CATALOG_SCHEMA;
|
|
40
|
+
payloadName: typeof GUIDANCE_PAYLOAD_NAME;
|
|
41
|
+
sourceRevision: string;
|
|
42
|
+
effectiveSystemContract: EffectiveSystemContract;
|
|
43
|
+
}>;
|
|
44
|
+
type GitReader = (args: string[]) => string;
|
|
45
|
+
export type GuidanceCatalogOptions = Readonly<{
|
|
46
|
+
root?: string;
|
|
47
|
+
revision?: string;
|
|
48
|
+
sourceRevision?: (path: string) => string;
|
|
49
|
+
gitReader?: GitReader;
|
|
50
|
+
}>;
|
|
51
|
+
/**
|
|
52
|
+
* Immutable product-side projection over the authoritative plugin/help/guide surfaces.
|
|
53
|
+
* The constructor reads existing registries and materializes one export payload at call time.
|
|
54
|
+
*/
|
|
55
|
+
export declare class GuidanceCatalog {
|
|
56
|
+
readonly bundle: GuidanceBundle;
|
|
57
|
+
constructor(options?: GuidanceCatalogOptions);
|
|
58
|
+
entries(): readonly GuidanceEntry[];
|
|
59
|
+
toJSON(): GuidanceBundle;
|
|
60
|
+
exportJson(): string;
|
|
61
|
+
write(path: string): void;
|
|
62
|
+
}
|
|
63
|
+
export declare function buildGuidanceCatalog(options?: GuidanceCatalogOptions): GuidanceCatalog;
|
|
64
|
+
export {};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { writeFileSync } from 'node:fs';
|
|
3
|
+
import { join, relative } from 'node:path';
|
|
4
|
+
import { git, repoRoot } from '@spexcode/spec-core';
|
|
5
|
+
import { loadAgentConfig, loadConfig, loadHookConfig, loadReviewConfig, loadSkillConfig, loadSystemConfig, } from '@spexcode/spec-core';
|
|
6
|
+
import { helpCatalogEntries } from './help.js';
|
|
7
|
+
import { guideCatalogEntries } from './guide.js';
|
|
8
|
+
import { HookPromptCatalog, HOOK_PROMPT_SOURCE } from './hook-prompts.js';
|
|
9
|
+
export const GUIDANCE_SCHEMA_VERSION = 1;
|
|
10
|
+
export const GUIDANCE_CATALOG_SCHEMA = 'spexcode.guidance-catalog/v1';
|
|
11
|
+
export const GUIDANCE_PAYLOAD_NAME = 'guidance-catalog.json';
|
|
12
|
+
const SURFACES = [
|
|
13
|
+
['agent', loadAgentConfig],
|
|
14
|
+
['command', loadConfig],
|
|
15
|
+
['hook', loadHookConfig],
|
|
16
|
+
['review', loadReviewConfig],
|
|
17
|
+
['skill', loadSkillConfig],
|
|
18
|
+
['system', loadSystemConfig],
|
|
19
|
+
];
|
|
20
|
+
const sha256 = (text) => createHash('sha256').update(text, 'utf8').digest('hex');
|
|
21
|
+
function freeze(value) {
|
|
22
|
+
if (!value || typeof value !== 'object' || Object.isFrozen(value))
|
|
23
|
+
return value;
|
|
24
|
+
for (const child of Object.values(value))
|
|
25
|
+
freeze(child);
|
|
26
|
+
return Object.freeze(value);
|
|
27
|
+
}
|
|
28
|
+
function sourcePathForPreset(preset) {
|
|
29
|
+
return join(preset.dir, 'spec.md').replaceAll('\\', '/');
|
|
30
|
+
}
|
|
31
|
+
function sortEntries(entries) {
|
|
32
|
+
return entries.sort((a, b) => {
|
|
33
|
+
const left = `${a.kind}\0${a.id}\0${a.surface ?? ''}\0${a.source.path}`;
|
|
34
|
+
const right = `${b.kind}\0${b.id}\0${b.surface ?? ''}\0${b.source.path}`;
|
|
35
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function sourceRevision(root, path, readGit) {
|
|
39
|
+
const result = readGit(['-C', root, 'log', '-1', '--format=%H', '--', path]).trim();
|
|
40
|
+
return result || 'working-tree';
|
|
41
|
+
}
|
|
42
|
+
function currentRevision(root, readGit) {
|
|
43
|
+
return readGit(['-C', root, 'rev-parse', 'HEAD']).trim() || 'working-tree';
|
|
44
|
+
}
|
|
45
|
+
function entrySource(root, path, text, revision, readSourceRevision) {
|
|
46
|
+
return { path: relative(root, join(root, path)).replaceAll('\\', '/'), contentHash: sha256(text), revision: readSourceRevision(path) || revision };
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Immutable product-side projection over the authoritative plugin/help/guide surfaces.
|
|
50
|
+
* The constructor reads existing registries and materializes one export payload at call time.
|
|
51
|
+
*/
|
|
52
|
+
export class GuidanceCatalog {
|
|
53
|
+
bundle;
|
|
54
|
+
constructor(options = {}) {
|
|
55
|
+
const root = options.root ?? repoRoot();
|
|
56
|
+
const readGit = options.gitReader ?? git;
|
|
57
|
+
const revision = options.revision ?? currentRevision(root, readGit);
|
|
58
|
+
const readSourceRevision = options.sourceRevision ?? ((path) => sourceRevision(root, path, readGit));
|
|
59
|
+
const sourceRevisions = new Map();
|
|
60
|
+
const sourceRevisionFor = (path) => {
|
|
61
|
+
const known = sourceRevisions.get(path);
|
|
62
|
+
if (known)
|
|
63
|
+
return known;
|
|
64
|
+
const value = readSourceRevision(path) || revision;
|
|
65
|
+
sourceRevisions.set(path, value);
|
|
66
|
+
return value;
|
|
67
|
+
};
|
|
68
|
+
const entries = [];
|
|
69
|
+
const hookPrompts = new HookPromptCatalog();
|
|
70
|
+
for (const [surface, loader] of SURFACES) {
|
|
71
|
+
for (const preset of loader()) {
|
|
72
|
+
if (surface === 'hook') {
|
|
73
|
+
const prompt = hookPrompts.entry(preset.name);
|
|
74
|
+
const handler = preset.files.find((file) => file.endsWith('.sh'));
|
|
75
|
+
if (!handler)
|
|
76
|
+
throw new Error(`surface:hook node '${preset.name}' ships no .sh script (one co-located .sh required)`);
|
|
77
|
+
entries.push({
|
|
78
|
+
id: `plugin:${surface}:${preset.name}`,
|
|
79
|
+
kind: 'plugin',
|
|
80
|
+
surface,
|
|
81
|
+
title: prompt.title,
|
|
82
|
+
description: prompt.description,
|
|
83
|
+
contentRole: prompt.role,
|
|
84
|
+
content: prompt.content,
|
|
85
|
+
source: entrySource(root, HOOK_PROMPT_SOURCE, prompt.content, revision, sourceRevisionFor),
|
|
86
|
+
runtime: {
|
|
87
|
+
path: handler,
|
|
88
|
+
revision: sourceRevisionFor(handler),
|
|
89
|
+
events: [...preset.events],
|
|
90
|
+
order: preset.order,
|
|
91
|
+
block: preset.block,
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
const path = sourcePathForPreset(preset);
|
|
97
|
+
entries.push({
|
|
98
|
+
id: `plugin:${surface}:${preset.name}`,
|
|
99
|
+
kind: 'plugin',
|
|
100
|
+
surface,
|
|
101
|
+
title: preset.title,
|
|
102
|
+
description: preset.desc,
|
|
103
|
+
contentRole: 'prompt',
|
|
104
|
+
content: preset.body,
|
|
105
|
+
source: entrySource(root, path, preset.body, revision, sourceRevisionFor),
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
for (const entry of helpCatalogEntries()) {
|
|
110
|
+
const path = 'spec-cli/src/help.ts';
|
|
111
|
+
entries.push({
|
|
112
|
+
id: `help:${entry.id}`,
|
|
113
|
+
kind: 'help',
|
|
114
|
+
title: entry.title,
|
|
115
|
+
description: 'CLI command usage and safety guidance',
|
|
116
|
+
contentRole: 'help',
|
|
117
|
+
content: entry.text,
|
|
118
|
+
source: entrySource(root, path, entry.text, revision, sourceRevisionFor),
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
for (const entry of guideCatalogEntries()) {
|
|
122
|
+
const path = 'spec-cli/src/guide.ts';
|
|
123
|
+
entries.push({
|
|
124
|
+
id: `guide:${entry.id}`,
|
|
125
|
+
kind: 'guide',
|
|
126
|
+
title: entry.title,
|
|
127
|
+
description: 'CLI workflow and format guidance',
|
|
128
|
+
contentRole: 'guide',
|
|
129
|
+
content: entry.text,
|
|
130
|
+
source: entrySource(root, path, entry.text, revision, sourceRevisionFor),
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
const systemEntries = entries.filter((entry) => entry.kind === 'plugin' && entry.surface === 'system');
|
|
134
|
+
const effectiveSystemContent = systemEntries.map((entry) => entry.content.trim()).filter(Boolean).join('\n\n');
|
|
135
|
+
const payload = {
|
|
136
|
+
schemaVersion: GUIDANCE_SCHEMA_VERSION,
|
|
137
|
+
revision,
|
|
138
|
+
entries: sortEntries(entries),
|
|
139
|
+
catalogSchema: GUIDANCE_CATALOG_SCHEMA,
|
|
140
|
+
payloadName: GUIDANCE_PAYLOAD_NAME,
|
|
141
|
+
sourceRevision: revision,
|
|
142
|
+
effectiveSystemContract: {
|
|
143
|
+
content: effectiveSystemContent,
|
|
144
|
+
contentHash: sha256(effectiveSystemContent),
|
|
145
|
+
sourceEntryIds: systemEntries.map((entry) => entry.id),
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
const bundleHash = sha256(JSON.stringify(payload));
|
|
149
|
+
this.bundle = freeze({ ...payload, bundleHash });
|
|
150
|
+
}
|
|
151
|
+
entries() {
|
|
152
|
+
return this.bundle.entries;
|
|
153
|
+
}
|
|
154
|
+
toJSON() {
|
|
155
|
+
return this.bundle;
|
|
156
|
+
}
|
|
157
|
+
exportJson() {
|
|
158
|
+
return `${JSON.stringify(this.bundle, null, 2)}\n`;
|
|
159
|
+
}
|
|
160
|
+
write(path) {
|
|
161
|
+
writeFileSync(path, this.exportJson(), 'utf8');
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
export function buildGuidanceCatalog(options = {}) {
|
|
165
|
+
return new GuidanceCatalog(options);
|
|
166
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function guideText(topic?: string): string | null;
|
|
2
|
+
export declare function guideTopics(): string[];
|
|
3
|
+
export type GuideCatalogEntry = Readonly<{
|
|
4
|
+
id: string;
|
|
5
|
+
title: string;
|
|
6
|
+
text: string;
|
|
7
|
+
}>;
|
|
8
|
+
export declare function guideCatalogEntries(): readonly GuideCatalogEntry[];
|
|
@@ -14,7 +14,7 @@ the rest, you don't hand-author the spec tree or wire the dashboard yourself.
|
|
|
14
14
|
startup commands.)
|
|
15
15
|
|
|
16
16
|
2. Adopt a repo
|
|
17
|
-
cd <your-repo> && spex init --harness claude,codex,opencode,pi,claude-headless,opencode-headless,pi-headless,codex-headless # seeds .spec/ + git hooks (additive, never overwrites)
|
|
17
|
+
cd <your-repo> && spex init --harness claude,codex,opencode,pi,zcode,claude-headless,opencode-headless,pi-headless,codex-headless # seeds .spec/ + git hooks (additive, never overwrites)
|
|
18
18
|
--harness is required and has no default — the explicit choice of which harness(es) materialize
|
|
19
19
|
delivers into. The example lists every built-in; drop the ones you don't use (any one id or
|
|
20
20
|
comma-separated subset is valid).
|
|
@@ -42,8 +42,7 @@ Look these up on demand — the formats an agent authors, and the settings it co
|
|
|
42
42
|
spex guide settings the spexcode.json / spexcode.local.json settings (launchers, dashboard icon, upload,
|
|
43
43
|
lint budgets, layout) — every field, and which of the two files it belongs in
|
|
44
44
|
spex guide footprint the footprint model — what SpexCode plants in a repo, and who sees it
|
|
45
|
-
(committed | ignored | hidden), and every migration recipe
|
|
46
|
-
|
|
45
|
+
(committed | ignored | hidden), and every migration recipe`;
|
|
47
46
|
const SPEC = `spex guide spec — the spec.md file format
|
|
48
47
|
|
|
49
48
|
A spec node is a DIRECTORY under .spec/<project>/…/<id>/ holding a spec.md. The node's id is its leaf dir
|
|
@@ -101,6 +100,13 @@ code does it. Two optional level-2 headings split ground truth from detail:
|
|
|
101
100
|
Bodies without those headings are read whole. Link sibling nodes with [[node-id]] — every link must name
|
|
102
101
|
a REAL node (lint's mention rule; backtick a placeholder like \`[[node]]\` so it reads as sample text).
|
|
103
102
|
|
|
103
|
+
COMMENT ALTITUDE: specs own intent, invariants, policy, and observable contracts; comments only navigate
|
|
104
|
+
non-obvious local decisions. Put contract or intent in the owning spec body, not a code comment. Keep a short
|
|
105
|
+
nearby comment only for ordering, platform behavior, measured pitfalls, or why a plausible alternative is
|
|
106
|
+
unsafe; delete commentary that merely translates code or repeats a name/type. Preserve measured values,
|
|
107
|
+
version-specific behavior, and rejected alternatives not in the spec. \`@@@title - explanation\` is reserved for
|
|
108
|
+
genuinely tricky surviving local reasoning.
|
|
109
|
+
|
|
104
110
|
WHAT lint CHECKS (spex spec lint; the pre-commit hook gates on errors):
|
|
105
111
|
integrity (error) every code:/related: path exists — and every anchor RESOLVES: a dead anchor (unit
|
|
106
112
|
deleted/renamed), an ambiguous one (two same-named units in one file), a file that
|
|
@@ -144,8 +150,10 @@ Heuristic spec health is deliberately outside this production gate. Bare \`spex
|
|
|
144
150
|
altitude and breadth findings; the tidy workflow consumes that report and adds semantic judgment.
|
|
145
151
|
|
|
146
152
|
LIFECYCLE: author each node on a node/<id> branch, one node per commit; \`spex spec lint\` must reach 0 errors
|
|
147
|
-
before merge. \`spex init\` seeds the first tree; \`spex guide eval\` covers the sibling eval.md, the measurement file
|
|
153
|
+
before merge. \`spex init\` seeds the first tree; \`spex guide eval\` covers the sibling eval.md, the measurement file.
|
|
148
154
|
|
|
155
|
+
SHARED LANDING: if the shared checkout is mid-merge, wait. Never abort or resolve someone else's merge; if your
|
|
156
|
+
own landing stops half-merged, abort it and report.`;
|
|
149
157
|
const EVAL = `spex guide eval — the eval.md file format
|
|
150
158
|
|
|
151
159
|
An eval.md sits BESIDE a node's spec.md and says how to MEASURE the node's loss — the gap between live
|
|
@@ -187,6 +195,13 @@ pre-commit \`internal check-staged\` BLOCKS the commit.
|
|
|
187
195
|
BODY (after the frontmatter): prose naming the measurement method — YATU ("You As The User"): the agent
|
|
188
196
|
looks at / calls the real product surface, not an internal helper chosen to make the evidence easy.
|
|
189
197
|
|
|
198
|
+
REPAIR EVIDENCE: for a bug fix, use one scenario's fail→pass pair. A, BEFORE EDITING: find the violated scenario
|
|
199
|
+
or add one to \`eval.md\`, run it against the old committed behavior, and file
|
|
200
|
+
\`spex eval add <node> --scenario <s> --fail\` with evidence of the failure. B, AFTER EDITING: run that same
|
|
201
|
+
scenario against the working tree until it passes; commit the verified tree; then file
|
|
202
|
+
\`spex eval add <node> --scenario <s> --pass\`. The measurement's \`codeSha\` must be that commit. New intent has no
|
|
203
|
+
prior failure to reproduce.
|
|
204
|
+
|
|
190
205
|
MEASURING AND FILING: the agent runs the scenario however it likes (a browser run, an API
|
|
191
206
|
transcript, a by-hand pass), compares the result to \`expected\`, and files it:
|
|
192
207
|
spex eval add <node> [--scenario <name>] (--pass | --fail) [--note <text>]
|
|
@@ -227,6 +242,31 @@ PICK THE EVIDENCE KIND BY WHAT THE BEHAVIOUR DOES OVER TIME:
|
|
|
227
242
|
\`data\` — rendered as a validatable data block, not flattened into scrolling transcript
|
|
228
243
|
text; free-form output stays a transcript. You pick the flag; the KIND follows the bytes.
|
|
229
244
|
The flags combine in ONE filing — several stills can ride beside the clip of the same run.
|
|
245
|
+
POPULATION DISCIPLINE: when \`expected\` quantifies over a set ("every X is Y", "nothing under Z"), the
|
|
246
|
+
measurement reports the set's SIZE, not only the verdict. An empty set satisfies a universal claim
|
|
247
|
+
VACUOUSLY, so a pass over nothing and a real pass are indistinguishable — and the universal form reads
|
|
248
|
+
STRICTER than an enumeration, which is what makes it the hardest wrong-population case to catch. File
|
|
249
|
+
\`N of N\`, never a bare boolean: \`0 of 0\` shows itself, \`true\` does not. The denominator must come from a
|
|
250
|
+
source that can DISAGREE with the numerator — count the population off the surface that does NOT decide the
|
|
251
|
+
outcome (a backend export, a ledger, the enumeration upstream of the thing under test) and the passing members
|
|
252
|
+
off the surface under test. A ratio whose halves share one source says only "what I selected, I selected": a
|
|
253
|
+
selector that silently drops half the population reports \`3 of 3\` when the truth is 6. Two weaker defences
|
|
254
|
+
that do not substitute — a precondition sentence depends on the next author remembering it, a printed
|
|
255
|
+
denominator depends on a reader noticing it. Nothing here enforces either (the schema has no population
|
|
256
|
+
field), so treat a zero-population run as a NON-measurement and do not file it. Cheaper than any of that, when
|
|
257
|
+
you can get it: restate the claim over something the product CANNOT make empty. "every active node's name is
|
|
258
|
+
readable" needs someone to arrange activity and goes vacuous when nobody does; "the rendered size never falls
|
|
259
|
+
below the authored size" is a property of the viewport itself, true of a one-node graph, and has no
|
|
260
|
+
population to get wrong. A claim with no population beats a well-reported one.
|
|
261
|
+
RENDERED GEOMETRY (browser): measure the rendered BOX, never the authored STYLE. An ancestor CSS \`transform\`
|
|
262
|
+
— the ordinary zoom/pan wrapper on a canvas or graph view — does NOT change computed style, so
|
|
263
|
+
\`getComputedStyle(el).fontSize\` answers the AUTHORED size while the screen shows that size times the
|
|
264
|
+
ancestor scale, and the measurement is a SILENT FALSE PASS. (No numbers here on purpose: the authored size is
|
|
265
|
+
whatever this project's stylesheet says today, and a manual that hard-codes one teaches a constant that
|
|
266
|
+
drifts — read it off the tree you are measuring.) Go through \`getBoundingClientRect()\` (it carries the
|
|
267
|
+
ancestor scale) and derive the effective size from the box, or from a known string's width. This is also why
|
|
268
|
+
a geometric claim ships WITH its \`--image\`: a rect can be computed wrong, while "is that text legible" is
|
|
269
|
+
human-judgeable, so the two evidences cover each other.
|
|
230
270
|
ANCHOR DISCIPLINE: an eval's \`codeSha\` is HEAD at filing time, and a git sha names only a COMMIT — an
|
|
231
271
|
uncommitted change has none. So measure the tree you are about to commit, COMMIT it, then file; confidence
|
|
232
272
|
is earned on the working tree, but the anchor can only land after the commit. Filing from a dirty tree
|
|
@@ -250,10 +290,8 @@ code file or the scenario (the eval.md) moves since it was filed.
|
|
|
250
290
|
eval-owners (a file governed by > maxOwners scenarios — split it)
|
|
251
291
|
spex eval ls <node> the eval timeline (verdict · freshness · evidence), newest first
|
|
252
292
|
spex eval scenario ls [<node>] the declared contracts; text --unmeasured = blind-spot worklist; --json = canonical declaration index
|
|
253
|
-
spex eval clean GC the content-addressed evidence cache
|
|
254
|
-
|
|
255
|
-
const UPLOAD_DEFAULTS = uploadPolicyDefaults()
|
|
256
|
-
|
|
293
|
+
spex eval clean GC the content-addressed evidence cache`;
|
|
294
|
+
const UPLOAD_DEFAULTS = uploadPolicyDefaults();
|
|
257
295
|
const SETTINGS = `spex guide settings — SpexCode's runtime settings (spexcode.json / spexcode.local.json)
|
|
258
296
|
|
|
259
297
|
SpexCode reads PROJECT runtime settings from TWO optional JSON files at the repo root. There is no imperative
|
|
@@ -285,7 +323,8 @@ see LAUNCHERS.
|
|
|
285
323
|
── LAYOUT (spexcode.json — portable; set only for a NON-DEFAULT repo layout) ──
|
|
286
324
|
main path to the source-of-truth checkout. Default: the \`main\` worktree.
|
|
287
325
|
mainBranch the stable source-of-truth BRANCH worktrees fork from. spex init stamps the root checkout's
|
|
288
|
-
branch at adoption
|
|
326
|
+
branch at adoption and the stamped value stays put for every later checkout, so a clone or a
|
|
327
|
+
fresh worktree does not re-guess it; an older omitted value uses the conventional main.
|
|
289
328
|
branchPrefix how a node branch is named. Default "node/".
|
|
290
329
|
Example — a repo whose trunk is \`staging\`, not \`main\`:
|
|
291
330
|
{ "mainBranch": "staging" }
|
|
@@ -492,8 +531,7 @@ Example — tune opt-in health diagnosis without changing the lint gate:
|
|
|
492
531
|
stamps the explicit choice, and a missing field fails materialize loud. PERSISTENT and
|
|
493
532
|
git-transactional: the edit takes effect at the next git-native materialize anchor (the commit
|
|
494
533
|
that carries it, a checkout/merge that receives it, or a manual \`spex materialize\`) — a
|
|
495
|
-
deselected harness's artifacts are pruned by that pass
|
|
496
|
-
|
|
534
|
+
deselected harness's artifacts are pruned by that pass.`;
|
|
497
535
|
const FOOTPRINT = `spex guide footprint — what SpexCode plants in a repo, and who sees it (one fixed behavior per kind)
|
|
498
536
|
|
|
499
537
|
SpexCode claims software engineering's HEAD (the recording of intent) and TAIL (the storage of
|
|
@@ -573,19 +611,74 @@ not a flag flip.
|
|
|
573
611
|
legacy untracked spec track the sources once: git add .spec spexcode.json (commit on your branch)
|
|
574
612
|
WARNING: tracking is not retroactive secrecy — history already pushed
|
|
575
613
|
elsewhere cannot be recalled.
|
|
576
|
-
back out entirely \`spex uninstall\` (add --hooks to also remove the spexcode git hooks)
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
614
|
+
back out entirely \`spex uninstall\` (add --hooks to also remove the spexcode git hooks).`;
|
|
615
|
+
const FILES = `spex guide files — hand an agent artifact back to the human
|
|
616
|
+
|
|
617
|
+
Use the session's file list when an artifact belongs in the human's hands:
|
|
618
|
+
|
|
619
|
+
spex session files add <path> publish one current file path
|
|
620
|
+
spex session files ls read your published paths
|
|
621
|
+
spex session files retract <path> withdraw one path
|
|
622
|
+
|
|
623
|
+
Posting resolves a relative path from your current directory and records its absolute path beside the global
|
|
624
|
+
session record. It copies, moves, stages, and uploads NOTHING. The path is live: editing the file after
|
|
625
|
+
posting changes what the human downloads. The reference is host-local; opening the session elsewhere cannot
|
|
626
|
+
make its path point at another machine's file.
|
|
627
|
+
|
|
628
|
+
The session page's top-right files icon is grey while the list is empty. Once live, it opens the posted list;
|
|
629
|
+
choosing a path previews its current text or raster-image bytes in a pop-out, while the adjacent download tool
|
|
630
|
+
downloads it through the backend at that moment. Previews are limited to 2 MiB, text and PNG/JPEG/GIF/WebP;
|
|
631
|
+
other types and larger files say to download instead. A missing, moved, or unreadable target stays listed but
|
|
632
|
+
reports that it no longer exists. The backend refuses a preview or download for any path not on that session's
|
|
633
|
+
list.
|
|
634
|
+
|
|
635
|
+
This is the reverse of a dashboard attachment: [[file-attach]] sends human bytes to an agent. Files publishes
|
|
636
|
+
an agent-owned path for a human to download.`;
|
|
637
|
+
const WEB = `spex guide web — hand a running local web service to the human
|
|
638
|
+
|
|
639
|
+
Use the session web list after starting a local page the human should inspect:
|
|
640
|
+
|
|
641
|
+
spex session web add http://127.0.0.1:5173/
|
|
642
|
+
spex session web ls
|
|
643
|
+
spex session web retract http://127.0.0.1:5173/
|
|
644
|
+
|
|
645
|
+
Posting records the canonical loopback HTTP URL beside the global session record. It does not fetch the page,
|
|
646
|
+
start a process, or move bytes. The dashboard uses its own same-origin gateway only when the human opens the
|
|
647
|
+
preview, including WebSocket traffic, so changes to the running service are visible at that moment.
|
|
648
|
+
|
|
649
|
+
Only loopback HTTP URLs with an explicit port are accepted: 127.0.0.1, localhost, or ::1. The service remains
|
|
650
|
+
host-local and must stay running. A stopped service remains listed and reports that its upstream is unavailable.
|
|
651
|
+
The proxy has a path prefix, so use relative asset/navigation URLs or configure your dev server's base path;
|
|
652
|
+
hard-coded root-absolute Vite/Next assets cannot be made portable by a proxy guessing at JavaScript.`;
|
|
653
|
+
const TOPICS = { spec: SPEC, eval: EVAL, settings: SETTINGS, footprint: FOOTPRINT, files: FILES, web: WEB };
|
|
580
654
|
// every guide page ends by naming the OTHER help layer, so a reader never dead-ends here: guide is
|
|
581
655
|
// the skill layer (workflows · formats · settings); command usage lives in help.ts's two layers.
|
|
582
|
-
const FOOTER = `\n\n(This is the skill layer. Command usage: \`spex help\` for the map, \`spex help <command>\` for one command.)
|
|
583
|
-
|
|
656
|
+
const FOOTER = `\n\n(This is the skill layer. Command usage: \`spex help\` for the map, \`spex help <command>\` for one command.)`;
|
|
584
657
|
// null = unknown topic: the caller fails loud (exit non-zero) while still naming the layers to go
|
|
585
658
|
// back to — an unknown topic must never read as a successful page ([[cli-surface]]'s dead-end rule).
|
|
586
|
-
export function guideText(topic
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
659
|
+
export function guideText(topic) {
|
|
660
|
+
if (!topic)
|
|
661
|
+
return SETUP + FOOTER;
|
|
662
|
+
const t = TOPICS[topic];
|
|
663
|
+
return t ? t + FOOTER : null;
|
|
664
|
+
}
|
|
665
|
+
// @@@ the unknown-topic list is DERIVED, never re-typed - a hand-kept enumeration goes blind the moment a
|
|
666
|
+
// topic is added beside it, and it did: `files` and `web` shipped while the error still named four.
|
|
667
|
+
export function guideTopics() {
|
|
668
|
+
return Object.keys(TOPICS);
|
|
669
|
+
}
|
|
670
|
+
// The catalog indexes the same rendered pages the CLI serves. Keeping this projection beside TOPICS makes a
|
|
671
|
+
// newly registered page automatically appear in the export and in the unknown-topic diagnostic.
|
|
672
|
+
export function guideCatalogEntries() {
|
|
673
|
+
const entries = [];
|
|
674
|
+
const setup = guideText();
|
|
675
|
+
if (setup)
|
|
676
|
+
entries.push({ id: 'setup', title: 'spex guide', text: setup });
|
|
677
|
+
for (const topic of guideTopics()) {
|
|
678
|
+
const text = guideText(topic);
|
|
679
|
+
if (text)
|
|
680
|
+
entries.push({ id: topic, title: `spex guide ${topic}`, text });
|
|
681
|
+
}
|
|
682
|
+
return entries;
|
|
590
683
|
}
|
|
591
|
-
import { uploadPolicyDefaults } from '
|
|
684
|
+
import { uploadPolicyDefaults } from '@spexcode/spec-core';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type Harness, type HarnessId } from './harness.js';
|
|
2
|
+
export type HarnessTarget = {
|
|
3
|
+
kind: 'native';
|
|
4
|
+
id: HarnessId;
|
|
5
|
+
} | {
|
|
6
|
+
kind: 'plugin';
|
|
7
|
+
folder: string;
|
|
8
|
+
};
|
|
9
|
+
export declare const NATIVE_HARNESS_IDS: readonly HarnessId[];
|
|
10
|
+
export declare function parseHarnessFlag(spec: string): unknown[];
|
|
11
|
+
export declare function resolveHarnessTargets(raw: unknown): HarnessTarget[];
|
|
12
|
+
export declare function partitionHarnesses(targets: HarnessTarget[]): {
|
|
13
|
+
selected: Harness[];
|
|
14
|
+
unselected: Harness[];
|
|
15
|
+
plugins: {
|
|
16
|
+
folder: string;
|
|
17
|
+
}[];
|
|
18
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { HARNESSES } from './harness.js';
|
|
2
|
+
// the native vocabulary (for messages and init's flag parsing). There is NO default set: the delivery
|
|
3
|
+
// targets are an explicit adopter choice, stamped by `spex init --harness` and read back from config forever.
|
|
4
|
+
export const NATIVE_HARNESS_IDS = HARNESSES.map((h) => h.id);
|
|
5
|
+
const KNOWN = HARNESSES.map((h) => h.id);
|
|
6
|
+
// the one-line repair every missing-selection error carries — the field is REQUIRED, never defaulted,
|
|
7
|
+
// because with many harnesses a silent "deliver everywhere" would litter the adopter's tree with artifacts
|
|
8
|
+
// for tools they never installed.
|
|
9
|
+
const MISSING = `spexcode.json has no "harnesses" field — the delivery targets are an EXPLICIT choice, never a default. Declare it, e.g. "harnesses": ["claude"] — members are native ids (${KNOWN.join(', ')}) or {"plugin":"<folder>"}. Fresh adoption: \`spex init --harness <ids>\` stamps it.`;
|
|
10
|
+
// parse `spex init --harness <spec>` into the raw JSON members the `harnesses` field carries: a comma-
|
|
11
|
+
// separated list where `plugin:<folder>` means a plugin target and anything else is a native id. Pure
|
|
12
|
+
// spelling translation — legality (unknown ids, plugin exclusivity) stays with resolveHarnessTargets.
|
|
13
|
+
export function parseHarnessFlag(spec) {
|
|
14
|
+
return spec.split(',').map((s) => s.trim()).filter(Boolean)
|
|
15
|
+
.map((s) => (s.startsWith('plugin:') ? { plugin: s.slice('plugin:'.length) } : s));
|
|
16
|
+
}
|
|
17
|
+
// parse + validate the spexcode.json `harnesses` field into resolved targets. FAIL LOUD on an illegal set —
|
|
18
|
+
// materialize and init both gate on this so a bad config never silently delivers the wrong thing. `raw` is the
|
|
19
|
+
// JSON value as written; a MISSING field is itself illegal (the choice must exist, stamped by init).
|
|
20
|
+
export function resolveHarnessTargets(raw) {
|
|
21
|
+
if (raw === undefined || raw === null)
|
|
22
|
+
throw new Error(MISSING);
|
|
23
|
+
if (!Array.isArray(raw))
|
|
24
|
+
throw new Error(`spexcode.json "harnesses" must be an ARRAY of targets (got ${typeof raw}). Members are native ids (${KNOWN.join(', ')}) or {"plugin":"<folder>"}.`);
|
|
25
|
+
if (raw.length === 0)
|
|
26
|
+
throw new Error(`spexcode.json "harnesses" is EMPTY — list at least one target: native ids (${KNOWN.join(', ')}) or {"plugin":"<folder>"}.`);
|
|
27
|
+
const targets = [];
|
|
28
|
+
for (const m of raw) {
|
|
29
|
+
if (typeof m === 'string') {
|
|
30
|
+
if (m === 'plugin')
|
|
31
|
+
throw new Error(`spexcode.json "harnesses": a plugin target needs an EXPLICIT landing folder — write {"plugin":"<folder>"} (e.g. {"plugin":".adopter-a"}), not the bare string "plugin", because each host agent reads a different plugins dir.`);
|
|
32
|
+
if (!KNOWN.includes(m))
|
|
33
|
+
throw new Error(`spexcode.json "harnesses": unknown harness id "${m}" — known native ids are ${KNOWN.join(', ')}, or use {"plugin":"<folder>"}.`);
|
|
34
|
+
targets.push({ kind: 'native', id: m });
|
|
35
|
+
}
|
|
36
|
+
else if (m && typeof m === 'object' && !Array.isArray(m) && 'plugin' in m) {
|
|
37
|
+
const folder = m.plugin;
|
|
38
|
+
if (typeof folder !== 'string' || !folder.trim())
|
|
39
|
+
throw new Error(`spexcode.json "harnesses": a {"plugin":…} target needs a NON-EMPTY folder string (e.g. {"plugin":".adopter-a"}) — each host agent reads a different plugins dir, so the folder must be explicit.`);
|
|
40
|
+
targets.push({ kind: 'plugin', folder: folder.trim() });
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
throw new Error(`spexcode.json "harnesses": each member must be a native id string (${KNOWN.join(', ')}) or a {"plugin":"<folder>"} object — got ${JSON.stringify(m)}.`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// PLUGIN EXCLUSIVITY: a plugin bundle is a SUPERSET delivery to its host agent, so pairing it with any
|
|
47
|
+
// native harness double-delivers. So a set with a plugin may carry NO native harness.
|
|
48
|
+
const natives = targets.filter((t) => t.kind === 'native');
|
|
49
|
+
if (targets.some((t) => t.kind === 'plugin') && natives.length)
|
|
50
|
+
throw new Error(`spexcode.json "harnesses": a plugin target is EXCLUSIVE — it cannot coexist with native harnesses (${natives.map((t) => t.id).join(', ')}). A plugin bundle already delivers the whole system to its host agent, so pairing it with a native harness double-delivers. Choose EITHER native harnesses OR plugin target(s).`);
|
|
51
|
+
return targets;
|
|
52
|
+
}
|
|
53
|
+
// split the live HARNESSES adapters by whether the resolved targets SELECT them: selected get write()n,
|
|
54
|
+
// unselected get clean()ed (pruned). `plugins` carries the plugin targets (no emitter yet — a later node).
|
|
55
|
+
export function partitionHarnesses(targets) {
|
|
56
|
+
const selectedIds = new Set(targets.filter((t) => t.kind === 'native').map((t) => t.id));
|
|
57
|
+
return {
|
|
58
|
+
selected: HARNESSES.filter((h) => selectedIds.has(h.id)),
|
|
59
|
+
unselected: HARNESSES.filter((h) => !selectedIds.has(h.id)),
|
|
60
|
+
plugins: targets.filter((t) => t.kind === 'plugin').map((t) => ({ folder: t.folder })),
|
|
61
|
+
};
|
|
62
|
+
}
|