spexcode 0.6.2 → 0.6.6
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 +3 -1
- package/bin/spex.mjs +4 -0
- package/node_modules/@spexcode/session-core/dist/delivery-queue.d.ts +23 -0
- package/node_modules/@spexcode/session-core/dist/delivery-queue.js +195 -0
- package/node_modules/@spexcode/session-core/dist/index.d.ts +5 -0
- package/node_modules/@spexcode/session-core/dist/index.js +5 -0
- package/node_modules/@spexcode/session-core/dist/internal.d.ts +3 -0
- package/node_modules/@spexcode/session-core/dist/internal.js +3 -0
- package/node_modules/@spexcode/session-core/dist/message.d.ts +22 -0
- package/node_modules/@spexcode/session-core/dist/message.js +52 -0
- package/node_modules/@spexcode/session-core/dist/record-lock.d.ts +7 -0
- package/node_modules/@spexcode/session-core/dist/record-lock.js +152 -0
- package/node_modules/@spexcode/session-core/dist/runtime-session.d.ts +50 -0
- package/node_modules/@spexcode/session-core/dist/runtime-session.js +286 -0
- package/node_modules/@spexcode/session-core/dist/session-cursors.d.ts +14 -0
- package/node_modules/@spexcode/session-core/dist/session-cursors.js +82 -0
- package/node_modules/@spexcode/session-core/dist/session-timeline.d.ts +46 -0
- package/node_modules/@spexcode/session-core/dist/session-timeline.js +216 -0
- package/node_modules/@spexcode/session-core/package.json +33 -0
- package/node_modules/@spexcode/spec-cli/bin/spex.mjs +77 -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 +36 -0
- package/node_modules/@spexcode/spec-cli/dist/claude-headless.js +316 -0
- package/node_modules/@spexcode/spec-cli/dist/cli.d.ts +1 -0
- package/node_modules/@spexcode/spec-cli/dist/cli.js +1908 -0
- package/node_modules/@spexcode/spec-cli/dist/client.d.ts +112 -0
- package/node_modules/@spexcode/spec-cli/dist/client.js +481 -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 +58 -0
- package/node_modules/@spexcode/spec-cli/dist/codex-runtime-generations.js +798 -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/doctor.d.ts +9 -0
- package/node_modules/@spexcode/spec-cli/dist/doctor.js +553 -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 +363 -0
- package/node_modules/@spexcode/spec-cli/dist/gateway.d.ts +38 -0
- package/node_modules/@spexcode/spec-cli/dist/gateway.js +527 -0
- package/node_modules/@spexcode/spec-cli/dist/graphCache.d.ts +27 -0
- package/node_modules/@spexcode/spec-cli/dist/graphCache.js +717 -0
- package/node_modules/@spexcode/spec-cli/dist/graphSnapshot.d.ts +14 -0
- package/node_modules/@spexcode/spec-cli/dist/graphSnapshot.js +36 -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} +36 -32
- 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 +338 -0
- package/node_modules/@spexcode/spec-cli/dist/harness.js +3146 -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 +15 -0
- package/node_modules/@spexcode/spec-cli/dist/help.js +594 -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 +8 -0
- package/node_modules/@spexcode/spec-cli/dist/listen.js +24 -0
- 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 +5 -0
- package/node_modules/@spexcode/spec-cli/dist/opencode-headless.js +215 -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/runtime-rotate.d.ts +1 -0
- package/node_modules/@spexcode/spec-cli/dist/runtime-rotate.js +58 -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-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 +11 -0
- package/node_modules/@spexcode/spec-cli/dist/session-timeline.js +20 -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 +433 -0
- package/node_modules/@spexcode/spec-cli/dist/sessions.js +4667 -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 +1 -1
- package/node_modules/@spexcode/spec-cli/package.json +49 -0
- package/node_modules/@spexcode/spec-cli/templates/spec/project/.plugins/commands/supervisor/spec.md +8 -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/{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-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 +170 -0
- package/node_modules/@spexcode/spec-core/dist/git.js +2768 -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 +187 -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 -728
- package/spec-cli/src/attach.ts +0 -43
- package/spec-cli/src/claude-headless.ts +0 -321
- package/spec-cli/src/cli.ts +0 -1258
- package/spec-cli/src/client.ts +0 -414
- 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 -165
- package/spec-cli/src/doctor.ts +0 -516
- package/spec-cli/src/execution-trace.ts +0 -444
- 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 -358
- package/spec-cli/src/gateway.ts +0 -461
- package/spec-cli/src/git.ts +0 -2556
- package/spec-cli/src/graph.ts +0 -271
- package/spec-cli/src/graphCache.ts +0 -710
- 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 -3025
- package/spec-cli/src/headless-controller.ts +0 -63
- package/spec-cli/src/help.ts +0 -492
- package/spec-cli/src/host-resources.ts +0 -762
- 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 -138
- package/spec-cli/src/index.ts +0 -818
- 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 -640
- package/spec-cli/src/lint.ts +0 -488
- package/spec-cli/src/listen.ts +0 -28
- package/spec-cli/src/localIssues.ts +0 -538
- package/spec-cli/src/materialize.ts +0 -417
- 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 -434
- 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-execution.ts +0 -68
- package/spec-cli/src/session-files.ts +0 -121
- package/spec-cli/src/session-follow.ts +0 -182
- package/spec-cli/src/session-reparent.ts +0 -33
- package/spec-cli/src/session-timeline.ts +0 -247
- package/spec-cli/src/session-web.ts +0 -135
- package/spec-cli/src/sessions.ts +0 -3883
- 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-dashboard/dist/assets/App-B6IbFbGu.js +0 -2
- package/spec-dashboard/dist/assets/Dashboard-C5ap-Sga.css +0 -1
- package/spec-dashboard/dist/assets/Dashboard-_sDk7Rcg.js +0 -27
- package/spec-dashboard/dist/assets/EvalsPage-BT357Lyt.js +0 -2
- package/spec-dashboard/dist/assets/IssuesPage-BG9rNOgV.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-D9yPMR3A.js +0 -2
- package/spec-dashboard/dist/assets/Modal-B3EcgeA3.js +0 -1
- package/spec-dashboard/dist/assets/PageScroll-CNZOugWV.js +0 -1
- package/spec-dashboard/dist/assets/ProjectsPage-C2CRHmvs.js +0 -1
- package/spec-dashboard/dist/assets/SessionInterface-6GBZ9nXN.css +0 -32
- package/spec-dashboard/dist/assets/SessionInterface-DOEjuT3l.js +0 -40
- package/spec-dashboard/dist/assets/SessionWindow-1nYgZ4CL.js +0 -1
- package/spec-dashboard/dist/assets/Settings-7WeTJn0V.js +0 -1
- package/spec-dashboard/dist/assets/Thread-CEbzAFQn.js +0 -13
- package/spec-dashboard/dist/assets/bindings-BC9vqpYU.js +0 -1
- package/spec-dashboard/dist/assets/data-SlvxNA2r.js +0 -1
- package/spec-dashboard/dist/assets/index-DLVeOHL-.js +0 -41
- package/spec-dashboard/dist/assets/index-DYLGfPjx.css +0 -1
- package/spec-dashboard/dist/assets/launch-Cp579UoJ.css +0 -1
- package/spec-dashboard/dist/assets/launch-yxCYr64x.js +0 -276
- package/spec-dashboard/dist/assets/sessionSurface--7l69h4F.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 -894
- package/spec-eval/src/evaltab.ts +0 -264
- package/spec-eval/src/filing.ts +0 -39
- package/spec-eval/src/freshness.ts +0 -836
- 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 -2220
- 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/comment-altitude/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/core/spec.md +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/atomic-landing/spec.md +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/forge-link/spec.md +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/memory-hygiene/spec.md +0 -0
- /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/reproduce-before-fix/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
package/spec-cli/src/ranker.ts
DELETED
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
// tier multipliers, name > desc > body. A doc's NAME is the strongest signal, its one-line DESC a curated
|
|
2
|
-
// summary (next), its BODY the weakest per-hit — but the body carries BM25 term-frequency so a doc that
|
|
3
|
-
// genuinely concentrates a rare word still climbs. IDF scales all three. The spread only ORDERS the tiers;
|
|
4
|
-
// the discriminating magnitude comes from rarity (IDF) and body-density (BM25), not these constants — which
|
|
5
|
-
// is why they sit in flat plateaus rather than being fitted to any case.
|
|
6
|
-
const W_NAME_PREFIX = 8
|
|
7
|
-
const W_NAME_SUBSTR = 5
|
|
8
|
-
const W_DESC = 2.2
|
|
9
|
-
const W_BODY = 1
|
|
10
|
-
|
|
11
|
-
// a tiny stoplist of question scaffolding + length-1 tokens, dropped so "how does the … is it …" can't drown
|
|
12
|
-
// the content words. Deliberately small and general — NOT tuned to any benchmark; just the function words a
|
|
13
|
-
// natural-language query carries that match nothing meaningful. Quantifiers (many, several, same, too…) are
|
|
14
|
-
// NOT stopped: in this corpus they are load-bearing ("too many owners" IS the multi-ownership concept —
|
|
15
|
-
// dropping them measurably breaks that reach).
|
|
16
|
-
const STOP = new Set([
|
|
17
|
-
'the', 'a', 'an', 'and', 'or', 'of', 'to', 'in', 'on', 'is', 'it', 'its', 'as', 'at', 'by', 'for',
|
|
18
|
-
'how', 'does', 'do', 'what', 'which', 'that', 'this', 'these', 'those', 'with', 'from', 'into', 'are',
|
|
19
|
-
'be', 'can', 'just', 'them', 'they', 'their', 'so', 'if', 'not', 'no', 'but', 'vs', 'us', 'we', 'you',
|
|
20
|
-
])
|
|
21
|
-
|
|
22
|
-
// The corpus is mostly English but not only — some nodes carry CJK prose (the root spexcode node is a whole
|
|
23
|
-
// Chinese paragraph), and the dashboard palette ([[shared-ranker]]) ranks session/issue titles that are
|
|
24
|
-
// frequently Chinese. CJK has no spaces, so a whitespace/`[^a-z0-9]` split silently discards ALL of it. We
|
|
25
|
-
// tokenize the SAME way on both sides: an ASCII alphanumeric run is one token; each CJK character is its own
|
|
26
|
-
// token (a unigram). Unigrams — not bigrams — keep the shared prefix-match/IDF/BM25 machinery untouched (a
|
|
27
|
-
// single-char query still matches, no bigram edge cases) and stay BLUNT & ROBUST, the floor's whole stance.
|
|
28
|
-
// Han (incl. Ext-A + compat) plus Japanese kana; enough to cover the CJK a spec body or a session title carries.
|
|
29
|
-
const CJK = '\\u3400-\\u4dbf\\u4e00-\\u9fff\\uf900-\\ufaff\\u3040-\\u30ff' // Ext-A · Unified · Compat · kana
|
|
30
|
-
const TOKEN_RE = new RegExp(`[a-z0-9]+|[${CJK}]`, 'g')
|
|
31
|
-
const CJK_RE = new RegExp(`[${CJK}]`)
|
|
32
|
-
function isCjk(t: string): boolean { return CJK_RE.test(t) }
|
|
33
|
-
function tokenize(text: string): string[] {
|
|
34
|
-
return text.toLowerCase().match(TOKEN_RE) ?? []
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// tokenize, lowercase, drop stopwords + length-1 ASCII tokens (a length-1 CJK token is a real word — keep it), de-dup.
|
|
38
|
-
export function terms(query: string): string[] {
|
|
39
|
-
const seen = new Set<string>()
|
|
40
|
-
for (const w of tokenize(query)) {
|
|
41
|
-
if (isCjk(w) || (w.length > 1 && !STOP.has(w))) seen.add(w)
|
|
42
|
-
}
|
|
43
|
-
return [...seen]
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// the words of a field, lowercased — used for word-boundary (prefix-of-a-word) matching, which kills
|
|
47
|
-
// short-token pollution (`main` must not match inside `domain`); CJK chars are single-char words.
|
|
48
|
-
function words(text: string): string[] {
|
|
49
|
-
return tokenize(text)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// light query-side stem for prefix matching: drop a trailing plural 's' (len≥4, not 'ss') then a mute 'e'
|
|
53
|
-
// (len≥5) — so `sessions` prefix-reaches `session`, `merge`→`merg` reaches `merging`, `declare`→`declar`
|
|
54
|
-
// reaches `declaration`. Without the e-drop the spec's promised merge↔merging reach silently never worked
|
|
55
|
-
// (`'merging'.startsWith('merge')` is false). Query-side only; IDF self-neutralises the extra reach (a
|
|
56
|
-
// looser term matches more docs → bigger df → smaller idf), so no flood.
|
|
57
|
-
function stem(t: string): string {
|
|
58
|
-
let s = t
|
|
59
|
-
if (s.length >= 4 && s.endsWith('s') && !s.endsWith('ss')) s = s.slice(0, -1)
|
|
60
|
-
if (s.length >= 5 && s.endsWith('e')) s = s.slice(0, -1)
|
|
61
|
-
return s
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// name match is forward-only (a chosen short field — reverse would let a stray short word swallow it);
|
|
65
|
-
// desc/body match bidirectionally so a longer doc word still reaches a shorter query term, reverse gated to
|
|
66
|
-
// words ≥3 chars so a stray short word can't swallow a longer term (IDF neutralises the generic words it
|
|
67
|
-
// pulls in).
|
|
68
|
-
function nameMatch(term: string, w: string): boolean { return w.startsWith(stem(term)) }
|
|
69
|
-
function textMatch(term: string, w: string): boolean { return w.startsWith(stem(term)) || (w.length >= 3 && term.startsWith(w)) }
|
|
70
|
-
|
|
71
|
-
// how strongly a query term's name-prefix hit counts, over a doc's name words: the FRACTION of the matched
|
|
72
|
-
// name word the query term actually spans. A full word (`port`→`port`, `api`→`api`) is 1.0 — the strong
|
|
73
|
-
// signal a name tier is for; a short query term that only PREFIXES a longer, unrelated word (`port`→`portable`,
|
|
74
|
-
// `governs`→`governed`) covers less of it and is weaker evidence, so it earns proportionally less than the
|
|
75
|
-
// full name weight. Floored at 0.5 (a prefix is still evidence, not noise). Returns 0 when no name word is
|
|
76
|
-
// prefixed. This is what stops a corpus-growth collision — a sibling whose NAME merely starts with a query
|
|
77
|
-
// word (portable-layout for "port", governed-related for "governs") — from outranking the node that owns the
|
|
78
|
-
// concept; the floor sat at an implicit 1.0 before, which let those partial prefixes score a full name hit.
|
|
79
|
-
const NAME_COVER_FLOOR = 0.5
|
|
80
|
-
function nameCover<T>(term: string, n: Fields<T>): number {
|
|
81
|
-
const st = stem(term)
|
|
82
|
-
let best = 0
|
|
83
|
-
for (const w of n.nameWords) {
|
|
84
|
-
if (w.startsWith(st)) { const r = st.length / w.length; if (r > best) best = r }
|
|
85
|
-
}
|
|
86
|
-
return best > 0 ? Math.max(NAME_COVER_FLOOR, best) : 0
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// classic BM25 tf: frequency with saturation (K1 sets how fast it saturates) and length-normalisation (B),
|
|
90
|
-
// both in a wide insensitive plateau. tf=0 → 0.
|
|
91
|
-
const K1 = 1.2
|
|
92
|
-
const B = 0.4
|
|
93
|
-
function bm25tf(tf: number, len: number, avgLen: number): number {
|
|
94
|
-
if (tf <= 0) return 0
|
|
95
|
-
return (tf * (K1 + 1)) / (tf + K1 * (1 - B + (B * len) / (avgLen || 1)))
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// the precomputed searchable fields of one doc (built once, reused for df, scoring, and snippet).
|
|
99
|
-
type Fields<T> = { ref: T; name: string; nameWords: string[]; desc: string; descWords: string[]; bodyWords: string[]; snippetText: string }
|
|
100
|
-
|
|
101
|
-
// the pre-IDF weight a term earns against one doc, picking its single best tier (three fields): a name
|
|
102
|
-
// word-prefix beats a name substring beats a desc hit beats a body hit. Name is a short, chosen field →
|
|
103
|
-
// near-binary, scaled only by prefix COVERAGE (a full word counts full; a query term that is a mere prefix
|
|
104
|
-
// of a longer name word counts proportionally less — see nameCover). Desc is presence too (a curated
|
|
105
|
-
// one-liner — repetition there is stuffing, not evidence)
|
|
106
|
-
// but LENGTH-NORMALISED: it was flat-binary until descs drifted long and a bloated desc became a cheat code
|
|
107
|
-
// (one 60-word desc catches every query term a curated one-liner can't). bm25tf(1, avgLen, avgLen) = 1, so
|
|
108
|
-
// a hit in an average-length desc scores exactly the old binary W_DESC — the normalisation only bites
|
|
109
|
-
// outliers. The body keeps the full BM25-saturated term-frequency that discriminates the long ties.
|
|
110
|
-
function tierWeight<T>(term: string, n: Fields<T>, avgBodyLen: number, avgDescLen: number): number {
|
|
111
|
-
const cover = nameCover(term, n)
|
|
112
|
-
if (cover > 0) return W_NAME_PREFIX * cover
|
|
113
|
-
if (n.name.includes(term)) return W_NAME_SUBSTR
|
|
114
|
-
if (n.descWords.some((w) => textMatch(term, w))) return W_DESC * bm25tf(1, n.descWords.length, avgDescLen)
|
|
115
|
-
const tf = n.bodyWords.reduce((c, w) => c + (textMatch(term, w) ? 1 : 0), 0)
|
|
116
|
-
return W_BODY * bm25tf(tf, n.bodyWords.length, avgBodyLen)
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// a short single-line window of prose around the FIRST matched term, so a reader sees WHY it matched. Falls
|
|
120
|
-
// back to the desc (then the text head) when only the name matched. Collapsed to one line, ~window chars.
|
|
121
|
-
function snippetFor(text: string, desc: string, qterms: string[], window = 140): string {
|
|
122
|
-
const flat = text.replace(/\s+/g, ' ').trim()
|
|
123
|
-
const lower = flat.toLowerCase()
|
|
124
|
-
let at = -1
|
|
125
|
-
for (const t of qterms) {
|
|
126
|
-
// ASCII terms locate at a word boundary (so `main` doesn't hit inside `domain`); a CJK term has no
|
|
127
|
-
// `\b` around it (JS `\b` is ASCII-only), so locate it by plain substring.
|
|
128
|
-
const i = isCjk(t) ? lower.indexOf(t) : lower.search(new RegExp('\\b' + t.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')))
|
|
129
|
-
if (i >= 0 && (at < 0 || i < at)) at = i
|
|
130
|
-
}
|
|
131
|
-
if (at < 0) {
|
|
132
|
-
const fb = (desc || flat).replace(/\s+/g, ' ').trim()
|
|
133
|
-
return fb.length > window ? fb.slice(0, window).trimEnd() + '…' : fb
|
|
134
|
-
}
|
|
135
|
-
const start = Math.max(0, at - Math.floor(window / 3))
|
|
136
|
-
let s = flat.slice(start, start + window).trim()
|
|
137
|
-
if (start > 0) s = '…' + s
|
|
138
|
-
if (start + window < flat.length) s = s + '…'
|
|
139
|
-
return s
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// what a caller hands in per doc: the original item (`ref`, returned verbatim) + its three text fields.
|
|
143
|
-
export type RankInput<T> = { ref: T; name: string; desc: string; body: string }
|
|
144
|
-
export type Ranked<T> = { ref: T; score: number; snippet: string }
|
|
145
|
-
|
|
146
|
-
// the shared entrypoint: sum each query term's best-tier weight × IDF, keep docs hitting ≥1 term, sort by
|
|
147
|
-
// score desc (stable — equal scores keep the caller's pre-sorted input order), cap to `limit` (default 10).
|
|
148
|
-
export function rankDocs<T>(query: string, inputs: RankInput<T>[], opts: { limit?: number } = {}): Ranked<T>[] {
|
|
149
|
-
const limit = opts.limit ?? 10
|
|
150
|
-
const qterms = terms(query)
|
|
151
|
-
if (!qterms.length) return []
|
|
152
|
-
|
|
153
|
-
const docs: Fields<T>[] = inputs.map((d) => {
|
|
154
|
-
const name = d.name.toLowerCase()
|
|
155
|
-
return {
|
|
156
|
-
ref: d.ref, name, nameWords: words(name),
|
|
157
|
-
desc: d.desc.toLowerCase(), descWords: words(d.desc),
|
|
158
|
-
bodyWords: words(d.body),
|
|
159
|
-
snippetText: `${d.desc}\n${d.body}`,
|
|
160
|
-
}
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
// IDF per query term: df = docs containing it (any field), idf = ln(N/df) — a term in every doc scores 0,
|
|
164
|
-
// a rare one carries the rank. Read from the corpus, not hand-set.
|
|
165
|
-
const N = docs.length
|
|
166
|
-
const avgBodyLen = docs.reduce((a, n) => a + n.bodyWords.length, 0) / (N || 1)
|
|
167
|
-
const avgDescLen = docs.reduce((a, n) => a + n.descWords.length, 0) / (N || 1)
|
|
168
|
-
const idf: Record<string, number> = {}
|
|
169
|
-
for (const t of qterms) {
|
|
170
|
-
let df = 0
|
|
171
|
-
for (const n of docs) {
|
|
172
|
-
if (n.nameWords.some((w) => nameMatch(t, w)) || n.descWords.some((w) => textMatch(t, w)) || n.bodyWords.some((w) => textMatch(t, w))) df++
|
|
173
|
-
}
|
|
174
|
-
idf[t] = df > 0 ? Math.log(N / df) : 0
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const scored: Ranked<T>[] = []
|
|
178
|
-
for (const n of docs) {
|
|
179
|
-
let score = 0
|
|
180
|
-
// cap EACH term's contribution at W_NAME_PREFIX: idf and BM25 order the tiers WITHIN this ceiling, but no
|
|
181
|
-
// single query term may out-score a full name hit. A many-word question should be answered by the node
|
|
182
|
-
// that matches it BROADLY, not by one that spikes on a single rare word it happens to carry in its NAME
|
|
183
|
-
// (a `spex search`-named node swallowing "…searches specs…", an injected-* node swallowing "injected…") —
|
|
184
|
-
// the corpus-growth failure where one uncapped idf×name term buried a node matching more of the query.
|
|
185
|
-
for (const t of qterms) score += Math.min(tierWeight(t, n, avgBodyLen, avgDescLen) * idf[t], W_NAME_PREFIX)
|
|
186
|
-
if (score <= 0) continue
|
|
187
|
-
scored.push({ ref: n.ref, score: Math.round(score * 100) / 100, snippet: snippetFor(n.snippetText, n.desc, qterms) })
|
|
188
|
-
}
|
|
189
|
-
scored.sort((a, b) => b.score - a.score) // stable: equal scores keep the caller's pre-sorted input order
|
|
190
|
-
return scored.slice(0, limit)
|
|
191
|
-
}
|
package/spec-cli/src/reaper.ts
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
// @@@ socket-level connection reaper ([[spec-cli]]) - the ONE mechanism that reaps abandoned sockets (the
|
|
2
|
-
// 135-conn starvation that wedged the public port and triggered the mass-restore cascade), and the SINGLE
|
|
3
|
-
// OWNER of the deadlines it enforces. Node's own `headersTimeout`/`keepAliveTimeout` cover the same phases
|
|
4
|
-
// (pre-request, idle-between-requests) and so are a second mechanism racing this one: MEASURED (eval
|
|
5
|
-
// server-reaps-abandoned-connections, issue #65) a `headersTimeout: 20000` set beside the reaper won the
|
|
6
|
-
// race on every reap at default config and silently capped SPEXCODE_REAP_HEADER_MS above 20s — the knob
|
|
7
|
-
// went dead while the close still looked timely (Node's 408, not the reaper's destroy). So install()
|
|
8
|
-
// DISABLES those overlapping Node timeouts on the server it guards; this helper is an explicit per-socket
|
|
9
|
-
// deadline at the server boundary, with no platform machinery shadowing it.
|
|
10
|
-
//
|
|
11
|
-
// It keys on "no request has completed yet / idle between requests" — never on response DURATION — so a
|
|
12
|
-
// long-lived ESTABLISHED stream (the /api/graph/stream SSE, a terminal WebSocket upgrade) is exempt for as
|
|
13
|
-
// long as it streams. The lifecycle per socket:
|
|
14
|
-
// - on socket birth: arm the HEADER deadline — the socket must produce a fully-parsed request within it,
|
|
15
|
-
// else it is a slow-loris and gets destroyed.
|
|
16
|
-
// - on 'request' (headers complete → the request is in flight): disarm. An active request/response is
|
|
17
|
-
// never reaped, however long its body/response takes (a slow board build or a streaming SSE response).
|
|
18
|
-
// - when the response finishes/closes and no request is left in flight: re-arm the IDLE deadline (the
|
|
19
|
-
// keep-alive window). Another request disarms it again; silence past it reaps the idle keep-alive socket.
|
|
20
|
-
// - on 'upgrade' (WebSocket): mark exempt permanently — a persistent bidirectional stream, not a request
|
|
21
|
-
// that ever "completes".
|
|
22
|
-
//
|
|
23
|
-
// WHICH socket the deadline lives on is load-bearing. On a TLS server (the public gateway) 'connection'
|
|
24
|
-
// fires with the RAW TCP socket, but every 'request'/'upgrade' reports the wrapping TLSSocket — a deadline
|
|
25
|
-
// armed on the raw socket is unreachable from request handling, never disarms, and destroys every TLS
|
|
26
|
-
// connection at the header deadline no matter how alive it is (MEASURED, eval
|
|
27
|
-
// stream-survives-public-gateway: the dashboard's actively-pinging SSE + terminal WS through the https
|
|
28
|
-
// gateway died every ~30s — the "reconnecting…" storm). So per-socket state is keyed on the socket requests
|
|
29
|
-
// actually report: the TLSSocket (born at 'secureConnection') on a TLS server, the plain socket elsewhere.
|
|
30
|
-
// The raw pre-handshake phase gets its own header-deadline guard (a TCP connect that never completes the TLS
|
|
31
|
-
// handshake is the same slow-loris one layer down), linked raw→TLS by the connection's addr:port 4-tuple —
|
|
32
|
-
// public API only, no reliance on Node's private TLSSocket internals.
|
|
33
|
-
//
|
|
34
|
-
// The child's reaped close propagates back through the supervisor's raw-TCP proxy (which pairs socket
|
|
35
|
-
// halves), so a reaped upstream frees its public-side socket too — no separate raw timeout on the proxy,
|
|
36
|
-
// which would blind it to a legitimately-idle WS/SSE.
|
|
37
|
-
import type { Server as HttpServer } from 'node:http'
|
|
38
|
-
import type { Socket } from 'node:net'
|
|
39
|
-
import { Server as TlsServer } from 'node:tls'
|
|
40
|
-
|
|
41
|
-
export interface ReaperOptions {
|
|
42
|
-
// ms a freshly-connected (or post-response idle) socket has to START a new request before it is reaped as a
|
|
43
|
-
// slow-loris. Env: SPEXCODE_REAP_HEADER_MS. Default 30s.
|
|
44
|
-
headerMs?: number
|
|
45
|
-
// ms a keep-alive socket may sit idle BETWEEN requests before reaping. Env: SPEXCODE_REAP_IDLE_MS. Default 15s.
|
|
46
|
-
idleMs?: number
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
interface SocketState { timer?: NodeJS.Timeout; active: number; upgraded: boolean; arm(ms: number): void; disarm(): void }
|
|
50
|
-
const STATE = Symbol('spexcode.reaper')
|
|
51
|
-
|
|
52
|
-
function resolveMs(explicit: number | undefined, env: string | undefined, fallback: number): number {
|
|
53
|
-
if (typeof explicit === 'number' && explicit > 0) return explicit
|
|
54
|
-
const n = Number(env)
|
|
55
|
-
return Number.isFinite(n) && n > 0 ? n : fallback
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Attach the reaper to a Node http/https server. Call it right after the server is created (before or just
|
|
59
|
-
// after listen); it hooks the socket-birth event ('connection', or 'secureConnection' on TLS servers),
|
|
60
|
-
// 'request' and 'upgrade', and needs no changes to the request handlers.
|
|
61
|
-
export function installConnectionReaper(server: HttpServer, opts: ReaperOptions = {}): void {
|
|
62
|
-
const headerMs = resolveMs(opts.headerMs, process.env.SPEXCODE_REAP_HEADER_MS, 30000)
|
|
63
|
-
const idleMs = resolveMs(opts.idleMs, process.env.SPEXCODE_REAP_IDLE_MS, 15000)
|
|
64
|
-
|
|
65
|
-
// claim single ownership of the phases the reaper covers (see header comment): Node's overlapping
|
|
66
|
-
// timeouts would otherwise race these deadlines and silently cap the env knobs. `requestTimeout` is
|
|
67
|
-
// deliberately LEFT at Node's default (~5 min): it bounds the in-flight request-body phase the reaper
|
|
68
|
-
// exempts (a silently-abandoned mid-body upload has no other reaper), and 5 min shadows no sane knob.
|
|
69
|
-
server.headersTimeout = 0
|
|
70
|
-
server.keepAliveTimeout = 0
|
|
71
|
-
|
|
72
|
-
// per-socket tracking, on the SAME socket object 'request'/'upgrade' will report (see header comment).
|
|
73
|
-
const track = (socket: Socket) => {
|
|
74
|
-
const state: SocketState = {
|
|
75
|
-
timer: undefined, active: 0, upgraded: false,
|
|
76
|
-
disarm() { if (state.timer) { clearTimeout(state.timer); state.timer = undefined } },
|
|
77
|
-
arm(ms: number) { state.disarm(); state.timer = setTimeout(() => socket.destroy(), ms); state.timer.unref?.() },
|
|
78
|
-
}
|
|
79
|
-
;(socket as unknown as Record<symbol, SocketState>)[STATE] = state
|
|
80
|
-
state.arm(headerMs) // slow-loris guard: first request's headers must complete within headerMs
|
|
81
|
-
socket.once('close', state.disarm) // socket gone → drop its pending timer
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (server instanceof TlsServer) {
|
|
85
|
-
// TLS: requests report the TLSSocket, so that is where the deadline must live. The raw phase before the
|
|
86
|
-
// handshake completes still needs a guard of its own; the 4-tuple key hands it off to the TLSSocket.
|
|
87
|
-
const pendingHandshake = new Map<string, () => void>()
|
|
88
|
-
server.on('connection', (raw: Socket) => {
|
|
89
|
-
const key = `${raw.remoteAddress}:${raw.remotePort}`
|
|
90
|
-
const timer = setTimeout(() => raw.destroy(), headerMs)
|
|
91
|
-
timer.unref?.()
|
|
92
|
-
const done = () => { clearTimeout(timer); pendingHandshake.delete(key) }
|
|
93
|
-
pendingHandshake.set(key, done)
|
|
94
|
-
raw.once('close', done)
|
|
95
|
-
})
|
|
96
|
-
server.on('secureConnection', (tlsSocket) => {
|
|
97
|
-
pendingHandshake.get(`${tlsSocket.remoteAddress}:${tlsSocket.remotePort}`)?.()
|
|
98
|
-
track(tlsSocket as unknown as Socket)
|
|
99
|
-
})
|
|
100
|
-
} else {
|
|
101
|
-
server.on('connection', track)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
server.on('request', (req, res) => {
|
|
105
|
-
const s = (req.socket as unknown as Record<symbol, SocketState>)[STATE]
|
|
106
|
-
if (!s) return
|
|
107
|
-
s.active++
|
|
108
|
-
s.disarm() // a request is in flight — never reap an active request/response
|
|
109
|
-
let ended = false
|
|
110
|
-
const done = () => {
|
|
111
|
-
if (ended) return
|
|
112
|
-
ended = true
|
|
113
|
-
s.active--
|
|
114
|
-
// response over and nothing else in flight → this is now an idle keep-alive socket; re-arm.
|
|
115
|
-
if (s.active === 0 && !s.upgraded && !req.socket.destroyed) s.arm(idleMs)
|
|
116
|
-
}
|
|
117
|
-
res.once('finish', done) // response fully sent
|
|
118
|
-
res.once('close', done) // response aborted / connection dropped
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
server.on('upgrade', (req) => {
|
|
122
|
-
const s = (req.socket as unknown as Record<symbol, SocketState>)[STATE]
|
|
123
|
-
if (s) { s.upgraded = true; s.disarm() } // persistent stream — exempt for its lifetime
|
|
124
|
-
})
|
|
125
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs'
|
|
2
|
-
|
|
3
|
-
function describe(e: unknown): string {
|
|
4
|
-
return e instanceof Error ? e.message : String(e)
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
// run a per-worktree DETAIL read; on a throw, branch on whether the worktree DIRECTORY still exists.
|
|
8
|
-
// dir gone → the worktree was genuinely removed mid-read → return null so the caller omits it.
|
|
9
|
-
// dir present → a flaky detail read (ENOENT race on a sibling file, or a git index/ref lock under a
|
|
10
|
-
// concurrent merge) → return the caller's `degraded` row so an EXISTING worktree is NEVER
|
|
11
|
-
// dropped from the board. read-failure != non-existence.
|
|
12
|
-
// `dir` is the worktree path (the existence fact). Accepts a sync OR async fn — resolveLayout's overlay
|
|
13
|
-
// read is async, listSessions' row read is sync; `degraded` is a sync raw-facts fallback.
|
|
14
|
-
export async function guardWorktree<T>(dir: string, fn: () => T | Promise<T>, degraded: () => T): Promise<T | null> {
|
|
15
|
-
try {
|
|
16
|
-
return await fn()
|
|
17
|
-
} catch (e) {
|
|
18
|
-
if (!existsSync(dir)) {
|
|
19
|
-
console.warn(`spec-cli: worktree ${dir} gone from disk (removed mid-read), omitting: ${describe(e)}`)
|
|
20
|
-
return null
|
|
21
|
-
}
|
|
22
|
-
console.warn(`spec-cli: worktree ${dir} detail-read failed (transient/lock); serving degraded row: ${describe(e)}`)
|
|
23
|
-
return degraded()
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// the last-resort process net: log an otherwise-fatal async throw and KEEP SERVING. Registering these
|
|
28
|
-
// handlers is itself what overrides Node's default "print the stack and exit" — so the backend rides out
|
|
29
|
-
// a transient race it didn't anticipate instead of dropping the public port. Idempotent (guarded) so a
|
|
30
|
-
// double-install in one process can't stack duplicate handlers.
|
|
31
|
-
let guardsInstalled = false
|
|
32
|
-
export function installProcessGuards(): void {
|
|
33
|
-
if (guardsInstalled) return
|
|
34
|
-
guardsInstalled = true
|
|
35
|
-
process.on('unhandledRejection', (reason) => {
|
|
36
|
-
console.error(`spec-cli: unhandledRejection kept the server alive (investigate): ${reason instanceof Error ? reason.stack : describe(reason)}`)
|
|
37
|
-
})
|
|
38
|
-
process.on('uncaughtException', (err) => {
|
|
39
|
-
console.error(`spec-cli: uncaughtException kept the server alive (investigate): ${err?.stack || describe(err)}`)
|
|
40
|
-
})
|
|
41
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
export type ReviewEvalNode = {
|
|
2
|
-
id: string
|
|
3
|
-
hue?: number
|
|
4
|
-
scenarios: any[]
|
|
5
|
-
evals: any[]
|
|
6
|
-
readings: any[]
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export type ReviewSnapshot = {
|
|
10
|
-
issues: any[]
|
|
11
|
-
evalNodes: ReviewEvalNode[]
|
|
12
|
-
forgeRevision: number
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
let current: ReviewSnapshot | null = null
|
|
16
|
-
|
|
17
|
-
export function publishReviewSnapshot(snapshot: ReviewSnapshot): void {
|
|
18
|
-
current = snapshot
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function readReviewSnapshot(): ReviewSnapshot {
|
|
22
|
-
if (!current) throw new Error('review snapshot is unavailable before the first successful graph build')
|
|
23
|
-
return current
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function hasReviewSnapshot(): boolean {
|
|
27
|
-
return current !== null
|
|
28
|
-
}
|