trail-code 0.0.0-stage → 0.28.0-semantic.3
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/LICENSE +21 -0
- package/README.md +567 -2
- package/dist/ai/crux.d.ts +88 -0
- package/dist/ai/crux.d.ts.map +1 -0
- package/dist/ai/crux.js +219 -0
- package/dist/ai/crux.js.map +1 -0
- package/dist/ai/failure.d.ts +60 -0
- package/dist/ai/failure.d.ts.map +1 -0
- package/dist/ai/failure.js +86 -0
- package/dist/ai/failure.js.map +1 -0
- package/dist/ai/llm/anthropic.d.ts +37 -0
- package/dist/ai/llm/anthropic.d.ts.map +1 -0
- package/dist/ai/llm/anthropic.js +144 -0
- package/dist/ai/llm/anthropic.js.map +1 -0
- package/dist/ai/llm/factory.d.ts +28 -0
- package/dist/ai/llm/factory.d.ts.map +1 -0
- package/dist/ai/llm/factory.js +36 -0
- package/dist/ai/llm/factory.js.map +1 -0
- package/dist/ai/llm/litellm.d.ts +34 -0
- package/dist/ai/llm/litellm.d.ts.map +1 -0
- package/dist/ai/llm/litellm.js +45 -0
- package/dist/ai/llm/litellm.js.map +1 -0
- package/dist/ai/llm/openai.d.ts +145 -0
- package/dist/ai/llm/openai.d.ts.map +1 -0
- package/dist/ai/llm/openai.js +629 -0
- package/dist/ai/llm/openai.js.map +1 -0
- package/dist/ai/llm/orcarouter.d.ts +34 -0
- package/dist/ai/llm/orcarouter.d.ts.map +1 -0
- package/dist/ai/llm/orcarouter.js +45 -0
- package/dist/ai/llm/orcarouter.js.map +1 -0
- package/dist/ai/llm/recover-tool.d.ts +21 -0
- package/dist/ai/llm/recover-tool.d.ts.map +1 -0
- package/dist/ai/llm/recover-tool.js +109 -0
- package/dist/ai/llm/recover-tool.js.map +1 -0
- package/dist/ai/llm/types.d.ts +122 -0
- package/dist/ai/llm/types.d.ts.map +1 -0
- package/dist/ai/llm/types.js +33 -0
- package/dist/ai/llm/types.js.map +1 -0
- package/dist/ai/providers.d.ts +59 -0
- package/dist/ai/providers.d.ts.map +1 -0
- package/dist/ai/providers.js +54 -0
- package/dist/ai/providers.js.map +1 -0
- package/dist/ai/summarize.d.ts +25 -0
- package/dist/ai/summarize.d.ts.map +1 -0
- package/dist/ai/summarize.js +34 -0
- package/dist/ai/summarize.js.map +1 -0
- package/dist/ai/synthesize.d.ts +40 -0
- package/dist/ai/synthesize.d.ts.map +1 -0
- package/dist/ai/synthesize.js +230 -0
- package/dist/ai/synthesize.js.map +1 -0
- package/dist/ask/ask.d.ts +199 -0
- package/dist/ask/ask.d.ts.map +1 -0
- package/dist/ask/ask.js +1291 -0
- package/dist/ask/ask.js.map +1 -0
- package/dist/ask/file-rank.d.ts +72 -0
- package/dist/ask/file-rank.d.ts.map +1 -0
- package/dist/ask/file-rank.js +160 -0
- package/dist/ask/file-rank.js.map +1 -0
- package/dist/ask/file-selection.d.ts +22 -0
- package/dist/ask/file-selection.d.ts.map +1 -0
- package/dist/ask/file-selection.js +66 -0
- package/dist/ask/file-selection.js.map +1 -0
- package/dist/ask/fuse.d.ts +195 -0
- package/dist/ask/fuse.d.ts.map +1 -0
- package/dist/ask/fuse.js +344 -0
- package/dist/ask/fuse.js.map +1 -0
- package/dist/ask/graphrank.d.ts +61 -0
- package/dist/ask/graphrank.d.ts.map +1 -0
- package/dist/ask/graphrank.js +130 -0
- package/dist/ask/graphrank.js.map +1 -0
- package/dist/ask/index-file.d.ts +44 -0
- package/dist/ask/index-file.d.ts.map +1 -0
- package/dist/ask/index-file.js +128 -0
- package/dist/ask/index-file.js.map +1 -0
- package/dist/ask/semantic.d.ts +42 -0
- package/dist/ask/semantic.d.ts.map +1 -0
- package/dist/ask/semantic.js +293 -0
- package/dist/ask/semantic.js.map +1 -0
- package/dist/bin/graft.d.ts +3 -0
- package/dist/bin/graft.d.ts.map +1 -0
- package/dist/bin/graft.js +14 -0
- package/dist/bin/graft.js.map +1 -0
- package/dist/bin/trail.d.ts +3 -0
- package/dist/bin/trail.d.ts.map +1 -0
- package/dist/bin/trail.js +13 -0
- package/dist/bin/trail.js.map +1 -0
- package/dist/blast/blast-cli.d.ts +35 -0
- package/dist/blast/blast-cli.d.ts.map +1 -0
- package/dist/blast/blast-cli.js +155 -0
- package/dist/blast/blast-cli.js.map +1 -0
- package/dist/blast/blast.d.ts +128 -0
- package/dist/blast/blast.d.ts.map +1 -0
- package/dist/blast/blast.js +383 -0
- package/dist/blast/blast.js.map +1 -0
- package/dist/blast/diff.d.ts +53 -0
- package/dist/blast/diff.d.ts.map +1 -0
- package/dist/blast/diff.js +193 -0
- package/dist/blast/diff.js.map +1 -0
- package/dist/blast/evidence.d.ts +51 -0
- package/dist/blast/evidence.d.ts.map +1 -0
- package/dist/blast/evidence.js +162 -0
- package/dist/blast/evidence.js.map +1 -0
- package/dist/blast/modules.d.ts +33 -0
- package/dist/blast/modules.d.ts.map +1 -0
- package/dist/blast/modules.js +83 -0
- package/dist/blast/modules.js.map +1 -0
- package/dist/blast/name.d.ts +74 -0
- package/dist/blast/name.d.ts.map +1 -0
- package/dist/blast/name.js +269 -0
- package/dist/blast/name.js.map +1 -0
- package/dist/blast/owners.d.ts +85 -0
- package/dist/blast/owners.d.ts.map +1 -0
- package/dist/blast/owners.js +272 -0
- package/dist/blast/owners.js.map +1 -0
- package/dist/blast/render.d.ts +46 -0
- package/dist/blast/render.d.ts.map +1 -0
- package/dist/blast/render.js +422 -0
- package/dist/blast/render.js.map +1 -0
- package/dist/blast/viz.d.ts +37 -0
- package/dist/blast/viz.d.ts.map +1 -0
- package/dist/blast/viz.js +180 -0
- package/dist/blast/viz.js.map +1 -0
- package/dist/brand.d.ts +111 -0
- package/dist/brand.d.ts.map +1 -0
- package/dist/brand.js +282 -0
- package/dist/brand.js.map +1 -0
- package/dist/claude/build-progress.d.ts +30 -0
- package/dist/claude/build-progress.d.ts.map +1 -0
- package/dist/claude/build-progress.js +81 -0
- package/dist/claude/build-progress.js.map +1 -0
- package/dist/claude/hermes-skill-template.d.ts +16 -0
- package/dist/claude/hermes-skill-template.d.ts.map +1 -0
- package/dist/claude/hermes-skill-template.js +154 -0
- package/dist/claude/hermes-skill-template.js.map +1 -0
- package/dist/claude/init.d.ts +65 -0
- package/dist/claude/init.d.ts.map +1 -0
- package/dist/claude/init.js +258 -0
- package/dist/claude/init.js.map +1 -0
- package/dist/claude/paths.d.ts +9 -0
- package/dist/claude/paths.d.ts.map +1 -0
- package/dist/claude/paths.js +22 -0
- package/dist/claude/paths.js.map +1 -0
- package/dist/claude/session-metrics.d.ts +73 -0
- package/dist/claude/session-metrics.d.ts.map +1 -0
- package/dist/claude/session-metrics.js +209 -0
- package/dist/claude/session-metrics.js.map +1 -0
- package/dist/claude/settings-merge.d.ts +76 -0
- package/dist/claude/settings-merge.d.ts.map +1 -0
- package/dist/claude/settings-merge.js +283 -0
- package/dist/claude/settings-merge.js.map +1 -0
- package/dist/claude/skill-template.d.ts +13 -0
- package/dist/claude/skill-template.d.ts.map +1 -0
- package/dist/claude/skill-template.js +290 -0
- package/dist/claude/skill-template.js.map +1 -0
- package/dist/claude/state.d.ts +85 -0
- package/dist/claude/state.d.ts.map +1 -0
- package/dist/claude/state.js +88 -0
- package/dist/claude/state.js.map +1 -0
- package/dist/claude/stats.d.ts +5 -0
- package/dist/claude/stats.d.ts.map +1 -0
- package/dist/claude/stats.js +24 -0
- package/dist/claude/stats.js.map +1 -0
- package/dist/cli-epilogue.d.ts +12 -0
- package/dist/cli-epilogue.d.ts.map +1 -0
- package/dist/cli-epilogue.js +72 -0
- package/dist/cli-epilogue.js.map +1 -0
- package/dist/cli-meta.d.ts +82 -0
- package/dist/cli-meta.d.ts.map +1 -0
- package/dist/cli-meta.js +238 -0
- package/dist/cli-meta.js.map +1 -0
- package/dist/cli-picker.d.ts +139 -0
- package/dist/cli-picker.d.ts.map +1 -0
- package/dist/cli-picker.js +439 -0
- package/dist/cli-picker.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1638 -0
- package/dist/cli.js.map +1 -0
- package/dist/context/batches.d.ts +29 -0
- package/dist/context/batches.d.ts.map +1 -0
- package/dist/context/batches.js +130 -0
- package/dist/context/batches.js.map +1 -0
- package/dist/context/build.d.ts +57 -0
- package/dist/context/build.d.ts.map +1 -0
- package/dist/context/build.js +396 -0
- package/dist/context/build.js.map +1 -0
- package/dist/context/check.d.ts +42 -0
- package/dist/context/check.d.ts.map +1 -0
- package/dist/context/check.js +162 -0
- package/dist/context/check.js.map +1 -0
- package/dist/context/map-dir.d.ts +13 -0
- package/dist/context/map-dir.d.ts.map +1 -0
- package/dist/context/map-dir.js +81 -0
- package/dist/context/map-dir.js.map +1 -0
- package/dist/context/node-file.d.ts +109 -0
- package/dist/context/node-file.d.ts.map +1 -0
- package/dist/context/node-file.js +390 -0
- package/dist/context/node-file.js.map +1 -0
- package/dist/context/price.d.ts +49 -0
- package/dist/context/price.d.ts.map +1 -0
- package/dist/context/price.js +83 -0
- package/dist/context/price.js.map +1 -0
- package/dist/context/savings.d.ts +67 -0
- package/dist/context/savings.d.ts.map +1 -0
- package/dist/context/savings.js +125 -0
- package/dist/context/savings.js.map +1 -0
- package/dist/engine.d.ts +85 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +122 -0
- package/dist/engine.js.map +1 -0
- package/dist/graph/bindings.d.ts +64 -0
- package/dist/graph/bindings.d.ts.map +1 -0
- package/dist/graph/bindings.js +713 -0
- package/dist/graph/bindings.js.map +1 -0
- package/dist/graph/build-run.d.ts +25 -0
- package/dist/graph/build-run.d.ts.map +1 -0
- package/dist/graph/build-run.js +121 -0
- package/dist/graph/build-run.js.map +1 -0
- package/dist/graph/build.d.ts +88 -0
- package/dist/graph/build.d.ts.map +1 -0
- package/dist/graph/build.js +386 -0
- package/dist/graph/build.js.map +1 -0
- package/dist/graph/cards.d.ts +46 -0
- package/dist/graph/cards.d.ts.map +1 -0
- package/dist/graph/cards.js +280 -0
- package/dist/graph/cards.js.map +1 -0
- package/dist/graph/check.d.ts +25 -0
- package/dist/graph/check.d.ts.map +1 -0
- package/dist/graph/check.js +192 -0
- package/dist/graph/check.js.map +1 -0
- package/dist/graph/container.d.ts +63 -0
- package/dist/graph/container.d.ts.map +1 -0
- package/dist/graph/container.js +191 -0
- package/dist/graph/container.js.map +1 -0
- package/dist/graph/depth-parser.d.ts +61 -0
- package/dist/graph/depth-parser.d.ts.map +1 -0
- package/dist/graph/depth-parser.js +153 -0
- package/dist/graph/depth-parser.js.map +1 -0
- package/dist/graph/enrich.d.ts +62 -0
- package/dist/graph/enrich.d.ts.map +1 -0
- package/dist/graph/enrich.js +258 -0
- package/dist/graph/enrich.js.map +1 -0
- package/dist/graph/extract-cache.d.ts +101 -0
- package/dist/graph/extract-cache.d.ts.map +1 -0
- package/dist/graph/extract-cache.js +199 -0
- package/dist/graph/extract-cache.js.map +1 -0
- package/dist/graph/extract.d.ts +85 -0
- package/dist/graph/extract.d.ts.map +1 -0
- package/dist/graph/extract.js +2377 -0
- package/dist/graph/extract.js.map +1 -0
- package/dist/graph/fingerprint.d.ts +76 -0
- package/dist/graph/fingerprint.d.ts.map +1 -0
- package/dist/graph/fingerprint.js +160 -0
- package/dist/graph/fingerprint.js.map +1 -0
- package/dist/graph/generic.d.ts +74 -0
- package/dist/graph/generic.d.ts.map +1 -0
- package/dist/graph/generic.js +773 -0
- package/dist/graph/generic.js.map +1 -0
- package/dist/graph/invariants.d.ts +33 -0
- package/dist/graph/invariants.d.ts.map +1 -0
- package/dist/graph/invariants.js +52 -0
- package/dist/graph/invariants.js.map +1 -0
- package/dist/graph/load.d.ts +29 -0
- package/dist/graph/load.d.ts.map +1 -0
- package/dist/graph/load.js +97 -0
- package/dist/graph/load.js.map +1 -0
- package/dist/graph/lsp/client.d.ts +61 -0
- package/dist/graph/lsp/client.d.ts.map +1 -0
- package/dist/graph/lsp/client.js +217 -0
- package/dist/graph/lsp/client.js.map +1 -0
- package/dist/graph/lsp/enrich.d.ts +11 -0
- package/dist/graph/lsp/enrich.d.ts.map +1 -0
- package/dist/graph/lsp/enrich.js +163 -0
- package/dist/graph/lsp/enrich.js.map +1 -0
- package/dist/graph/lsp/registry.d.ts +22 -0
- package/dist/graph/lsp/registry.d.ts.map +1 -0
- package/dist/graph/lsp/registry.js +71 -0
- package/dist/graph/lsp/registry.js.map +1 -0
- package/dist/graph/map.d.ts +107 -0
- package/dist/graph/map.d.ts.map +1 -0
- package/dist/graph/map.js +239 -0
- package/dist/graph/map.js.map +1 -0
- package/dist/graph/markdown.d.ts +22 -0
- package/dist/graph/markdown.d.ts.map +1 -0
- package/dist/graph/markdown.js +143 -0
- package/dist/graph/markdown.js.map +1 -0
- package/dist/graph/native.d.ts +46 -0
- package/dist/graph/native.d.ts.map +1 -0
- package/dist/graph/native.js +169 -0
- package/dist/graph/native.js.map +1 -0
- package/dist/graph/queries/c.scm +13 -0
- package/dist/graph/queries/c_sharp.scm +19 -0
- package/dist/graph/queries/clojure.scm +58 -0
- package/dist/graph/queries/cpp.scm +23 -0
- package/dist/graph/queries/dart.scm +42 -0
- package/dist/graph/queries/elixir.scm +54 -0
- package/dist/graph/queries/gleam.scm +51 -0
- package/dist/graph/queries/java.scm +20 -0
- package/dist/graph/queries/kotlin.scm +43 -0
- package/dist/graph/queries/lua.scm +36 -0
- package/dist/graph/queries/nix.scm +32 -0
- package/dist/graph/queries/php.scm +40 -0
- package/dist/graph/queries/ruby.scm +65 -0
- package/dist/graph/queries/rust.scm +41 -0
- package/dist/graph/queries/scala.scm +66 -0
- package/dist/graph/queries/solidity.scm +43 -0
- package/dist/graph/queries/swift.scm +51 -0
- package/dist/graph/refresh.d.ts +106 -0
- package/dist/graph/refresh.d.ts.map +1 -0
- package/dist/graph/refresh.js +430 -0
- package/dist/graph/refresh.js.map +1 -0
- package/dist/graph/relations.d.ts +14 -0
- package/dist/graph/relations.d.ts.map +1 -0
- package/dist/graph/relations.js +8 -0
- package/dist/graph/relations.js.map +1 -0
- package/dist/graph/resolve.d.ts +17 -0
- package/dist/graph/resolve.d.ts.map +1 -0
- package/dist/graph/resolve.js +716 -0
- package/dist/graph/resolve.js.map +1 -0
- package/dist/graph/root.d.ts +11 -0
- package/dist/graph/root.d.ts.map +1 -0
- package/dist/graph/root.js +40 -0
- package/dist/graph/root.js.map +1 -0
- package/dist/graph/scopes.d.ts +40 -0
- package/dist/graph/scopes.d.ts.map +1 -0
- package/dist/graph/scopes.js +383 -0
- package/dist/graph/scopes.js.map +1 -0
- package/dist/graph/seed.d.ts +38 -0
- package/dist/graph/seed.d.ts.map +1 -0
- package/dist/graph/seed.js +229 -0
- package/dist/graph/seed.js.map +1 -0
- package/dist/graph/source-files.d.ts +46 -0
- package/dist/graph/source-files.d.ts.map +1 -0
- package/dist/graph/source-files.js +118 -0
- package/dist/graph/source-files.js.map +1 -0
- package/dist/graph/traverse-cli.d.ts +55 -0
- package/dist/graph/traverse-cli.d.ts.map +1 -0
- package/dist/graph/traverse-cli.js +189 -0
- package/dist/graph/traverse-cli.js.map +1 -0
- package/dist/graph/traverse.d.ts +112 -0
- package/dist/graph/traverse.d.ts.map +1 -0
- package/dist/graph/traverse.js +192 -0
- package/dist/graph/traverse.js.map +1 -0
- package/dist/graph/types.d.ts +78 -0
- package/dist/graph/types.d.ts.map +1 -0
- package/dist/graph/types.js +14 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/graph/wasm-runtime.d.ts +19 -0
- package/dist/graph/wasm-runtime.d.ts.map +1 -0
- package/dist/graph/wasm-runtime.js +38 -0
- package/dist/graph/wasm-runtime.js.map +1 -0
- package/dist/graph/workspace-cli.d.ts +56 -0
- package/dist/graph/workspace-cli.d.ts.map +1 -0
- package/dist/graph/workspace-cli.js +111 -0
- package/dist/graph/workspace-cli.js.map +1 -0
- package/dist/graph/workspace.d.ts +172 -0
- package/dist/graph/workspace.d.ts.map +1 -0
- package/dist/graph/workspace.js +714 -0
- package/dist/graph/workspace.js.map +1 -0
- package/dist/graph/write.d.ts +13 -0
- package/dist/graph/write.d.ts.map +1 -0
- package/dist/graph/write.js +86 -0
- package/dist/graph/write.js.map +1 -0
- package/dist/hosts/antigravity.d.ts +14 -0
- package/dist/hosts/antigravity.d.ts.map +1 -0
- package/dist/hosts/antigravity.js +59 -0
- package/dist/hosts/antigravity.js.map +1 -0
- package/dist/hosts/auto.d.ts +37 -0
- package/dist/hosts/auto.d.ts.map +1 -0
- package/dist/hosts/auto.js +141 -0
- package/dist/hosts/auto.js.map +1 -0
- package/dist/hosts/claude-global.d.ts +72 -0
- package/dist/hosts/claude-global.d.ts.map +1 -0
- package/dist/hosts/claude-global.js +230 -0
- package/dist/hosts/claude-global.js.map +1 -0
- package/dist/hosts/config-write.d.ts +36 -0
- package/dist/hosts/config-write.d.ts.map +1 -0
- package/dist/hosts/config-write.js +64 -0
- package/dist/hosts/config-write.js.map +1 -0
- package/dist/hosts/init.d.ts +28 -0
- package/dist/hosts/init.d.ts.map +1 -0
- package/dist/hosts/init.js +89 -0
- package/dist/hosts/init.js.map +1 -0
- package/dist/hosts/instructions.d.ts +14 -0
- package/dist/hosts/instructions.d.ts.map +1 -0
- package/dist/hosts/instructions.js +95 -0
- package/dist/hosts/instructions.js.map +1 -0
- package/dist/hosts/mcp-config.d.ts +78 -0
- package/dist/hosts/mcp-config.d.ts.map +1 -0
- package/dist/hosts/mcp-config.js +251 -0
- package/dist/hosts/mcp-config.js.map +1 -0
- package/dist/hosts/plan.d.ts +32 -0
- package/dist/hosts/plan.d.ts.map +1 -0
- package/dist/hosts/plan.js +73 -0
- package/dist/hosts/plan.js.map +1 -0
- package/dist/hosts/registry.d.ts +41 -0
- package/dist/hosts/registry.d.ts.map +1 -0
- package/dist/hosts/registry.js +164 -0
- package/dist/hosts/registry.js.map +1 -0
- package/dist/hosts/retract.d.ts +47 -0
- package/dist/hosts/retract.d.ts.map +1 -0
- package/dist/hosts/retract.js +520 -0
- package/dist/hosts/retract.js.map +1 -0
- package/dist/hosts/sections.d.ts +47 -0
- package/dist/hosts/sections.d.ts.map +1 -0
- package/dist/hosts/sections.js +127 -0
- package/dist/hosts/sections.js.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/ingest/fs.d.ts +79 -0
- package/dist/ingest/fs.d.ts.map +1 -0
- package/dist/ingest/fs.js +306 -0
- package/dist/ingest/fs.js.map +1 -0
- package/dist/init-guard.d.ts +16 -0
- package/dist/init-guard.d.ts.map +1 -0
- package/dist/init-guard.js +27 -0
- package/dist/init-guard.js.map +1 -0
- package/dist/mcp/instructions.d.ts +5 -0
- package/dist/mcp/instructions.d.ts.map +1 -0
- package/dist/mcp/instructions.js +64 -0
- package/dist/mcp/instructions.js.map +1 -0
- package/dist/mcp/kept-listing.d.ts +27 -0
- package/dist/mcp/kept-listing.d.ts.map +1 -0
- package/dist/mcp/kept-listing.js +63 -0
- package/dist/mcp/kept-listing.js.map +1 -0
- package/dist/mcp/server.d.ts +4 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +147 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tool-names.d.ts +27 -0
- package/dist/mcp/tool-names.d.ts.map +1 -0
- package/dist/mcp/tool-names.js +47 -0
- package/dist/mcp/tool-names.js.map +1 -0
- package/dist/mcp/tools.d.ts +22 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +440 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/node-version.d.ts +15 -0
- package/dist/node-version.d.ts.map +1 -0
- package/dist/node-version.js +23 -0
- package/dist/node-version.js.map +1 -0
- package/dist/search/grep-cli.d.ts +35 -0
- package/dist/search/grep-cli.d.ts.map +1 -0
- package/dist/search/grep-cli.js +115 -0
- package/dist/search/grep-cli.js.map +1 -0
- package/dist/search/grep.d.ts +60 -0
- package/dist/search/grep.d.ts.map +1 -0
- package/dist/search/grep.js +143 -0
- package/dist/search/grep.js.map +1 -0
- package/dist/search/ignored-code.d.ts +9 -0
- package/dist/search/ignored-code.d.ts.map +1 -0
- package/dist/search/ignored-code.js +73 -0
- package/dist/search/ignored-code.js.map +1 -0
- package/dist/search/user-regexp.d.ts +26 -0
- package/dist/search/user-regexp.d.ts.map +1 -0
- package/dist/search/user-regexp.js +150 -0
- package/dist/search/user-regexp.js.map +1 -0
- package/dist/telemetry/contract.d.ts +117 -0
- package/dist/telemetry/contract.d.ts.map +1 -0
- package/dist/telemetry/contract.js +341 -0
- package/dist/telemetry/contract.js.map +1 -0
- package/dist/telemetry/flush.d.ts +21 -0
- package/dist/telemetry/flush.d.ts.map +1 -0
- package/dist/telemetry/flush.js +85 -0
- package/dist/telemetry/flush.js.map +1 -0
- package/dist/telemetry/gate.d.ts +30 -0
- package/dist/telemetry/gate.d.ts.map +1 -0
- package/dist/telemetry/gate.js +81 -0
- package/dist/telemetry/gate.js.map +1 -0
- package/dist/telemetry/identity.d.ts +40 -0
- package/dist/telemetry/identity.d.ts.map +1 -0
- package/dist/telemetry/identity.js +80 -0
- package/dist/telemetry/identity.js.map +1 -0
- package/dist/telemetry/index.d.ts +18 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +16 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/key.d.ts +21 -0
- package/dist/telemetry/key.d.ts.map +1 -0
- package/dist/telemetry/key.js +49 -0
- package/dist/telemetry/key.js.map +1 -0
- package/dist/telemetry/notice.d.ts +19 -0
- package/dist/telemetry/notice.d.ts.map +1 -0
- package/dist/telemetry/notice.js +93 -0
- package/dist/telemetry/notice.js.map +1 -0
- package/dist/telemetry/queue.d.ts +35 -0
- package/dist/telemetry/queue.d.ts.map +1 -0
- package/dist/telemetry/queue.js +162 -0
- package/dist/telemetry/queue.js.map +1 -0
- package/dist/telemetry/send.d.ts +19 -0
- package/dist/telemetry/send.d.ts.map +1 -0
- package/dist/telemetry/send.js +84 -0
- package/dist/telemetry/send.js.map +1 -0
- package/dist/telemetry/sessions.d.ts +25 -0
- package/dist/telemetry/sessions.d.ts.map +1 -0
- package/dist/telemetry/sessions.js +104 -0
- package/dist/telemetry/sessions.js.map +1 -0
- package/dist/telemetry/track.d.ts +62 -0
- package/dist/telemetry/track.d.ts.map +1 -0
- package/dist/telemetry/track.js +143 -0
- package/dist/telemetry/track.js.map +1 -0
- package/dist/upkeep-run.d.ts +22 -0
- package/dist/upkeep-run.d.ts.map +1 -0
- package/dist/upkeep-run.js +85 -0
- package/dist/upkeep-run.js.map +1 -0
- package/dist/upkeep.d.ts +127 -0
- package/dist/upkeep.d.ts.map +1 -0
- package/dist/upkeep.js +252 -0
- package/dist/upkeep.js.map +1 -0
- package/dist/util/actions-folder.d.ts +2 -0
- package/dist/util/actions-folder.d.ts.map +1 -0
- package/dist/util/actions-folder.js +9 -0
- package/dist/util/actions-folder.js.map +1 -0
- package/dist/util/browser.d.ts +3 -0
- package/dist/util/browser.d.ts.map +1 -0
- package/dist/util/browser.js +14 -0
- package/dist/util/browser.js.map +1 -0
- package/dist/util/child-process.d.ts +15 -0
- package/dist/util/child-process.d.ts.map +1 -0
- package/dist/util/child-process.js +15 -0
- package/dist/util/child-process.js.map +1 -0
- package/dist/util/front-matter.d.ts +46 -0
- package/dist/util/front-matter.d.ts.map +1 -0
- package/dist/util/front-matter.js +113 -0
- package/dist/util/front-matter.js.map +1 -0
- package/dist/util/id.d.ts +7 -0
- package/dist/util/id.d.ts.map +1 -0
- package/dist/util/id.js +14 -0
- package/dist/util/id.js.map +1 -0
- package/dist/util/paths.d.ts +29 -0
- package/dist/util/paths.d.ts.map +1 -0
- package/dist/util/paths.js +71 -0
- package/dist/util/paths.js.map +1 -0
- package/dist/util/private-file.d.ts +14 -0
- package/dist/util/private-file.d.ts.map +1 -0
- package/dist/util/private-file.js +82 -0
- package/dist/util/private-file.js.map +1 -0
- package/dist/util/source.d.ts +4 -0
- package/dist/util/source.d.ts.map +1 -0
- package/dist/util/source.js +12 -0
- package/dist/util/source.js.map +1 -0
- package/dist/util/spinner.d.ts +15 -0
- package/dist/util/spinner.d.ts.map +1 -0
- package/dist/util/spinner.js +52 -0
- package/dist/util/spinner.js.map +1 -0
- package/dist/util/state.d.ts +120 -0
- package/dist/util/state.d.ts.map +1 -0
- package/dist/util/state.js +264 -0
- package/dist/util/state.js.map +1 -0
- package/dist/vendor/grammars/tree-sitter-go.LICENSE +21 -0
- package/dist/vendor/grammars/tree-sitter-go.wasm +0 -0
- package/dist/vendor/grammars/tree-sitter-java.LICENSE +21 -0
- package/dist/vendor/grammars/tree-sitter-java.wasm +0 -0
- package/dist/vendor/grammars/tree-sitter-kotlin.LICENSE +9 -0
- package/dist/vendor/grammars/tree-sitter-kotlin.wasm +0 -0
- package/dist/vendor/grammars/tree-sitter-php.LICENSE +22 -0
- package/dist/vendor/grammars/tree-sitter-php.wasm +0 -0
- package/dist/vendor/grammars/tree-sitter-python.LICENSE +21 -0
- package/dist/vendor/grammars/tree-sitter-python.wasm +0 -0
- package/dist/vendor/grammars/tree-sitter-r.LICENSE +9 -0
- package/dist/vendor/grammars/tree-sitter-r.wasm +0 -0
- package/dist/vendor/grammars/tree-sitter-swift.LICENSE +21 -0
- package/dist/vendor/grammars/tree-sitter-swift.wasm +0 -0
- package/dist/vendor/grammars/tree-sitter-tsx.wasm +0 -0
- package/dist/vendor/grammars/tree-sitter-typescript.LICENSE +21 -0
- package/dist/vendor/grammars/tree-sitter-typescript.wasm +0 -0
- package/dist/viewer/app.js +2 -0
- package/dist/viewer/index.html +49 -0
- package/dist/viewer/style.css +154 -0
- package/dist/viz/assemble.d.ts +83 -0
- package/dist/viz/assemble.d.ts.map +1 -0
- package/dist/viz/assemble.js +101 -0
- package/dist/viz/assemble.js.map +1 -0
- package/dist/viz/export.d.ts +39 -0
- package/dist/viz/export.d.ts.map +1 -0
- package/dist/viz/export.js +98 -0
- package/dist/viz/export.js.map +1 -0
- package/dist/viz/serve.d.ts +13 -0
- package/dist/viz/serve.d.ts.map +1 -0
- package/dist/viz/serve.js +130 -0
- package/dist/viz/serve.js.map +1 -0
- package/package.json +115 -4
- package/scripts/build-grammar-wasm.mjs +112 -0
- package/scripts/build-viewer.mjs +44 -0
- package/scripts/graph-quality.mjs +117 -0
- package/scripts/pack-trail.mjs +53 -0
- package/scripts/postinstall.mjs +65 -0
- package/scripts/run-tests.mjs +72 -0
- package/scripts/stamp-telemetry-key.mjs +56 -0
- package/scripts/tally-audit.mjs +140 -0
- package/scripts/vendor-grammars.mjs +53 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scope-aware ranking for `graft ask`. Pure functions, no fs.
|
|
3
|
+
*
|
|
4
|
+
* The problem: lexical + graph scores are corpus-relative. In a multi-scope
|
|
5
|
+
* repo (a monorepo's `frontend/` + `backend/`, sub-projects under one root),
|
|
6
|
+
* scoring every node against one pooled corpus lets the biggest sub-project set
|
|
7
|
+
* the score scale and drown the small one.
|
|
8
|
+
*
|
|
9
|
+
* This module solves it by keeping the scope PARTITION — each scope is scored
|
|
10
|
+
* and walked separately — while making the resulting scores COMPARABLE, so the
|
|
11
|
+
* combined order can be read straight off the score. Comparability has two
|
|
12
|
+
* requirements, and both must hold or the order is meaningless:
|
|
13
|
+
*
|
|
14
|
+
* 1. shared corpus statistics — the caller scores every scope against the
|
|
15
|
+
* repo-wide IDF and length prior (see `ask.ts`), so the same term is worth
|
|
16
|
+
* the same everywhere;
|
|
17
|
+
* 2. a shared normalization denominator — {@link rankScopesAndFuse} divides
|
|
18
|
+
* every scope by the best raw score in the REPO, not by each scope's own
|
|
19
|
+
* best (see `globalMaxLex` there).
|
|
20
|
+
*
|
|
21
|
+
* Issue #117 was the consequence of neither holding. Each scope divided by its
|
|
22
|
+
* own maximum, so a barely-relevant scope's top hit normalized to ~1.0 exactly
|
|
23
|
+
* like the genuinely relevant scope's top hit; RRF then fused by RANK, which
|
|
24
|
+
* discards magnitude outright, so the weak scope's rank-1 tied the strong
|
|
25
|
+
* scope's rank-1 and displaced its rank-2 — frequently the answer. Measurement
|
|
26
|
+
* across four repositories and four ecosystems put 73% of missed files in that
|
|
27
|
+
* bucket. RRF is retained for `federateAsk` (see `graph/workspace.ts`), where
|
|
28
|
+
* the corpora really are separate repositories and no shared denominator
|
|
29
|
+
* exists — that is the case rank fusion is for.
|
|
30
|
+
*
|
|
31
|
+
* Soft federation: a scope whose top hit is probably an incidental word
|
|
32
|
+
* collision, not a second home for the query, is left out of the combined order
|
|
33
|
+
* and reported in `alsoMatched` instead, so the output can say "also matched:
|
|
34
|
+
* docs/ — narrow with --in docs/" rather than diluting the pack. With
|
|
35
|
+
* comparable scores that gate is simply {@link PARTICIPATION_RATIO} — a scope
|
|
36
|
+
* must reach a real share of the best score anywhere in the repo. Under
|
|
37
|
+
* per-scope normalization that check was vacuous (every scope's top was ~1.0),
|
|
38
|
+
* which is why a separate match-STRENGTH gate ({@link STRONG_FLOOR}/{@link
|
|
39
|
+
* HIGH_FLOOR}) had to stand in for it; that signal is still exported and still
|
|
40
|
+
* used by `federateAsk`, which normalizes per child repo and therefore still
|
|
41
|
+
* needs it.
|
|
42
|
+
*/
|
|
43
|
+
/** One scored document, attributed to the ranking scope (path prefix, "" =
|
|
44
|
+
* root) it was scored within. Scores must be per-scope-normalized (each
|
|
45
|
+
* scope's best ≈ its own ceiling) — fusion compares ranks, not raw scores. */
|
|
46
|
+
export interface ScopedDoc {
|
|
47
|
+
id: string;
|
|
48
|
+
scope: string;
|
|
49
|
+
score: number;
|
|
50
|
+
}
|
|
51
|
+
/** Components preserved until immediately before comparable-scope combination.
|
|
52
|
+
* Optional ranking experiments can adjust lexical evidence without having to
|
|
53
|
+
* reconstruct it from the already blended scalar score. */
|
|
54
|
+
export interface ScopeRankCandidate extends ScopedDoc {
|
|
55
|
+
/** Repo-global-normalized lexical component. */
|
|
56
|
+
lexical: number;
|
|
57
|
+
/** Scope-local normalized PPR component. */
|
|
58
|
+
graph: number;
|
|
59
|
+
/** Query-aware final multiplier, such as test-file de-ranking. */
|
|
60
|
+
rankFactor: number;
|
|
61
|
+
}
|
|
62
|
+
export interface FusionResult {
|
|
63
|
+
/** fused order, best first; carries per-doc scope label + fused score.
|
|
64
|
+
* Normalized so the top MULTI-scope fused doc is 1 — but the single-scoring-
|
|
65
|
+
* scope degenerate case passes ORIGINAL (pre-fusion) scores through
|
|
66
|
+
* unchanged, and those are not guaranteed to fall in [0,1]. */
|
|
67
|
+
ranked: {
|
|
68
|
+
id: string;
|
|
69
|
+
scope: string;
|
|
70
|
+
score: number;
|
|
71
|
+
}[];
|
|
72
|
+
/** scopes that participated in fusion */
|
|
73
|
+
federated: string[];
|
|
74
|
+
/** scopes that matched weakly (≥1 scoring doc but below the participation gate) with their best doc */
|
|
75
|
+
alsoMatched: {
|
|
76
|
+
scope: string;
|
|
77
|
+
bestId: string;
|
|
78
|
+
}[];
|
|
79
|
+
}
|
|
80
|
+
/** RRF smoothing constant — the standard value from the original RRF paper;
|
|
81
|
+
* high enough that rank 1 vs 2 differ gently rather than by 2×. */
|
|
82
|
+
export declare const RRF_K = 60;
|
|
83
|
+
/** A scope federates only when its best doc scores at least this share of the
|
|
84
|
+
* global best — below it the match is reported, not fused. Used by
|
|
85
|
+
* `fuseScopes`'s own internal gate (a post-normalization safety net once a
|
|
86
|
+
* caller has already applied the real match-strength gate — see
|
|
87
|
+
* {@link STRONG_FLOOR}/{@link HIGH_FLOOR}). */
|
|
88
|
+
export declare const PARTICIPATION_RATIO = 0.25;
|
|
89
|
+
/** The single source of truth for the cross-scope participation gate shared
|
|
90
|
+
* by `rankScopesAndFuse` (single-graph multi-scope) and `federateAsk`
|
|
91
|
+
* (workspace federation, `src/graph/workspace.ts`) — the two paths that solve
|
|
92
|
+
* the identical "a weak scope must not federate beside a strong one" problem.
|
|
93
|
+
* They MUST use the same floors so they can never drift into inconsistent
|
|
94
|
+
* behavior again.
|
|
95
|
+
*
|
|
96
|
+
* A scope federates iff its top hit matched a query term in a NAME/PATH field
|
|
97
|
+
* at all (any strength ≥ `STRONG_FLOOR`) — the primary gate. Well below every
|
|
98
|
+
* genuine fixture (≥0.45) yet strictly above a body-only collision's 0, so a
|
|
99
|
+
* real partial-relevance hit on a common/low-idf term is never overcorrected
|
|
100
|
+
* out. */
|
|
101
|
+
export declare const STRONG_FLOOR = 0.1;
|
|
102
|
+
/** …OR the overall (name+path+body) coverage is broad enough to be real even
|
|
103
|
+
* body-only. A single incidental body-token collision measures ~0.29 and RISES
|
|
104
|
+
* with corpus size (0.30+ at 200 nodes) but never approaches this, while a
|
|
105
|
+
* genuinely broad match clears it. This is why the gate is on absolute,
|
|
106
|
+
* scale-invariant floors, NOT a raw-lexical-score ratio (which — calibrated for
|
|
107
|
+
* raw-lexical-SCORE space — was far too lenient in coverage/matched-fraction
|
|
108
|
+
* space and leaked junk, worsening as the corpus grew). */
|
|
109
|
+
export declare const HIGH_FLOOR = 0.5;
|
|
110
|
+
/**
|
|
111
|
+
* Partition by scope, rank within scope (input scores are already
|
|
112
|
+
* per-scope-normalized), gate by soft federation, fuse by RRF:
|
|
113
|
+
* `fused(id) = Σ 1/(K + rank_in_scope(id))`, then normalized so the top fused
|
|
114
|
+
* doc is 1. Non-scoring docs (score ≤ 0) are dropped entirely.
|
|
115
|
+
*
|
|
116
|
+
* Degenerate cases degrade to current behavior: zero scoring docs → empty
|
|
117
|
+
* result; exactly one scoring scope → its docs pass through in score order
|
|
118
|
+
* with their ORIGINAL scores (no RRF re-scoring, no gate) — byte-for-byte the
|
|
119
|
+
* single-corpus ranking the caller would have produced anyway.
|
|
120
|
+
*/
|
|
121
|
+
export declare function fuseScopes(docs: ScopedDoc[]): FusionResult;
|
|
122
|
+
/**
|
|
123
|
+
* Combine scopes whose scores are ALREADY comparable (shared corpus statistics
|
|
124
|
+
* and a shared normalization denominator — see the module header). Same shape
|
|
125
|
+
* and same gate as {@link fuseScopes}, but the combined order is read straight
|
|
126
|
+
* off the score instead of from reciprocal rank, because with a common scale
|
|
127
|
+
* the magnitude is exactly the signal rank fusion would throw away.
|
|
128
|
+
*
|
|
129
|
+
* Only {@link rankScopesAndFuse} may call this. `federateAsk` fuses separate
|
|
130
|
+
* repositories, which have no common denominator, and must keep using
|
|
131
|
+
* {@link fuseScopes}.
|
|
132
|
+
*/
|
|
133
|
+
export declare function combineComparableScopes(docs: ScopedDoc[]): FusionResult;
|
|
134
|
+
/** The per-scope scoring hooks `rankScopesAndFuse` drives — the caller owns
|
|
135
|
+
* the actual lexical math and graph walk (they need its corpus state); this
|
|
136
|
+
* module owns the orchestration so the shape of "rank per scope, then fuse"
|
|
137
|
+
* lives in one place. */
|
|
138
|
+
export interface ScopeRankOps {
|
|
139
|
+
/** Lexical scores for the scope's own docs (positive entries only), computed
|
|
140
|
+
* against the REPO-WIDE corpus statistics. Per-scope statistics would make
|
|
141
|
+
* the returned numbers incomparable between scopes, which is exactly the
|
|
142
|
+
* defect in #117 — see the module header. */
|
|
143
|
+
lex(scope: string): Map<string, number>;
|
|
144
|
+
/** Does ANY scoring doc in this scope match a query term in its NAME or PATH?
|
|
145
|
+
*
|
|
146
|
+
* Serves ONE narrow purpose: suppressing a scope whose entire claim on the
|
|
147
|
+
* query is prose. Score cannot catch that on its own — BM25 rewards a term
|
|
148
|
+
* repeated in comments, so a file mentioning "gateway" thirty times in a
|
|
149
|
+
* banner can outscore the class actually named `GatewayTimeout`.
|
|
150
|
+
*
|
|
151
|
+
* Deliberately evaluated over the whole scope, not just its top hit, and as a
|
|
152
|
+
* presence check rather than a share threshold. Both choices are load-bearing:
|
|
153
|
+
* a share of the whole query is unreachable for long queries (which is how the
|
|
154
|
+
* old gate ended up admitting one scope and hiding the rest), and judging a
|
|
155
|
+
* scope by its single best doc suppressed any scope whose top hit was a file
|
|
156
|
+
* node — measured at 7.6 points of pooled R@10. */
|
|
157
|
+
hasIdentifierMatch?(scope: string): boolean;
|
|
158
|
+
/** Graph walk restricted to the scope's subgraph, seeded by that scope's
|
|
159
|
+
* lexical scores; returns top-normalized centrality (or an empty map). */
|
|
160
|
+
walk(scope: string, seeds: Map<string, number>): Map<string, number>;
|
|
161
|
+
/** Optional query-aware multiplier applied after lexical normalization and
|
|
162
|
+
* graph blending. Use this for priors (such as test-file de-ranking) that
|
|
163
|
+
* normalization must not erase. */
|
|
164
|
+
rankFactor?(scope: string, id: string): number;
|
|
165
|
+
/** Optional candidate collapse after lexical + graph components are known
|
|
166
|
+
* but before comparable scopes are gated and combined. File-aware ranking uses this
|
|
167
|
+
* to supply exactly one real representative per file. The default path omits
|
|
168
|
+
* the hook and remains byte-identical. */
|
|
169
|
+
collapseCandidates?(candidates: readonly ScopeRankCandidate[]): readonly ScopedDoc[];
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Multi-scope orchestration for `ask`'s symbol ranking: for each scope, score
|
|
173
|
+
* lexically (against the repo-wide statistics the caller supplies), walk the
|
|
174
|
+
* scope's subgraph, blend exactly like the single-scope path (`lexN +
|
|
175
|
+
* graphWeight·pr`, walk-rescued nodes joining above `rescueFloor`), then
|
|
176
|
+
* combine the scopes with {@link combineComparableScopes}. A scope with zero
|
|
177
|
+
* lexical matches contributes nothing (no seeds → no walk → no docs).
|
|
178
|
+
*
|
|
179
|
+
* The one thing that differs from the single-scope path: `lexN` divides by
|
|
180
|
+
* `globalMaxLex`, the best raw lexical score across ALL scopes, rather than by
|
|
181
|
+
* each scope's own best. That shared denominator is what makes the blended
|
|
182
|
+
* scores comparable, and therefore what lets the combined order be read off the
|
|
183
|
+
* score. Dividing per scope — as this did before #117 — pinned every scope's
|
|
184
|
+
* top hit to ~1.0 regardless of how well it matched, which is the defect.
|
|
185
|
+
*
|
|
186
|
+
* Participation is then the {@link PARTICIPATION_RATIO} share check inside
|
|
187
|
+
* {@link combineComparableScopes}: a scope must reach a real fraction of the
|
|
188
|
+
* best score anywhere in the repo, else it is reported in `alsoMatched` for
|
|
189
|
+
* `--in`. The match-STRENGTH floors ({@link STRONG_FLOOR}/{@link HIGH_FLOOR})
|
|
190
|
+
* are no longer applied here — they existed to stand in for a share check that
|
|
191
|
+
* per-scope normalization had made vacuous. `federateAsk` still normalizes per
|
|
192
|
+
* child repo, so it still gates on strength; see `src/graph/workspace.ts`.
|
|
193
|
+
*/
|
|
194
|
+
export declare function rankScopesAndFuse(scopes: string[], ops: ScopeRankOps, graphWeight: number, rescueFloor: number): FusionResult;
|
|
195
|
+
//# sourceMappingURL=fuse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fuse.d.ts","sourceRoot":"","sources":["../../src/ask/fuse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH;;8EAE8E;AAC9E,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;2DAE2D;AAC3D,MAAM,WAAW,kBAAmB,SAAQ,SAAS;IACnD,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B;;;mEAG+D;IAC/D,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvD,yCAAyC;IACzC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,uGAAuG;IACvG,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAClD;AAED;mEACmE;AACnE,eAAO,MAAM,KAAK,KAAK,CAAC;AAExB;;;;+CAI+C;AAC/C,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAExC;;;;;;;;;;;UAWU;AACV,eAAO,MAAM,YAAY,MAAM,CAAC;AAChC;;;;;;2DAM2D;AAC3D,eAAO,MAAM,UAAU,MAAM,CAAC;AAQ9B;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,YAAY,CA+D1D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,YAAY,CAyDvE;AAED;;;yBAGyB;AACzB,MAAM,WAAW,YAAY;IAC3B;;;iDAG6C;IAC7C,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC;;;;;;;;;;;;uDAYmD;IACnD,kBAAkB,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5C;8EAC0E;IAC1E,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrE;;uCAEmC;IACnC,UAAU,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/C;;;8CAG0C;IAC1C,kBAAkB,CAAC,CACjB,UAAU,EAAE,SAAS,kBAAkB,EAAE,GACxC,SAAS,SAAS,EAAE,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EAAE,EAChB,GAAG,EAAE,YAAY,EACjB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,YAAY,CAqFd"}
|
package/dist/ask/fuse.js
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scope-aware ranking for `graft ask`. Pure functions, no fs.
|
|
3
|
+
*
|
|
4
|
+
* The problem: lexical + graph scores are corpus-relative. In a multi-scope
|
|
5
|
+
* repo (a monorepo's `frontend/` + `backend/`, sub-projects under one root),
|
|
6
|
+
* scoring every node against one pooled corpus lets the biggest sub-project set
|
|
7
|
+
* the score scale and drown the small one.
|
|
8
|
+
*
|
|
9
|
+
* This module solves it by keeping the scope PARTITION — each scope is scored
|
|
10
|
+
* and walked separately — while making the resulting scores COMPARABLE, so the
|
|
11
|
+
* combined order can be read straight off the score. Comparability has two
|
|
12
|
+
* requirements, and both must hold or the order is meaningless:
|
|
13
|
+
*
|
|
14
|
+
* 1. shared corpus statistics — the caller scores every scope against the
|
|
15
|
+
* repo-wide IDF and length prior (see `ask.ts`), so the same term is worth
|
|
16
|
+
* the same everywhere;
|
|
17
|
+
* 2. a shared normalization denominator — {@link rankScopesAndFuse} divides
|
|
18
|
+
* every scope by the best raw score in the REPO, not by each scope's own
|
|
19
|
+
* best (see `globalMaxLex` there).
|
|
20
|
+
*
|
|
21
|
+
* Issue #117 was the consequence of neither holding. Each scope divided by its
|
|
22
|
+
* own maximum, so a barely-relevant scope's top hit normalized to ~1.0 exactly
|
|
23
|
+
* like the genuinely relevant scope's top hit; RRF then fused by RANK, which
|
|
24
|
+
* discards magnitude outright, so the weak scope's rank-1 tied the strong
|
|
25
|
+
* scope's rank-1 and displaced its rank-2 — frequently the answer. Measurement
|
|
26
|
+
* across four repositories and four ecosystems put 73% of missed files in that
|
|
27
|
+
* bucket. RRF is retained for `federateAsk` (see `graph/workspace.ts`), where
|
|
28
|
+
* the corpora really are separate repositories and no shared denominator
|
|
29
|
+
* exists — that is the case rank fusion is for.
|
|
30
|
+
*
|
|
31
|
+
* Soft federation: a scope whose top hit is probably an incidental word
|
|
32
|
+
* collision, not a second home for the query, is left out of the combined order
|
|
33
|
+
* and reported in `alsoMatched` instead, so the output can say "also matched:
|
|
34
|
+
* docs/ — narrow with --in docs/" rather than diluting the pack. With
|
|
35
|
+
* comparable scores that gate is simply {@link PARTICIPATION_RATIO} — a scope
|
|
36
|
+
* must reach a real share of the best score anywhere in the repo. Under
|
|
37
|
+
* per-scope normalization that check was vacuous (every scope's top was ~1.0),
|
|
38
|
+
* which is why a separate match-STRENGTH gate ({@link STRONG_FLOOR}/{@link
|
|
39
|
+
* HIGH_FLOOR}) had to stand in for it; that signal is still exported and still
|
|
40
|
+
* used by `federateAsk`, which normalizes per child repo and therefore still
|
|
41
|
+
* needs it.
|
|
42
|
+
*/
|
|
43
|
+
/** RRF smoothing constant — the standard value from the original RRF paper;
|
|
44
|
+
* high enough that rank 1 vs 2 differ gently rather than by 2×. */
|
|
45
|
+
export const RRF_K = 60;
|
|
46
|
+
/** A scope federates only when its best doc scores at least this share of the
|
|
47
|
+
* global best — below it the match is reported, not fused. Used by
|
|
48
|
+
* `fuseScopes`'s own internal gate (a post-normalization safety net once a
|
|
49
|
+
* caller has already applied the real match-strength gate — see
|
|
50
|
+
* {@link STRONG_FLOOR}/{@link HIGH_FLOOR}). */
|
|
51
|
+
export const PARTICIPATION_RATIO = 0.25;
|
|
52
|
+
/** The single source of truth for the cross-scope participation gate shared
|
|
53
|
+
* by `rankScopesAndFuse` (single-graph multi-scope) and `federateAsk`
|
|
54
|
+
* (workspace federation, `src/graph/workspace.ts`) — the two paths that solve
|
|
55
|
+
* the identical "a weak scope must not federate beside a strong one" problem.
|
|
56
|
+
* They MUST use the same floors so they can never drift into inconsistent
|
|
57
|
+
* behavior again.
|
|
58
|
+
*
|
|
59
|
+
* A scope federates iff its top hit matched a query term in a NAME/PATH field
|
|
60
|
+
* at all (any strength ≥ `STRONG_FLOOR`) — the primary gate. Well below every
|
|
61
|
+
* genuine fixture (≥0.45) yet strictly above a body-only collision's 0, so a
|
|
62
|
+
* real partial-relevance hit on a common/low-idf term is never overcorrected
|
|
63
|
+
* out. */
|
|
64
|
+
export const STRONG_FLOOR = 0.1;
|
|
65
|
+
/** …OR the overall (name+path+body) coverage is broad enough to be real even
|
|
66
|
+
* body-only. A single incidental body-token collision measures ~0.29 and RISES
|
|
67
|
+
* with corpus size (0.30+ at 200 nodes) but never approaches this, while a
|
|
68
|
+
* genuinely broad match clears it. This is why the gate is on absolute,
|
|
69
|
+
* scale-invariant floors, NOT a raw-lexical-score ratio (which — calibrated for
|
|
70
|
+
* raw-lexical-SCORE space — was far too lenient in coverage/matched-fraction
|
|
71
|
+
* space and leaked junk, worsening as the corpus grew). */
|
|
72
|
+
export const HIGH_FLOOR = 0.5;
|
|
73
|
+
/** Score-desc, id-asc ordering — the id tiebreak is what makes fusion
|
|
74
|
+
* deterministic under input shuffle. */
|
|
75
|
+
function byScore(a, b) {
|
|
76
|
+
return b.score - a.score || a.id.localeCompare(b.id);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Partition by scope, rank within scope (input scores are already
|
|
80
|
+
* per-scope-normalized), gate by soft federation, fuse by RRF:
|
|
81
|
+
* `fused(id) = Σ 1/(K + rank_in_scope(id))`, then normalized so the top fused
|
|
82
|
+
* doc is 1. Non-scoring docs (score ≤ 0) are dropped entirely.
|
|
83
|
+
*
|
|
84
|
+
* Degenerate cases degrade to current behavior: zero scoring docs → empty
|
|
85
|
+
* result; exactly one scoring scope → its docs pass through in score order
|
|
86
|
+
* with their ORIGINAL scores (no RRF re-scoring, no gate) — byte-for-byte the
|
|
87
|
+
* single-corpus ranking the caller would have produced anyway.
|
|
88
|
+
*/
|
|
89
|
+
export function fuseScopes(docs) {
|
|
90
|
+
const byScope = new Map();
|
|
91
|
+
for (const d of docs) {
|
|
92
|
+
if (d.score <= 0)
|
|
93
|
+
continue;
|
|
94
|
+
const list = byScope.get(d.scope);
|
|
95
|
+
if (list)
|
|
96
|
+
list.push(d);
|
|
97
|
+
else
|
|
98
|
+
byScope.set(d.scope, [d]);
|
|
99
|
+
}
|
|
100
|
+
for (const list of byScope.values())
|
|
101
|
+
list.sort(byScore);
|
|
102
|
+
if (byScope.size === 0)
|
|
103
|
+
return { ranked: [], federated: [], alsoMatched: [] };
|
|
104
|
+
if (byScope.size === 1) {
|
|
105
|
+
const [scope, list] = byScope.entries().next().value;
|
|
106
|
+
return {
|
|
107
|
+
ranked: list.map((d) => ({ id: d.id, scope, score: d.score })),
|
|
108
|
+
federated: [scope],
|
|
109
|
+
alsoMatched: [],
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
// Gate: order scopes by their best doc (desc, scope-name tiebreak), split
|
|
113
|
+
// into federated (≥ ratio × global best, inclusive) and alsoMatched.
|
|
114
|
+
const scopesByBest = [...byScope.entries()].sort((a, b) => b[1][0].score - a[1][0].score || a[0].localeCompare(b[0]));
|
|
115
|
+
const gate = PARTICIPATION_RATIO * scopesByBest[0][1][0].score;
|
|
116
|
+
const federated = [];
|
|
117
|
+
const alsoMatched = [];
|
|
118
|
+
for (const [scope, list] of scopesByBest) {
|
|
119
|
+
if (list[0].score >= gate)
|
|
120
|
+
federated.push(scope);
|
|
121
|
+
else
|
|
122
|
+
alsoMatched.push({ scope, bestId: list[0].id });
|
|
123
|
+
}
|
|
124
|
+
// RRF: each federated scope contributes 1/(K + rank) per doc; an id listed
|
|
125
|
+
// in more than one scope sums its contributions and is attributed to the
|
|
126
|
+
// scope where it ranked best.
|
|
127
|
+
const acc = new Map();
|
|
128
|
+
for (const scope of federated) {
|
|
129
|
+
byScope.get(scope).forEach((d, i) => {
|
|
130
|
+
const contribution = 1 / (RRF_K + i + 1);
|
|
131
|
+
const prev = acc.get(d.id);
|
|
132
|
+
if (!prev)
|
|
133
|
+
acc.set(d.id, { scope, score: contribution, bestRank: i });
|
|
134
|
+
else {
|
|
135
|
+
prev.score += contribution;
|
|
136
|
+
if (i < prev.bestRank) {
|
|
137
|
+
prev.scope = scope;
|
|
138
|
+
prev.bestRank = i;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
let max = 0;
|
|
144
|
+
for (const e of acc.values())
|
|
145
|
+
if (e.score > max)
|
|
146
|
+
max = e.score;
|
|
147
|
+
const ranked = [...acc.entries()].map(([id, e]) => ({
|
|
148
|
+
id,
|
|
149
|
+
scope: e.scope,
|
|
150
|
+
score: e.score / max,
|
|
151
|
+
}));
|
|
152
|
+
ranked.sort((a, b) => b.score - a.score || a.scope.localeCompare(b.scope) || a.id.localeCompare(b.id));
|
|
153
|
+
return { ranked, federated, alsoMatched };
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Combine scopes whose scores are ALREADY comparable (shared corpus statistics
|
|
157
|
+
* and a shared normalization denominator — see the module header). Same shape
|
|
158
|
+
* and same gate as {@link fuseScopes}, but the combined order is read straight
|
|
159
|
+
* off the score instead of from reciprocal rank, because with a common scale
|
|
160
|
+
* the magnitude is exactly the signal rank fusion would throw away.
|
|
161
|
+
*
|
|
162
|
+
* Only {@link rankScopesAndFuse} may call this. `federateAsk` fuses separate
|
|
163
|
+
* repositories, which have no common denominator, and must keep using
|
|
164
|
+
* {@link fuseScopes}.
|
|
165
|
+
*/
|
|
166
|
+
export function combineComparableScopes(docs) {
|
|
167
|
+
const byScope = new Map();
|
|
168
|
+
for (const d of docs) {
|
|
169
|
+
if (d.score <= 0)
|
|
170
|
+
continue;
|
|
171
|
+
const list = byScope.get(d.scope);
|
|
172
|
+
if (list)
|
|
173
|
+
list.push(d);
|
|
174
|
+
else
|
|
175
|
+
byScope.set(d.scope, [d]);
|
|
176
|
+
}
|
|
177
|
+
for (const list of byScope.values())
|
|
178
|
+
list.sort(byScore);
|
|
179
|
+
if (byScope.size === 0)
|
|
180
|
+
return { ranked: [], federated: [], alsoMatched: [] };
|
|
181
|
+
// One scoring scope: pass through untouched. Identical to the single-scope
|
|
182
|
+
// path by construction — the guarantee that a single-scope repo cannot move.
|
|
183
|
+
if (byScope.size === 1) {
|
|
184
|
+
const [scope, list] = byScope.entries().next().value;
|
|
185
|
+
return {
|
|
186
|
+
ranked: list.map((d) => ({ id: d.id, scope, score: d.score })),
|
|
187
|
+
federated: [scope],
|
|
188
|
+
alsoMatched: [],
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
// Gate on a real share of the best score in the repo. This is the same
|
|
192
|
+
// ratio check `fuseScopes` runs, but here it MEANS something: the scores
|
|
193
|
+
// being compared share a denominator.
|
|
194
|
+
const scopesByBest = [...byScope.entries()].sort((a, b) => b[1][0].score - a[1][0].score || a[0].localeCompare(b[0]));
|
|
195
|
+
const gate = PARTICIPATION_RATIO * scopesByBest[0][1][0].score;
|
|
196
|
+
const federated = [];
|
|
197
|
+
const alsoMatched = [];
|
|
198
|
+
for (const [scope, list] of scopesByBest) {
|
|
199
|
+
if (list[0].score >= gate)
|
|
200
|
+
federated.push(scope);
|
|
201
|
+
else
|
|
202
|
+
alsoMatched.push({ scope, bestId: list[0].id });
|
|
203
|
+
}
|
|
204
|
+
// An id can only belong to one scope (scope is a path prefix), but keep the
|
|
205
|
+
// defensive max so a duplicate cannot double-count or flip its attribution.
|
|
206
|
+
const acc = new Map();
|
|
207
|
+
for (const scope of federated) {
|
|
208
|
+
for (const d of byScope.get(scope)) {
|
|
209
|
+
const prev = acc.get(d.id);
|
|
210
|
+
if (!prev || d.score > prev.score)
|
|
211
|
+
acc.set(d.id, { scope, score: d.score });
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
let max = 0;
|
|
215
|
+
for (const e of acc.values())
|
|
216
|
+
if (e.score > max)
|
|
217
|
+
max = e.score;
|
|
218
|
+
const ranked = [...acc.entries()].map(([id, e]) => ({
|
|
219
|
+
id,
|
|
220
|
+
scope: e.scope,
|
|
221
|
+
score: max > 0 ? e.score / max : 0,
|
|
222
|
+
}));
|
|
223
|
+
ranked.sort((a, b) => b.score - a.score || a.scope.localeCompare(b.scope) || a.id.localeCompare(b.id));
|
|
224
|
+
return { ranked, federated, alsoMatched };
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Multi-scope orchestration for `ask`'s symbol ranking: for each scope, score
|
|
228
|
+
* lexically (against the repo-wide statistics the caller supplies), walk the
|
|
229
|
+
* scope's subgraph, blend exactly like the single-scope path (`lexN +
|
|
230
|
+
* graphWeight·pr`, walk-rescued nodes joining above `rescueFloor`), then
|
|
231
|
+
* combine the scopes with {@link combineComparableScopes}. A scope with zero
|
|
232
|
+
* lexical matches contributes nothing (no seeds → no walk → no docs).
|
|
233
|
+
*
|
|
234
|
+
* The one thing that differs from the single-scope path: `lexN` divides by
|
|
235
|
+
* `globalMaxLex`, the best raw lexical score across ALL scopes, rather than by
|
|
236
|
+
* each scope's own best. That shared denominator is what makes the blended
|
|
237
|
+
* scores comparable, and therefore what lets the combined order be read off the
|
|
238
|
+
* score. Dividing per scope — as this did before #117 — pinned every scope's
|
|
239
|
+
* top hit to ~1.0 regardless of how well it matched, which is the defect.
|
|
240
|
+
*
|
|
241
|
+
* Participation is then the {@link PARTICIPATION_RATIO} share check inside
|
|
242
|
+
* {@link combineComparableScopes}: a scope must reach a real fraction of the
|
|
243
|
+
* best score anywhere in the repo, else it is reported in `alsoMatched` for
|
|
244
|
+
* `--in`. The match-STRENGTH floors ({@link STRONG_FLOOR}/{@link HIGH_FLOOR})
|
|
245
|
+
* are no longer applied here — they existed to stand in for a share check that
|
|
246
|
+
* per-scope normalization had made vacuous. `federateAsk` still normalizes per
|
|
247
|
+
* child repo, so it still gates on strength; see `src/graph/workspace.ts`.
|
|
248
|
+
*/
|
|
249
|
+
export function rankScopesAndFuse(scopes, ops, graphWeight, rescueFloor) {
|
|
250
|
+
// Pass 1: lexical scoring only, per scope.
|
|
251
|
+
const lexByScope = new Map();
|
|
252
|
+
for (const scope of scopes) {
|
|
253
|
+
const lex = ops.lex(scope);
|
|
254
|
+
if (lex.size === 0)
|
|
255
|
+
continue;
|
|
256
|
+
lexByScope.set(scope, lex);
|
|
257
|
+
}
|
|
258
|
+
const alsoMatched = [];
|
|
259
|
+
const candidatesWithComponents = [];
|
|
260
|
+
// Per-scope raw best, plus the best raw score anywhere in the repo. That
|
|
261
|
+
// repo-wide maximum is the shared denominator every scope normalizes by.
|
|
262
|
+
const meta = new Map();
|
|
263
|
+
let globalMaxLex = 0;
|
|
264
|
+
for (const [scope, lex] of lexByScope) {
|
|
265
|
+
let maxLex = 0, bestId = "";
|
|
266
|
+
for (const [id, v] of lex)
|
|
267
|
+
if (v > maxLex || (v === maxLex && id < bestId)) {
|
|
268
|
+
maxLex = v;
|
|
269
|
+
bestId = id;
|
|
270
|
+
}
|
|
271
|
+
if (maxLex <= 0)
|
|
272
|
+
continue;
|
|
273
|
+
meta.set(scope, { lex, maxLex, bestId });
|
|
274
|
+
if (maxLex > globalMaxLex)
|
|
275
|
+
globalMaxLex = maxLex;
|
|
276
|
+
}
|
|
277
|
+
// Body-only suppression. With a shared denominator a weak scope simply
|
|
278
|
+
// scores low, so participation is decided on score in
|
|
279
|
+
// `combineComparableScopes` — no scope is excluded on a share threshold any
|
|
280
|
+
// more. The single exception is a scope in which NO doc matched a query term
|
|
281
|
+
// in a name or path while some other scope did: that is the comment-banner
|
|
282
|
+
// collision (see `hasIdentifierMatch` above), and score cannot separate it
|
|
283
|
+
// from a real match. Only applied when a genuine identifier match exists
|
|
284
|
+
// somewhere, so a query that legitimately matches only prose still returns
|
|
285
|
+
// something.
|
|
286
|
+
const bodyOnly = new Set();
|
|
287
|
+
if (ops.hasIdentifierMatch) {
|
|
288
|
+
const named = new Map();
|
|
289
|
+
for (const scope of meta.keys())
|
|
290
|
+
named.set(scope, ops.hasIdentifierMatch(scope));
|
|
291
|
+
if ([...named.values()].some(Boolean)) {
|
|
292
|
+
for (const [scope, ok] of named)
|
|
293
|
+
if (!ok)
|
|
294
|
+
bodyOnly.add(scope);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
for (const scope of bodyOnly) {
|
|
298
|
+
alsoMatched.push({ scope, bestId: meta.get(scope).bestId });
|
|
299
|
+
meta.delete(scope);
|
|
300
|
+
}
|
|
301
|
+
// The denominator must come from the scopes that actually rank, or a
|
|
302
|
+
// suppressed scope could still set the scale for everyone else.
|
|
303
|
+
globalMaxLex = 0;
|
|
304
|
+
for (const { maxLex } of meta.values())
|
|
305
|
+
if (maxLex > globalMaxLex)
|
|
306
|
+
globalMaxLex = maxLex;
|
|
307
|
+
for (const [scope, { lex }] of meta) {
|
|
308
|
+
const pr = ops.walk(scope, lex);
|
|
309
|
+
const candidates = new Set(lex.keys());
|
|
310
|
+
for (const [id, p] of pr)
|
|
311
|
+
if (p >= rescueFloor)
|
|
312
|
+
candidates.add(id);
|
|
313
|
+
for (const id of candidates) {
|
|
314
|
+
const lexN = globalMaxLex > 0 ? (lex.get(id) ?? 0) / globalMaxLex : 0;
|
|
315
|
+
const graph = pr.get(id) ?? 0;
|
|
316
|
+
const rankFactor = ops.rankFactor?.(scope, id) ?? 1;
|
|
317
|
+
const blended = (lexN + graphWeight * graph) * rankFactor;
|
|
318
|
+
if (blended > 0) {
|
|
319
|
+
candidatesWithComponents.push({
|
|
320
|
+
id,
|
|
321
|
+
scope,
|
|
322
|
+
score: blended,
|
|
323
|
+
lexical: lexN,
|
|
324
|
+
graph,
|
|
325
|
+
rankFactor,
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
const scoped = ops.collapseCandidates
|
|
331
|
+
? [...ops.collapseCandidates(candidatesWithComponents)]
|
|
332
|
+
: candidatesWithComponents.map((candidate) => ({
|
|
333
|
+
id: candidate.id,
|
|
334
|
+
scope: candidate.scope,
|
|
335
|
+
score: candidate.score,
|
|
336
|
+
}));
|
|
337
|
+
const combined = combineComparableScopes(scoped);
|
|
338
|
+
return {
|
|
339
|
+
ranked: combined.ranked,
|
|
340
|
+
federated: combined.federated,
|
|
341
|
+
alsoMatched: [...alsoMatched, ...combined.alsoMatched],
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
//# sourceMappingURL=fuse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fuse.js","sourceRoot":"","sources":["../../src/ask/fuse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph-rank re-ranking for `graft ask` — the fix for lexical keyword-collision.
|
|
3
|
+
*
|
|
4
|
+
* Pure term-overlap ranking treats every node independently, so a node that
|
|
5
|
+
* merely shares a word with the query (a window "overlay" widget) can outrank
|
|
6
|
+
* the node the query is actually about (a scroll-"overlay" config) purely on
|
|
7
|
+
* word count. The graph knows better: the right node is the one wired into the
|
|
8
|
+
* cluster of code the query touches.
|
|
9
|
+
*
|
|
10
|
+
* This module runs personalized PageRank (random-walk-with-restart) over the
|
|
11
|
+
* wiring graph, seeded by the lexical scores. Mass concentrates on nodes that
|
|
12
|
+
* are edge-connected to the matched set; a lexically-matched but structurally
|
|
13
|
+
* isolated node keeps only its own restart mass and sinks. "Lexical proposes,
|
|
14
|
+
* graph disposes." Deterministic, $0, no embeddings — a lexical-seed →
|
|
15
|
+
* graph-rank pipeline, the established alternative to vector search for code.
|
|
16
|
+
*/
|
|
17
|
+
import type { GraphV1 } from "../graph/types.js";
|
|
18
|
+
export interface PageRankOptions {
|
|
19
|
+
/** Restart probability — the mass that teleports back to the seed set each
|
|
20
|
+
* step. Higher keeps the walk closer to the seeds. 0.25 is the standard value. */
|
|
21
|
+
alpha?: number;
|
|
22
|
+
/** Power-iteration count. 25 is plenty to converge on graphs this size. */
|
|
23
|
+
iters?: number;
|
|
24
|
+
/** Restrict the walk to a subgraph: when present, an edge counts only when
|
|
25
|
+
* BOTH endpoints pass, and only passing ids can hold rank mass or seed
|
|
26
|
+
* weight. Seeds outside the filter are silently ignored (same as a seed
|
|
27
|
+
* naming a non-existent node). Omit for the full-graph walk (unchanged
|
|
28
|
+
* behavior). */
|
|
29
|
+
nodeFilter?: (id: string) => boolean;
|
|
30
|
+
}
|
|
31
|
+
/** Immutable graph topology consumed by the PageRank iteration. Preparing it
|
|
32
|
+
* separately lets a multi-scope query partition one large graph once, instead
|
|
33
|
+
* of rescanning every node and edge for every scope. */
|
|
34
|
+
export interface PageRankTopology {
|
|
35
|
+
ids: ReadonlySet<string>;
|
|
36
|
+
adjacency: ReadonlyMap<string, readonly string[]>;
|
|
37
|
+
}
|
|
38
|
+
export type PageRankRunOptions = Pick<PageRankOptions, "alpha" | "iters">;
|
|
39
|
+
/** Build independent PageRank topologies in one node pass and one edge pass.
|
|
40
|
+
* Edges crossing partitions are excluded, exactly like applying a nodeFilter
|
|
41
|
+
* for each partition independently. Returning `undefined` omits a node. */
|
|
42
|
+
export declare function preparePageRankPartitions(graph: GraphV1, partitionOfId: (id: string) => string | undefined): Map<string, PageRankTopology>;
|
|
43
|
+
/** Prepare one optionally filtered topology. Kept public for callers/tests that
|
|
44
|
+
* reuse the same graph across multiple seed sets. */
|
|
45
|
+
export declare function preparePageRankTopology(graph: GraphV1, nodeFilter?: (id: string) => boolean): PageRankTopology;
|
|
46
|
+
/**
|
|
47
|
+
* Personalized PageRank over the wiring graph.
|
|
48
|
+
*
|
|
49
|
+
* `seeds` maps node id → restart weight (a node's lexical score; only positive
|
|
50
|
+
* weights matter). The graph is treated as UNDIRECTED — for "understand this
|
|
51
|
+
* area" a callee is as relevant as a caller. Returns a score per node
|
|
52
|
+
* normalized so the top node is 1; nodes untouched by the walk are absent.
|
|
53
|
+
*
|
|
54
|
+
* Edges whose endpoints aren't both real nodes (e.g. an unresolved import
|
|
55
|
+
* module string) are ignored, so only genuine symbol-to-symbol wiring counts.
|
|
56
|
+
*/
|
|
57
|
+
export declare function personalizedPageRank(graph: GraphV1, seeds: Map<string, number>, opts?: PageRankOptions): Map<string, number>;
|
|
58
|
+
/** Run PageRank on an already prepared topology. This is numerically identical
|
|
59
|
+
* to {@link personalizedPageRank}; it only removes repeated topology scans. */
|
|
60
|
+
export declare function personalizedPageRankPrepared(topology: PageRankTopology, seeds: Map<string, number>, opts?: PageRankRunOptions): Map<string, number>;
|
|
61
|
+
//# sourceMappingURL=graphrank.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphrank.d.ts","sourceRoot":"","sources":["../../src/ask/graphrank.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAGjD,MAAM,WAAW,eAAe;IAC9B;sFACkF;IAClF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;oBAIgB;IAChB,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;CACtC;AAED;;wDAEwD;AACxD,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACzB,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;CACnD;AAED,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC;AAkB1E;;2EAE2E;AAC3E,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,EACd,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GAChD,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAuB/B;AAED;qDACqD;AACrD,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,OAAO,EACd,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,GACnC,gBAAgB,CAclB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC1B,IAAI,GAAE,eAAoB,GACzB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAMrB;AAED;+EAC+E;AAC/E,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC1B,IAAI,GAAE,kBAAuB,GAC5B,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA8CrB"}
|