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,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Opt-in LSP enrichment (`graft build --lsp`): add compiler-grade call edges the
|
|
3
|
+
* AST resolver couldn't — chiefly member calls (`obj.foo()`) whose receiver type
|
|
4
|
+
* graft can't infer, and every call in the generic breadth tier (which has no
|
|
5
|
+
* receiver typing at all). For each function/method node we ask the language
|
|
6
|
+
* server for its outgoing calls (call hierarchy) and map each callee's definition
|
|
7
|
+
* back to a graft node, adding a `calls` edge stamped `lsp_resolved`. Precision is
|
|
8
|
+
* the server's (compiler-grade), so this closes the edge-recall gap WITHOUT the
|
|
9
|
+
* name-guessing that halved precision (see resolve.ts). Best-effort: no server /
|
|
10
|
+
* a timeout / an error → the graph is returned unchanged.
|
|
11
|
+
*/
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
import { readFileSync, realpathSync } from "node:fs";
|
|
14
|
+
import { fileURLToPath } from "node:url";
|
|
15
|
+
import { relPosix } from "../../util/paths.js";
|
|
16
|
+
import { languageLabelOf } from "../extract.js";
|
|
17
|
+
import { genericLangOf } from "../generic.js";
|
|
18
|
+
import { LspClient } from "./client.js";
|
|
19
|
+
import { pickServer } from "./registry.js";
|
|
20
|
+
const CALLABLE = new Set(["function", "method"]);
|
|
21
|
+
const DEFN = new Set(["function", "method", "class", "struct", "interface", "type", "enum"]);
|
|
22
|
+
const langOf = (path) => genericLangOf(path)?.name ?? languageLabelOf(path);
|
|
23
|
+
const parseSpan = (s) => {
|
|
24
|
+
const m = /^L(\d+)-L(\d+)$/.exec(s);
|
|
25
|
+
return m ? [Number(m[1]), Number(m[2])] : null;
|
|
26
|
+
};
|
|
27
|
+
export async function enrichWithLsp(graph, root, opts = {}) {
|
|
28
|
+
const languagesPresent = new Set();
|
|
29
|
+
for (const n of graph.nodes) {
|
|
30
|
+
const l = langOf(n.path);
|
|
31
|
+
if (l)
|
|
32
|
+
languagesPresent.add(l);
|
|
33
|
+
}
|
|
34
|
+
const server = pickServer(languagesPresent);
|
|
35
|
+
if (!server)
|
|
36
|
+
return { added: 0, queried: 0, server: null };
|
|
37
|
+
// Canonicalize the root: servers (rust-analyzer/clangd) report callee URIs
|
|
38
|
+
// against the REAL path, so under a symlinked checkout (macOS /tmp →
|
|
39
|
+
// /private/tmp, common in CI) an un-resolved root would fail the in-repo test
|
|
40
|
+
// for every callee and silently zero out enrichment.
|
|
41
|
+
const realRoot = (() => { try {
|
|
42
|
+
return realpathSync(root);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return root;
|
|
46
|
+
} })();
|
|
47
|
+
root = realRoot;
|
|
48
|
+
// Index nodes by file for both source selection and callee→node mapping.
|
|
49
|
+
const byId = new Map(graph.nodes.map((n) => [n.id, n]));
|
|
50
|
+
const spansByFile = new Map();
|
|
51
|
+
for (const n of graph.nodes) {
|
|
52
|
+
if (n.kind === "file" || !DEFN.has(n.kind))
|
|
53
|
+
continue;
|
|
54
|
+
const sp = parseSpan(n.span);
|
|
55
|
+
if (!sp)
|
|
56
|
+
continue;
|
|
57
|
+
const list = spansByFile.get(n.path) ?? [];
|
|
58
|
+
list.push({ node: n, from: sp[0], to: sp[1] });
|
|
59
|
+
spansByFile.set(n.path, list);
|
|
60
|
+
}
|
|
61
|
+
// The definition node covering a 1-indexed line in a file: innermost (smallest span).
|
|
62
|
+
const nodeAt = (rel, line) => {
|
|
63
|
+
const cands = (spansByFile.get(rel) ?? []).filter((s) => s.from <= line && line <= s.to);
|
|
64
|
+
if (!cands.length)
|
|
65
|
+
return null;
|
|
66
|
+
return cands.sort((a, b) => (a.to - a.from) - (b.to - b.from))[0].node;
|
|
67
|
+
};
|
|
68
|
+
// Source nodes to query: callable nodes in files this server handles.
|
|
69
|
+
const serverLangs = new Set(server.languages);
|
|
70
|
+
let sources = graph.nodes.filter((n) => CALLABLE.has(n.kind) && serverLangs.has(langOf(n.path) ?? ""));
|
|
71
|
+
if (opts.maxNodes && sources.length > opts.maxNodes)
|
|
72
|
+
sources = sources.slice(0, opts.maxNodes);
|
|
73
|
+
let client;
|
|
74
|
+
// spawn throws synchronously when Windows refuses the program (e.g. a .cmd that isn't an
|
|
75
|
+
// npm shim: EINVAL), before any error listener exists — no enrichment, not a failed build.
|
|
76
|
+
try {
|
|
77
|
+
client = new LspClient(server.command, server.args, root, server.languageId);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return { added: 0, queried: 0, server: server.command };
|
|
81
|
+
}
|
|
82
|
+
if (!(await client.initialize())) {
|
|
83
|
+
await client.dispose();
|
|
84
|
+
return { added: 0, queried: 0, server: server.command };
|
|
85
|
+
}
|
|
86
|
+
const existing = new Set(graph.edges.map((e) => `${e.source}\0${e.relation}\0${e.target}`));
|
|
87
|
+
const fileLines = new Map();
|
|
88
|
+
const linesOf = (rel) => {
|
|
89
|
+
if (!fileLines.has(rel)) {
|
|
90
|
+
try {
|
|
91
|
+
fileLines.set(rel, readFileSync(join(root, rel), "utf8").split("\n"));
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
fileLines.set(rel, []);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return fileLines.get(rel);
|
|
98
|
+
};
|
|
99
|
+
// The name-token position of a definition (0-indexed), scanning its first few
|
|
100
|
+
// lines for the name — call hierarchy needs a position ON the symbol.
|
|
101
|
+
const namePos = (src) => {
|
|
102
|
+
const sp = parseSpan(src.span);
|
|
103
|
+
if (!sp)
|
|
104
|
+
return null;
|
|
105
|
+
const lines = linesOf(src.path);
|
|
106
|
+
for (let ln = sp[0] - 1; ln < Math.min(sp[0] + 2, lines.length); ln++) {
|
|
107
|
+
const c = (lines[ln] ?? "").indexOf(src.name);
|
|
108
|
+
if (c >= 0)
|
|
109
|
+
return { line: ln, character: c };
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
};
|
|
113
|
+
// Wait for the server to finish indexing (it answers call-hierarchy empty
|
|
114
|
+
// until ready). Warm up on the first source node that has a findable position.
|
|
115
|
+
const warm = sources.find((s) => namePos(s));
|
|
116
|
+
if (warm) {
|
|
117
|
+
const wp = namePos(warm);
|
|
118
|
+
if (!(await client.waitUntilReady(join(root, warm.path), wp))) {
|
|
119
|
+
await client.dispose();
|
|
120
|
+
return { added: 0, queried: 0, server: server.command }; // never became ready
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
let added = 0, queried = 0;
|
|
124
|
+
for (const src of sources) {
|
|
125
|
+
const abs = join(root, src.path);
|
|
126
|
+
client.didOpen(abs);
|
|
127
|
+
const pos = namePos(src);
|
|
128
|
+
if (!pos)
|
|
129
|
+
continue;
|
|
130
|
+
const items = await client.prepareCallHierarchy(abs, pos);
|
|
131
|
+
if (!items.length)
|
|
132
|
+
continue;
|
|
133
|
+
queried++;
|
|
134
|
+
opts.onProgress?.(queried, sources.length);
|
|
135
|
+
const callees = await client.outgoingCalls(items[0]);
|
|
136
|
+
for (const callee of callees) {
|
|
137
|
+
let calleeAbs;
|
|
138
|
+
try {
|
|
139
|
+
calleeAbs = fileURLToPath(callee.uri);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const rel = relPosix(root, calleeAbs);
|
|
145
|
+
// In-repo iff the repo-relative path doesn't escape the root. (A raw
|
|
146
|
+
// `startsWith(root)` is separator-unsafe: root=/a/foo matches /a/foo-bar.)
|
|
147
|
+
if (rel.startsWith("..") || rel.startsWith("/"))
|
|
148
|
+
continue; // external/dependency
|
|
149
|
+
const target = nodeAt(rel, (callee.selectionRange?.start.line ?? callee.range.start.line) + 1);
|
|
150
|
+
if (!target || target.id === src.id)
|
|
151
|
+
continue;
|
|
152
|
+
const key = `${src.id}\0calls\0${target.id}`;
|
|
153
|
+
if (existing.has(key))
|
|
154
|
+
continue;
|
|
155
|
+
existing.add(key);
|
|
156
|
+
graph.edges.push({ source: src.id, target: target.id, relation: "calls", confidence: "lsp_resolved" });
|
|
157
|
+
added++;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
await client.dispose();
|
|
161
|
+
return { added, queried, server: server.command };
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=enrich.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enrich.js","sourceRoot":"","sources":["../../../src/graph/lsp/enrich.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface LspServer {
|
|
2
|
+
/** graft language names (as produced by languageLabelOf/genericLangOf) this serves. */
|
|
3
|
+
languages: string[];
|
|
4
|
+
command: string;
|
|
5
|
+
args: string[];
|
|
6
|
+
/** the LSP `languageId` to tag opened documents with. */
|
|
7
|
+
languageId: string;
|
|
8
|
+
}
|
|
9
|
+
/** First-match-wins; ordering is priority. Extend by adding a row. */
|
|
10
|
+
export declare const LSP_SERVERS: readonly LspServer[];
|
|
11
|
+
/** Windows: the first `<cmd>.com/.exe/.cmd` in PATH order, searching only
|
|
12
|
+
* absolute PATH folders. Not `where.exe`: it (and cmd.exe finding `where.exe` itself)
|
|
13
|
+
* searches the current folder first, so a checkout could plant
|
|
14
|
+
* `typescript-language-server.cmd` and have `graft build --lsp` run it. The extension
|
|
15
|
+
* matters too: npm puts an extensionless sh script next to each `.cmd` shim, which
|
|
16
|
+
* Windows can't run. */
|
|
17
|
+
export declare function findOnWindowsPath(cmd: string, pathVar?: string, exists?: (p: string) => boolean): string | null;
|
|
18
|
+
/** Pick the highest-priority installed server that covers at least one of the
|
|
19
|
+
* languages present in the repo, with `command` resolved to an absolute path.
|
|
20
|
+
* Returns null if none is installed. */
|
|
21
|
+
export declare function pickServer(languagesPresent: Set<string>): LspServer | null;
|
|
22
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/graph/lsp/registry.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,SAAS;IACxB,uFAAuF;IACvF,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,sEAAsE;AACtE,eAAO,MAAM,WAAW,EAAE,SAAS,SAAS,EAM3C,CAAC;AAEF;;;;;wBAKwB;AACxB,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,SAAyB,EAAE,MAAM,GAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAoB,GAAG,MAAM,GAAG,IAAI,CAU3I;AAqBD;;wCAEwC;AACxC,wBAAgB,UAAU,CAAC,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,SAAS,GAAG,IAAI,CAO1E"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LSP server registry — maps graft language names to a language server command.
|
|
3
|
+
* Only servers whose binary is actually on PATH are eligible; a missing binary
|
|
4
|
+
* simply means that language gets no LSP enrichment (the AST graph stands alone).
|
|
5
|
+
*/
|
|
6
|
+
import { execSync } from "node:child_process";
|
|
7
|
+
import { existsSync } from "node:fs";
|
|
8
|
+
import { win32 } from "node:path";
|
|
9
|
+
/** First-match-wins; ordering is priority. Extend by adding a row. */
|
|
10
|
+
export const LSP_SERVERS = [
|
|
11
|
+
{ languages: ["rust"], command: "rust-analyzer", args: [], languageId: "rust" },
|
|
12
|
+
{ languages: ["cpp", "c"], command: "clangd", args: ["--background-index"], languageId: "cpp" },
|
|
13
|
+
{ languages: ["go"], command: "gopls", args: [], languageId: "go" },
|
|
14
|
+
{ languages: ["python"], command: "pyright-langserver", args: ["--stdio"], languageId: "python" },
|
|
15
|
+
{ languages: ["typescript", "javascript", "tsx"], command: "typescript-language-server", args: ["--stdio"], languageId: "typescript" },
|
|
16
|
+
];
|
|
17
|
+
/** Windows: the first `<cmd>.com/.exe/.cmd` in PATH order, searching only
|
|
18
|
+
* absolute PATH folders. Not `where.exe`: it (and cmd.exe finding `where.exe` itself)
|
|
19
|
+
* searches the current folder first, so a checkout could plant
|
|
20
|
+
* `typescript-language-server.cmd` and have `graft build --lsp` run it. The extension
|
|
21
|
+
* matters too: npm puts an extensionless sh script next to each `.cmd` shim, which
|
|
22
|
+
* Windows can't run. */
|
|
23
|
+
export function findOnWindowsPath(cmd, pathVar = process.env.PATH ?? "", exists = existsSync) {
|
|
24
|
+
for (const entry of pathVar.split(";")) {
|
|
25
|
+
const dir = entry.trim().replace(/^"(.*)"$/, "$1");
|
|
26
|
+
if (!/^([a-zA-Z]:[\\/]|\\\\)/.test(dir))
|
|
27
|
+
continue; // relative or empty ("." = the current folder)
|
|
28
|
+
for (const ext of [".com", ".exe", ".cmd"]) { // .cmd: npm's shims (see spawnSpec); a .bat can't be started without a shell
|
|
29
|
+
const p = win32.join(dir, cmd + ext);
|
|
30
|
+
if (exists(p))
|
|
31
|
+
return p;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
const resolved = new Map();
|
|
37
|
+
/** Resolve a command to its ABSOLUTE path via the login shell's PATH. `spawn`
|
|
38
|
+
* resolves against `process.env.PATH`, which often omits `~/.cargo/bin`,
|
|
39
|
+
* `~/go/bin`, etc. where these servers live — so `command -v` can find a server
|
|
40
|
+
* that `spawn(cmd)` then can't. Spawning the absolute path avoids that mismatch.
|
|
41
|
+
* On Windows `execSync` runs through cmd.exe, which has no `command -v`: search
|
|
42
|
+
* PATH directly there (findOnWindowsPath). */
|
|
43
|
+
function resolveCommand(cmd) {
|
|
44
|
+
if (resolved.has(cmd))
|
|
45
|
+
return resolved.get(cmd);
|
|
46
|
+
let abs = null;
|
|
47
|
+
try {
|
|
48
|
+
abs = process.platform === "win32"
|
|
49
|
+
? findOnWindowsPath(cmd)
|
|
50
|
+
: execSync(`command -v ${cmd}`, { encoding: "utf8" }).trim() || null;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
abs = null;
|
|
54
|
+
}
|
|
55
|
+
resolved.set(cmd, abs);
|
|
56
|
+
return abs;
|
|
57
|
+
}
|
|
58
|
+
/** Pick the highest-priority installed server that covers at least one of the
|
|
59
|
+
* languages present in the repo, with `command` resolved to an absolute path.
|
|
60
|
+
* Returns null if none is installed. */
|
|
61
|
+
export function pickServer(languagesPresent) {
|
|
62
|
+
for (const s of LSP_SERVERS) {
|
|
63
|
+
if (!s.languages.some((l) => languagesPresent.has(l)))
|
|
64
|
+
continue;
|
|
65
|
+
const abs = resolveCommand(s.command);
|
|
66
|
+
if (abs)
|
|
67
|
+
return { ...s, command: abs };
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/graph/lsp/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `graft map` core: a deterministic, token-budgeted repo orientation —
|
|
3
|
+
* directory clusters, per-directory hubs, and global hotspots — computed
|
|
4
|
+
* purely from the wiring graph (no LLM, no I/O beyond the already-loaded
|
|
5
|
+
* `GraphV1`).
|
|
6
|
+
*
|
|
7
|
+
* Grouping is by first path segment (`src/cache.ts` → `src`), so a coding
|
|
8
|
+
* agent gets the same top-level shape a human sees in a file tree. When one
|
|
9
|
+
* segment swallows most of the repo (a flat `src/` with everything under
|
|
10
|
+
* it), that single group would be useless as an orientation aid, so it gets
|
|
11
|
+
* one refinement pass: split one level deeper (`src` → `src/ask`,
|
|
12
|
+
* `src/graph`, …). Hubs and hotspots rank by incoming `WALK_RELATIONS`
|
|
13
|
+
* edges (shared with `graphrank.ts`/`grep.ts`, so "important" means the same
|
|
14
|
+
* thing everywhere in graft) — never by lines of code or heuristics that
|
|
15
|
+
* drift from the actual wiring.
|
|
16
|
+
*
|
|
17
|
+
* Pure and synchronous: same fixture-testable shape as `grep.ts` — no CLI or
|
|
18
|
+
* MCP concerns live here. `cli.ts` and `mcp/tools.ts` both call
|
|
19
|
+
* `buildRepoMap` + `formatRepoMap` directly.
|
|
20
|
+
*/
|
|
21
|
+
import type { GraphV1 } from "./types.js";
|
|
22
|
+
import { type Savings } from "../context/savings.js";
|
|
23
|
+
export interface Hub {
|
|
24
|
+
name: string;
|
|
25
|
+
kind: string;
|
|
26
|
+
path: string;
|
|
27
|
+
span: string;
|
|
28
|
+
inDegree: number;
|
|
29
|
+
}
|
|
30
|
+
export interface DirEntry {
|
|
31
|
+
path: string;
|
|
32
|
+
files: number;
|
|
33
|
+
symbols: number;
|
|
34
|
+
languages: string[];
|
|
35
|
+
hubs: Hub[];
|
|
36
|
+
/** True when the >60% split refinement bottomed out on a file that sits
|
|
37
|
+
* directly in the split directory (no deeper subdirectory to split into —
|
|
38
|
+
* see `dirKey`'s doc). In that case `path` IS a file's own full path, not
|
|
39
|
+
* a directory, so `formatDirLine` must not append a trailing "/". False
|
|
40
|
+
* for every real directory group (the overwhelming majority). */
|
|
41
|
+
isFile: boolean;
|
|
42
|
+
}
|
|
43
|
+
/** One scope's own directory breakdown — same shape a single-scope `buildRepoMap`
|
|
44
|
+
* would produce for that scope's nodes alone, dir paths repo-rooted (not
|
|
45
|
+
* scope-relative) so a hit is directly openable without mentally re-prefixing. */
|
|
46
|
+
export interface ScopeGroup {
|
|
47
|
+
/** Display label via `scopeLabel` — "(root)" or "backend/". */
|
|
48
|
+
scope: string;
|
|
49
|
+
/** Sorted by symbol count desc (ties by path asc), capped at `maxDirs`. */
|
|
50
|
+
dirs: DirEntry[];
|
|
51
|
+
/** This scope's directory groups beyond the `maxDirs` cap. */
|
|
52
|
+
dropped: number;
|
|
53
|
+
}
|
|
54
|
+
export interface RepoMap {
|
|
55
|
+
totals: {
|
|
56
|
+
files: number;
|
|
57
|
+
symbols: number;
|
|
58
|
+
edges: number;
|
|
59
|
+
languages: string[];
|
|
60
|
+
};
|
|
61
|
+
/** Single-scope repos: sorted by symbol count desc (ties by path asc), capped
|
|
62
|
+
* at `maxDirs`. Multi-scope repos: empty — use `scopes` instead (see below). */
|
|
63
|
+
dirs: DirEntry[];
|
|
64
|
+
/** Multi-scope repos ONLY (`scopesOfGraph(graph).length > 1`): one entry per
|
|
65
|
+
* scope, scope label as the top-level group key, that scope's own dirs
|
|
66
|
+
* second — a monorepo's sub-projects each read like their own little map
|
|
67
|
+
* instead of being pooled by raw first-path-segment. Absent on single-scope
|
|
68
|
+
* repos (the byte-identical-output regression guarantee: same
|
|
69
|
+
* `scopesOfGraph(g).length <= 1` early branch `ask.ts` uses). */
|
|
70
|
+
scopes?: ScopeGroup[];
|
|
71
|
+
/** Global top hubs by inDegree, ties by name asc then path asc. */
|
|
72
|
+
hotspots: Hub[];
|
|
73
|
+
/** Directory groups beyond the `maxDirs` cap — never silently dropped.
|
|
74
|
+
* Multi-scope repos: always 0 here; see each `ScopeGroup.dropped` instead. */
|
|
75
|
+
dropped: number;
|
|
76
|
+
/** Tokens-saved baseline: every indexed file read whole — the cost of
|
|
77
|
+
* orienting by reading the repo instead of this map. */
|
|
78
|
+
saved?: Savings;
|
|
79
|
+
}
|
|
80
|
+
export interface BuildRepoMapOptions {
|
|
81
|
+
/** Max directory entries kept (the rest are counted into `dropped`). Default 16. */
|
|
82
|
+
maxDirs?: number;
|
|
83
|
+
/** Max hubs listed per directory. Default 3. */
|
|
84
|
+
hubsPerDir?: number;
|
|
85
|
+
/** Max global hotspots. Default 12. */
|
|
86
|
+
hotspots?: number;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Build the repo map from an already-loaded `GraphV1`. Deterministic: same
|
|
90
|
+
* graph in → byte-identical `RepoMap` out (modulo insertion order, which is
|
|
91
|
+
* never observed — everything meaningful is sorted).
|
|
92
|
+
*
|
|
93
|
+
* Single-scope repos (`scopesOfGraph(graph).length <= 1`, the overwhelming
|
|
94
|
+
* majority) take the exact pre-scope-awareness path below — same branch guard
|
|
95
|
+
* `ask.ts` uses, so this is a byte-level regression guarantee. Multi-scope
|
|
96
|
+
* repos group `dirs` by scope FIRST (see `scopes` on `RepoMap`); `dirs` itself
|
|
97
|
+
* is then empty and `scopes` carries the breakdown instead.
|
|
98
|
+
*/
|
|
99
|
+
export declare function buildRepoMap(graph: GraphV1, opts?: BuildRepoMapOptions): RepoMap;
|
|
100
|
+
/**
|
|
101
|
+
* Render a `RepoMap` as the human report. Deterministic (same map in → same
|
|
102
|
+
* string out) and targets <= 6000 chars for a typical repo (the `maxDirs`/
|
|
103
|
+
* `hubsPerDir`/`hotspots` caps in `buildRepoMap` are what keep it bounded on
|
|
104
|
+
* very large graphs).
|
|
105
|
+
*/
|
|
106
|
+
export declare function formatRepoMap(map: RepoMap): string;
|
|
107
|
+
//# sourceMappingURL=map.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../../src/graph/map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,OAAO,EAAU,MAAM,YAAY,CAAC;AAIlD,OAAO,EAA2B,KAAK,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAE9E,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ;;;;qEAIiE;IACjE,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;kFAEkF;AAClF,MAAM,WAAW,UAAU;IACzB,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC/E;oFACgF;IAChF,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB;;;;;qEAKiE;IACjE,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;IACtB,mEAAmE;IACnE,QAAQ,EAAE,GAAG,EAAE,CAAC;IAChB;kFAC8E;IAC9E,OAAO,EAAE,MAAM,CAAC;IAChB;4DACwD;IACxD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,oFAAoF;IACpF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAsID;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAkDpF;AAkCD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAyBlD"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { languageLabelOf } from "./extract.js";
|
|
2
|
+
import { WALK_RELATIONS } from "./relations.js";
|
|
3
|
+
import { scopeLabel, scopeOf, scopesOfGraph } from "./scopes.js";
|
|
4
|
+
import { withSavings, savingsFor } from "../context/savings.js";
|
|
5
|
+
const DEFAULT_MAX_DIRS = 16;
|
|
6
|
+
const DEFAULT_HUBS_PER_DIR = 3;
|
|
7
|
+
const DEFAULT_HOTSPOTS = 12;
|
|
8
|
+
/** A single group must not exceed this share of all file nodes, or it's
|
|
9
|
+
* refined one path-segment deeper — see the module doc. */
|
|
10
|
+
const SPLIT_THRESHOLD = 0.6;
|
|
11
|
+
/** First `depth` path segments, joined back with `/`. Files with fewer
|
|
12
|
+
* segments than `depth` (e.g. a root-level file at depth 2) just use every
|
|
13
|
+
* segment they have — there's nothing deeper to split into. */
|
|
14
|
+
function dirKey(path, depth) {
|
|
15
|
+
const segments = path.split("/");
|
|
16
|
+
return segments.slice(0, Math.min(depth, segments.length)).join("/");
|
|
17
|
+
}
|
|
18
|
+
/** Incoming WALK_RELATIONS edge count per target id — the same "coupling"
|
|
19
|
+
* metric `grep.ts` uses, so a hub in `graft map` means the same thing as a
|
|
20
|
+
* high-inDegree group in `graft grep`. */
|
|
21
|
+
function computeInDegree(graph) {
|
|
22
|
+
const deg = new Map();
|
|
23
|
+
for (const e of graph.edges) {
|
|
24
|
+
if (!WALK_RELATIONS.has(e.relation))
|
|
25
|
+
continue;
|
|
26
|
+
deg.set(e.target, (deg.get(e.target) ?? 0) + 1);
|
|
27
|
+
}
|
|
28
|
+
return deg;
|
|
29
|
+
}
|
|
30
|
+
/** Top `cap` nodes by inDegree (ties broken by name asc, then path asc, for
|
|
31
|
+
* full determinism regardless of the input nodes' array order), dropping
|
|
32
|
+
* anything with zero inbound edges — a hub with no callers isn't a hub. */
|
|
33
|
+
function topHubs(nodes, inDegree, cap) {
|
|
34
|
+
return nodes
|
|
35
|
+
.map((n) => ({ name: n.name, kind: n.kind, path: n.path, span: n.span, inDegree: inDegree.get(n.id) ?? 0 }))
|
|
36
|
+
.filter((h) => h.inDegree > 0)
|
|
37
|
+
.sort((a, b) => b.inDegree - a.inDegree || a.name.localeCompare(b.name) || a.path.localeCompare(b.path))
|
|
38
|
+
.slice(0, cap);
|
|
39
|
+
}
|
|
40
|
+
/** Display labels, not tree-sitter grammars: a `scripts/` tree of `.mjs` files is
|
|
41
|
+
* "javascript" here, not "typescript". See {@link languageLabelOf}. */
|
|
42
|
+
function sortedLanguages(paths) {
|
|
43
|
+
const set = new Set();
|
|
44
|
+
for (const p of paths) {
|
|
45
|
+
const label = languageLabelOf(p);
|
|
46
|
+
if (label)
|
|
47
|
+
set.add(label);
|
|
48
|
+
}
|
|
49
|
+
return [...set].sort();
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The directory-clustering core, factored out so it can run once over the
|
|
53
|
+
* whole graph (single-scope) or once per scope's own node subset
|
|
54
|
+
* (multi-scope) with identical grouping/splitting/sorting rules.
|
|
55
|
+
*
|
|
56
|
+
* `stripPrefix` is the scope prefix to strip before computing depth/split
|
|
57
|
+
* ("" for single-scope / the root scope — a no-op, `relPath` is then the
|
|
58
|
+
* identity function). Reported `DirEntry.path`s are always repo-rooted
|
|
59
|
+
* (the prefix is reattached), never scope-relative — a hit stays directly
|
|
60
|
+
* openable without mentally re-prefixing it.
|
|
61
|
+
*/
|
|
62
|
+
function computeDirEntries(nodes, inDegree, maxDirs, hubsPerDir, stripPrefix) {
|
|
63
|
+
const fileNodes = nodes.filter((n) => n.kind === "file");
|
|
64
|
+
const totalFiles = fileNodes.length;
|
|
65
|
+
const relPath = (path) => stripPrefix === "" ? path : path === stripPrefix ? "" : path.slice(stripPrefix.length + 1);
|
|
66
|
+
// Pass 1: depth-1 file counts (relative to `stripPrefix`), to find (at most
|
|
67
|
+
// one) group over the split threshold — two groups can't both exceed 60%
|
|
68
|
+
// of the same total.
|
|
69
|
+
const depth1FileCounts = new Map();
|
|
70
|
+
for (const n of fileNodes) {
|
|
71
|
+
const key = dirKey(relPath(n.path), 1);
|
|
72
|
+
depth1FileCounts.set(key, (depth1FileCounts.get(key) ?? 0) + 1);
|
|
73
|
+
}
|
|
74
|
+
let splitSegment = null;
|
|
75
|
+
if (totalFiles > 0) {
|
|
76
|
+
for (const [seg, count] of depth1FileCounts) {
|
|
77
|
+
if (count / totalFiles > SPLIT_THRESHOLD) {
|
|
78
|
+
splitSegment = seg;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const depthFor = (rp) => (splitSegment !== null && dirKey(rp, 1) === splitSegment ? 2 : 1);
|
|
84
|
+
// Pass 2: assign every node (file and symbol alike) to its group.
|
|
85
|
+
const groups = new Map();
|
|
86
|
+
for (const n of nodes) {
|
|
87
|
+
const rp = relPath(n.path);
|
|
88
|
+
const key = dirKey(rp, depthFor(rp));
|
|
89
|
+
let g = groups.get(key);
|
|
90
|
+
if (!g) {
|
|
91
|
+
g = { files: [], symbols: [] };
|
|
92
|
+
groups.set(key, g);
|
|
93
|
+
}
|
|
94
|
+
if (n.kind === "file")
|
|
95
|
+
g.files.push(n);
|
|
96
|
+
else
|
|
97
|
+
g.symbols.push(n);
|
|
98
|
+
}
|
|
99
|
+
const fullPath = (relKey) => stripPrefix === "" ? relKey : relKey === "" ? stripPrefix : `${stripPrefix}/${relKey}`;
|
|
100
|
+
// A group's key is a FILE's own path (not a directory) exactly when the
|
|
101
|
+
// split-refinement's depth-2 grouping had nowhere deeper to go and
|
|
102
|
+
// `dirKey` degenerated to the file's full relative path verbatim — see
|
|
103
|
+
// `dirKey`'s doc. Detecting that by membership (rather than re-deriving
|
|
104
|
+
// depth here) stays correct regardless of which pass produced the key.
|
|
105
|
+
const fileRelPaths = new Set(fileNodes.map((f) => relPath(f.path)));
|
|
106
|
+
const dirEntries = [...groups.entries()].map(([relKey, g]) => ({
|
|
107
|
+
path: fullPath(relKey),
|
|
108
|
+
files: g.files.length,
|
|
109
|
+
symbols: g.symbols.length,
|
|
110
|
+
languages: sortedLanguages(g.files.map((f) => f.path)),
|
|
111
|
+
hubs: topHubs(g.symbols, inDegree, hubsPerDir),
|
|
112
|
+
isFile: fileRelPaths.has(relKey),
|
|
113
|
+
}));
|
|
114
|
+
dirEntries.sort((a, b) => b.symbols - a.symbols || a.path.localeCompare(b.path));
|
|
115
|
+
const dropped = Math.max(0, dirEntries.length - maxDirs);
|
|
116
|
+
const dirs = dirEntries.slice(0, maxDirs);
|
|
117
|
+
return { dirs, dropped };
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Build the repo map from an already-loaded `GraphV1`. Deterministic: same
|
|
121
|
+
* graph in → byte-identical `RepoMap` out (modulo insertion order, which is
|
|
122
|
+
* never observed — everything meaningful is sorted).
|
|
123
|
+
*
|
|
124
|
+
* Single-scope repos (`scopesOfGraph(graph).length <= 1`, the overwhelming
|
|
125
|
+
* majority) take the exact pre-scope-awareness path below — same branch guard
|
|
126
|
+
* `ask.ts` uses, so this is a byte-level regression guarantee. Multi-scope
|
|
127
|
+
* repos group `dirs` by scope FIRST (see `scopes` on `RepoMap`); `dirs` itself
|
|
128
|
+
* is then empty and `scopes` carries the breakdown instead.
|
|
129
|
+
*/
|
|
130
|
+
export function buildRepoMap(graph, opts = {}) {
|
|
131
|
+
const maxDirs = opts.maxDirs ?? DEFAULT_MAX_DIRS;
|
|
132
|
+
const hubsPerDir = opts.hubsPerDir ?? DEFAULT_HUBS_PER_DIR;
|
|
133
|
+
const hotspotsN = opts.hotspots ?? DEFAULT_HOTSPOTS;
|
|
134
|
+
const fileNodes = graph.nodes.filter((n) => n.kind === "file");
|
|
135
|
+
const totalFiles = fileNodes.length;
|
|
136
|
+
const inDegree = computeInDegree(graph);
|
|
137
|
+
const scopes = scopesOfGraph(graph);
|
|
138
|
+
let dirs;
|
|
139
|
+
let dropped;
|
|
140
|
+
let scopeGroups;
|
|
141
|
+
if (scopes.length <= 1) {
|
|
142
|
+
const computed = computeDirEntries(graph.nodes, inDegree, maxDirs, hubsPerDir, "");
|
|
143
|
+
dirs = computed.dirs;
|
|
144
|
+
dropped = computed.dropped;
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
// Multi-scope: each scope gets its OWN dir breakdown, computed exactly
|
|
148
|
+
// like the single-scope path above but fed only that scope's node
|
|
149
|
+
// subset (prefix stripped for depth/split math, reattached on output).
|
|
150
|
+
// Grouping by raw first-path-segment instead would pool every scope
|
|
151
|
+
// nested more than one segment deep (e.g. two workspace packages both
|
|
152
|
+
// under `packages/`) into one shared bucket, losing the split entirely.
|
|
153
|
+
dirs = [];
|
|
154
|
+
dropped = 0;
|
|
155
|
+
scopeGroups = scopes.map((s) => {
|
|
156
|
+
const nodesInScope = graph.nodes.filter((n) => scopeOf(n.path, scopes).prefix === s.prefix);
|
|
157
|
+
const computed = computeDirEntries(nodesInScope, inDegree, maxDirs, hubsPerDir, s.prefix);
|
|
158
|
+
return { scope: scopeLabel(s.prefix), dirs: computed.dirs, dropped: computed.dropped };
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
const allSymbols = graph.nodes.filter((n) => n.kind !== "file");
|
|
162
|
+
const hotspots = topHubs(allSymbols, inDegree, hotspotsN);
|
|
163
|
+
return {
|
|
164
|
+
totals: {
|
|
165
|
+
files: totalFiles,
|
|
166
|
+
symbols: allSymbols.length,
|
|
167
|
+
edges: graph.edges.length,
|
|
168
|
+
languages: sortedLanguages(fileNodes.map((f) => f.path)),
|
|
169
|
+
},
|
|
170
|
+
dirs,
|
|
171
|
+
scopes: scopeGroups,
|
|
172
|
+
hotspots,
|
|
173
|
+
dropped,
|
|
174
|
+
saved: savingsFor(graph, fileNodes.map((f) => f.path)),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
const DIR_COL_WIDTH = 20;
|
|
178
|
+
function basenameOf(path) {
|
|
179
|
+
const i = path.lastIndexOf("/");
|
|
180
|
+
return i >= 0 ? path.slice(i + 1) : path;
|
|
181
|
+
}
|
|
182
|
+
function formatDirHub(h) {
|
|
183
|
+
return `${h.name} (${basenameOf(h.path)}, ${h.inDegree}←)`;
|
|
184
|
+
}
|
|
185
|
+
function formatDirLine(d) {
|
|
186
|
+
// `d.path` is only ever a real directory unless the >60% split refinement
|
|
187
|
+
// bottomed out on a file with nowhere deeper to split into (`d.isFile`) —
|
|
188
|
+
// only then is the trailing "/" wrong (it would glue onto the file's own
|
|
189
|
+
// extension, e.g. "auth.ts/").
|
|
190
|
+
const label = (d.isFile ? d.path : `${d.path}/`).padEnd(DIR_COL_WIDTH);
|
|
191
|
+
const counts = `${d.files} files · ${d.symbols} symbols`;
|
|
192
|
+
const hubs = d.hubs.length ? ` hubs: ${d.hubs.map(formatDirHub).join(", ")}` : "";
|
|
193
|
+
return `${label}${counts}${hubs}`;
|
|
194
|
+
}
|
|
195
|
+
function formatHotspot(h) {
|
|
196
|
+
return `${h.name} · ${h.kind} · ${h.path}:${h.span} · ${h.inDegree}←`;
|
|
197
|
+
}
|
|
198
|
+
/** The "+N more directories not shown" note, or null when nothing was dropped. */
|
|
199
|
+
function droppedNote(dropped) {
|
|
200
|
+
if (dropped <= 0)
|
|
201
|
+
return null;
|
|
202
|
+
return `… +${dropped} more director${dropped === 1 ? "y" : "ies"} not shown (raise max-dirs to see more)`;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Render a `RepoMap` as the human report. Deterministic (same map in → same
|
|
206
|
+
* string out) and targets <= 6000 chars for a typical repo (the `maxDirs`/
|
|
207
|
+
* `hubsPerDir`/`hotspots` caps in `buildRepoMap` are what keep it bounded on
|
|
208
|
+
* very large graphs).
|
|
209
|
+
*/
|
|
210
|
+
export function formatRepoMap(map) {
|
|
211
|
+
const { totals } = map;
|
|
212
|
+
const header = `repo map — ${totals.files} files · ${totals.symbols} symbols · ${totals.edges} edges · ${totals.languages.join(", ")}`;
|
|
213
|
+
const lines = [header, ""];
|
|
214
|
+
if (map.scopes) {
|
|
215
|
+
// Multi-scope: scope label as the top-level group heading, that scope's
|
|
216
|
+
// own dirs listed under it — `map.dirs` is empty here, see `buildRepoMap`.
|
|
217
|
+
for (const sg of map.scopes) {
|
|
218
|
+
lines.push(`## ${sg.scope}`);
|
|
219
|
+
for (const d of sg.dirs)
|
|
220
|
+
lines.push(formatDirLine(d));
|
|
221
|
+
const note = droppedNote(sg.dropped);
|
|
222
|
+
if (note)
|
|
223
|
+
lines.push(note);
|
|
224
|
+
lines.push("");
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
for (const d of map.dirs)
|
|
229
|
+
lines.push(formatDirLine(d));
|
|
230
|
+
const note = droppedNote(map.dropped);
|
|
231
|
+
if (note)
|
|
232
|
+
lines.push(note);
|
|
233
|
+
lines.push("");
|
|
234
|
+
}
|
|
235
|
+
lines.push(`hotspots: ${map.hotspots.map(formatHotspot).join(" ")}`);
|
|
236
|
+
const body = lines.join("\n");
|
|
237
|
+
return withSavings(body, map.saved) + "\n";
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"map.js","sourceRoot":"","sources":["../../src/graph/map.ts"],"names":[],"mappings":"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"}
|