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,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `graft viz --export <dir>`: the same viewer, as one self-contained HTML file.
|
|
3
|
+
*
|
|
4
|
+
* This exists so a PR comment has somewhere real to point. A Mermaid diagram in a
|
|
5
|
+
* comment can hold about five circles before it stops being readable, and it can
|
|
6
|
+
* never hold the thing a reviewer actually wants next — click an area, see its
|
|
7
|
+
* dependent symbols at exact `file:line`. Every other tool in this space solved
|
|
8
|
+
* that the same way: keep a small table in the comment and link out to a hosted
|
|
9
|
+
* view. Exporting rather than hosting keeps graft's promise intact — no account, no
|
|
10
|
+
* server, no telemetry; the artifact is a file you can open with `file://`, publish
|
|
11
|
+
* to GitHub Pages, or attach to a build.
|
|
12
|
+
*
|
|
13
|
+
* The output inlines the CSS, the bundled JS and both graphs, because a file served
|
|
14
|
+
* from a Pages subdirectory cannot rely on absolute asset paths (`/app.js` resolves
|
|
15
|
+
* to the domain root, not the PR's folder) and a reader must not need a web server.
|
|
16
|
+
*/
|
|
17
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
18
|
+
import { join } from "node:path";
|
|
19
|
+
import { assembleContextGraph } from "./assemble.js";
|
|
20
|
+
/** The wiring graph as the viewer's endpoint would have served it, or null. */
|
|
21
|
+
function codeGraph(contextDir) {
|
|
22
|
+
const file = join(contextDir, ".graph", "wiring.json");
|
|
23
|
+
if (!existsSync(file))
|
|
24
|
+
return null;
|
|
25
|
+
try {
|
|
26
|
+
const parsed = JSON.parse(readFileSync(file, "utf8"));
|
|
27
|
+
return parsed?.meta?.version === 1 ? parsed : null;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* JSON safe to drop inside a `<script>` element.
|
|
35
|
+
*
|
|
36
|
+
* `</script>` anywhere in the data — a summary quoting HTML, a symbol named after a
|
|
37
|
+
* tag — would close the element and spill the rest of the graph into the page as
|
|
38
|
+
* text. `<` is escaped as a unicode sequence, which is still valid JSON to the
|
|
39
|
+
* parser and inert to the HTML tokenizer.
|
|
40
|
+
*/
|
|
41
|
+
function inlineJson(value) {
|
|
42
|
+
return JSON.stringify(value ?? null)
|
|
43
|
+
.replace(/</g, "\\u003c")
|
|
44
|
+
// Line and paragraph separators are legal in a JSON string and illegal in a
|
|
45
|
+
// JavaScript source line, so an unescaped one is a syntax error at load time.
|
|
46
|
+
.replace(/\u2028/g, "\\u2028")
|
|
47
|
+
.replace(/\u2029/g, "\\u2029");
|
|
48
|
+
}
|
|
49
|
+
/** The two tags this exporter rewrites, verbatim from viewer/index.html. */
|
|
50
|
+
const LINK_TAG = '<link rel="stylesheet" href="/style.css">';
|
|
51
|
+
const SCRIPT_TAG = '<script type="module" src="/app.js"></script>';
|
|
52
|
+
export function exportViz(opts) {
|
|
53
|
+
const html = readFileSync(join(opts.viewerDir, "index.html"), "utf8");
|
|
54
|
+
// Checked on the SOURCE, before anything is inlined. Checking the assembled page
|
|
55
|
+
// instead looks equivalent and is not: a stylesheet comment or a bundled string
|
|
56
|
+
// containing one of these tags would fail an export that was in fact correct.
|
|
57
|
+
if (!html.includes(LINK_TAG) || !html.includes(SCRIPT_TAG)) {
|
|
58
|
+
throw new Error("viz export: viewer/index.html no longer matches the asset tags this exporter rewrites");
|
|
59
|
+
}
|
|
60
|
+
const css = readFileSync(join(opts.viewerDir, "style.css"), "utf8");
|
|
61
|
+
const js = readFileSync(join(opts.viewerDir, "app.js"), "utf8");
|
|
62
|
+
const context = opts.contextGraph ?? assembleContextGraph(opts.contextDir);
|
|
63
|
+
const tabs = opts.tabs ?? ["context", "code", "outline"];
|
|
64
|
+
// Both remaining tabs read the wiring graph, so dropping them drops the payload
|
|
65
|
+
// as well — the point of the option, not a side effect of it.
|
|
66
|
+
const wanted = tabs.includes("code") || tabs.includes("outline");
|
|
67
|
+
const code = wanted ? codeGraph(opts.contextDir) : null;
|
|
68
|
+
// Which tab to open on. The viewer starts on Context, which only a `--deep` build
|
|
69
|
+
// fills: a structural build writes wiring cards (no frontmatter, so nothing to
|
|
70
|
+
// assemble) and INDEX.md, and INDEX alone assembles to a single node. Since the
|
|
71
|
+
// PR path is now structural by design, opening on Context would show a canvas
|
|
72
|
+
// with one dot while the whole wiring graph sat behind an unadvertised tab.
|
|
73
|
+
const codeNodes = code?.nodes?.length ?? 0;
|
|
74
|
+
// A supplied graph is the caller's whole point, so it is always the landing tab.
|
|
75
|
+
const defaultTab = opts.contextGraph || context.nodes.length > 1 || codeNodes === 0 ? "context" : "code";
|
|
76
|
+
const contextGraph = {
|
|
77
|
+
...context,
|
|
78
|
+
meta: { ...context.meta, repoName: opts.repoName, subtitle: opts.subtitle, defaultTab, tabs },
|
|
79
|
+
};
|
|
80
|
+
const data = [
|
|
81
|
+
"<script>window.__GRAFT_DATA__ = {",
|
|
82
|
+
` contextGraph: ${inlineJson(contextGraph)},`,
|
|
83
|
+
` codeGraph: ${inlineJson(code)}`,
|
|
84
|
+
"};</script>",
|
|
85
|
+
].join("\n");
|
|
86
|
+
// Replacer FUNCTIONS, not replacement strings: `$&`, `$\'` and friends are
|
|
87
|
+
// substitution patterns inside a replacement string, and a minified bundle is
|
|
88
|
+
// full of them — the first version of this put the original `<script src>` tag
|
|
89
|
+
// back into the page via a stray `$&` in app.js. A function is taken verbatim.
|
|
90
|
+
const page = html
|
|
91
|
+
.replace(LINK_TAG, () => `<style>\n${css}\n</style>`)
|
|
92
|
+
.replace(SCRIPT_TAG, () => `${data}\n<script type="module">\n${js}\n</script>`);
|
|
93
|
+
mkdirSync(opts.outDir, { recursive: true });
|
|
94
|
+
const file = join(opts.outDir, "index.html");
|
|
95
|
+
writeFileSync(file, page);
|
|
96
|
+
return { file, bytes: Buffer.byteLength(page), contextNodes: contextGraph.nodes.length, codeNodes, defaultTab, tabs };
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/viz/export.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface VizServerOptions {
|
|
2
|
+
contextDir: string;
|
|
3
|
+
viewerDir: string;
|
|
4
|
+
port: number;
|
|
5
|
+
repoName: string;
|
|
6
|
+
wiringOverride?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface VizServer {
|
|
9
|
+
url: string;
|
|
10
|
+
close(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
export declare function startVizServer(opts: VizServerOptions): Promise<VizServer>;
|
|
13
|
+
//# sourceMappingURL=serve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/viz/serve.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AA+BD,wBAAsB,cAAc,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,CAAC,CA4F/E"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `graft viz` local server. Zero runtime dependencies: node:http serves
|
|
3
|
+
* the prebuilt viewer bundle, two JSON endpoints, and an SSE channel that
|
|
4
|
+
* pings the browser whenever the context dir changes on disk.
|
|
5
|
+
*
|
|
6
|
+
* GET / viewer (index.html, app.js, style.css from viewerDir)
|
|
7
|
+
* GET /api/context-graph assembled from .context/*.md on every request
|
|
8
|
+
* GET /api/code-graph .context/graph.json passthrough (404 until generated)
|
|
9
|
+
* GET /events SSE; fs.watch on the context dir, debounced 300ms
|
|
10
|
+
*/
|
|
11
|
+
import { createServer } from "node:http";
|
|
12
|
+
import { readFileSync, existsSync, watch } from "node:fs";
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import { assembleContextGraph } from "./assemble.js";
|
|
15
|
+
import { cmd } from "../brand.js";
|
|
16
|
+
const PORT_ATTEMPTS = 10;
|
|
17
|
+
const WATCH_DEBOUNCE_MS = 300;
|
|
18
|
+
const STATIC_FILES = {
|
|
19
|
+
"/": { file: "index.html", type: "text/html; charset=utf-8" },
|
|
20
|
+
"/index.html": { file: "index.html", type: "text/html; charset=utf-8" },
|
|
21
|
+
"/app.js": { file: "app.js", type: "text/javascript; charset=utf-8" },
|
|
22
|
+
"/style.css": { file: "style.css", type: "text/css; charset=utf-8" },
|
|
23
|
+
};
|
|
24
|
+
function sendJson(res, status, body) {
|
|
25
|
+
res.writeHead(status, { "content-type": "application/json; charset=utf-8" });
|
|
26
|
+
res.end(JSON.stringify(body));
|
|
27
|
+
}
|
|
28
|
+
function listen(server, port) {
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
const onError = (err) => {
|
|
31
|
+
if (err.code === "EADDRINUSE")
|
|
32
|
+
resolve(false);
|
|
33
|
+
else
|
|
34
|
+
reject(err);
|
|
35
|
+
};
|
|
36
|
+
server.once("error", onError);
|
|
37
|
+
server.listen(port, "127.0.0.1", () => {
|
|
38
|
+
server.removeListener("error", onError);
|
|
39
|
+
resolve(true);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
export async function startVizServer(opts) {
|
|
44
|
+
const sseClients = new Set();
|
|
45
|
+
const server = createServer((req, res) => {
|
|
46
|
+
const path = (req.url ?? "/").split("?")[0];
|
|
47
|
+
const asset = STATIC_FILES[path];
|
|
48
|
+
if (asset) {
|
|
49
|
+
const file = join(opts.viewerDir, asset.file);
|
|
50
|
+
if (!existsSync(file)) {
|
|
51
|
+
res.writeHead(404, { "content-type": "text/plain" });
|
|
52
|
+
res.end("viewer bundle missing — run the package build");
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
res.writeHead(200, { "content-type": asset.type });
|
|
56
|
+
res.end(readFileSync(file));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (path === "/api/context-graph") {
|
|
60
|
+
const graph = assembleContextGraph(opts.contextDir);
|
|
61
|
+
sendJson(res, 200, { ...graph, meta: { ...graph.meta, repoName: opts.repoName } });
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (path === "/api/code-graph") {
|
|
65
|
+
const file = join(opts.contextDir, ".graph", "wiring.json");
|
|
66
|
+
const wiringFile = opts.wiringOverride ?? file;
|
|
67
|
+
if (!existsSync(file)) {
|
|
68
|
+
sendJson(res, 404, { error: `no wiring graph in this context dir — run \`${cmd("graft build")}\` first` });
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
const parsed = JSON.parse(readFileSync(wiringFile, "utf8"));
|
|
73
|
+
if (parsed?.meta?.version !== 1) {
|
|
74
|
+
sendJson(res, 404, { error: `wiring.json has an unsupported version — regenerate with \`${cmd("graft build")}\`` });
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
sendJson(res, 200, parsed);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
sendJson(res, 404, { error: `wiring.json is unreadable — regenerate with \`${cmd("graft build")}\`` });
|
|
81
|
+
}
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (path === "/events") {
|
|
85
|
+
res.writeHead(200, {
|
|
86
|
+
"content-type": "text/event-stream",
|
|
87
|
+
"cache-control": "no-cache",
|
|
88
|
+
connection: "keep-alive",
|
|
89
|
+
});
|
|
90
|
+
res.write(": connected\n\n");
|
|
91
|
+
sseClients.add(res);
|
|
92
|
+
req.on("close", () => sseClients.delete(res));
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
res.writeHead(404, { "content-type": "text/plain" });
|
|
96
|
+
res.end("not found");
|
|
97
|
+
});
|
|
98
|
+
let port = opts.port;
|
|
99
|
+
let bound = false;
|
|
100
|
+
for (let i = 0; i < PORT_ATTEMPTS && !bound; i++) {
|
|
101
|
+
port = opts.port + i;
|
|
102
|
+
bound = await listen(server, port);
|
|
103
|
+
}
|
|
104
|
+
if (!bound) {
|
|
105
|
+
throw new Error(`no free port in ${opts.port}–${opts.port + PORT_ATTEMPTS - 1}`);
|
|
106
|
+
}
|
|
107
|
+
let watcher;
|
|
108
|
+
let debounce;
|
|
109
|
+
if (existsSync(opts.contextDir)) {
|
|
110
|
+
watcher = watch(opts.contextDir, () => {
|
|
111
|
+
clearTimeout(debounce);
|
|
112
|
+
debounce = setTimeout(() => {
|
|
113
|
+
for (const client of sseClients)
|
|
114
|
+
client.write("data: change\n\n");
|
|
115
|
+
}, WATCH_DEBOUNCE_MS);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
url: `http://127.0.0.1:${port}`,
|
|
120
|
+
close() {
|
|
121
|
+
clearTimeout(debounce);
|
|
122
|
+
watcher?.close();
|
|
123
|
+
for (const client of sseClients)
|
|
124
|
+
client.end();
|
|
125
|
+
sseClients.clear();
|
|
126
|
+
return new Promise((resolve, reject) => server.close((err) => (err ? reject(err) : resolve())));
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=serve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/viz/serve.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,117 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trail-code",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.28.0-semantic.3",
|
|
4
|
+
"description": "Build a repo's context graph as a folder of linked markdown files: a local, regenerable cache that every query keeps in sync with your code. (fork of @trailhq/trail-code: semantic search, --include-md, knowledge repos)",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ai",
|
|
7
|
+
"agents",
|
|
8
|
+
"knowledge-graph",
|
|
9
|
+
"context",
|
|
10
|
+
"codebase",
|
|
11
|
+
"llm",
|
|
12
|
+
"graft"
|
|
13
|
+
],
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/jastorgalj/Trail-Code.git"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://github.com/jastorgalj/Trail-Code#readme",
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/jastorgalj/Trail-Code/issues"
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"type": "module",
|
|
27
|
+
"main": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"import": "./dist/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./package.json": "./package.json"
|
|
35
|
+
},
|
|
36
|
+
"bin": {
|
|
37
|
+
"graft": "dist/bin/graft.js",
|
|
38
|
+
"trail": "dist/bin/trail.js"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist",
|
|
42
|
+
"scripts",
|
|
43
|
+
"README.md",
|
|
44
|
+
"LICENSE"
|
|
45
|
+
],
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build": "tsc -p tsconfig.json && tsc -p viewer/tsconfig.json && node scripts/build-viewer.mjs && node scripts/vendor-grammars.mjs",
|
|
48
|
+
"dev": "tsc -p tsconfig.json --watch",
|
|
49
|
+
"cli": "tsx src/cli.ts",
|
|
50
|
+
"test": "node scripts/run-tests.mjs",
|
|
51
|
+
"prepare": "npm run build && node scripts/stamp-telemetry-key.mjs",
|
|
52
|
+
"prepublishOnly": "npm run build",
|
|
53
|
+
"postinstall": "node scripts/postinstall.mjs"
|
|
54
|
+
},
|
|
55
|
+
"engines": {
|
|
56
|
+
"node": "^20.16.0 || >=22.3.0"
|
|
57
|
+
},
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"@anthropic-ai/sdk": "^0.133.0",
|
|
60
|
+
"@huggingface/transformers": "^3.0.0",
|
|
61
|
+
"better-sqlite3": "^13.0.3",
|
|
62
|
+
"sqlite-vec": "^0.1.9",
|
|
63
|
+
"commander": "^15.0.0",
|
|
64
|
+
"dotenv": "^18.0.7",
|
|
65
|
+
"gray-matter": "^4.0.3",
|
|
66
|
+
"openai": "^7.8.0",
|
|
67
|
+
"tree-sitter-wasm": "^2.0.4",
|
|
68
|
+
"vscode-jsonrpc": "^8.2.1",
|
|
69
|
+
"vscode-languageserver-protocol": "^3.18.2",
|
|
70
|
+
"web-tree-sitter": "^0.27.1",
|
|
71
|
+
"web-tree-sitter-depth": "npm:web-tree-sitter@0.22.2"
|
|
72
|
+
},
|
|
73
|
+
"devDependencies": {
|
|
74
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
75
|
+
"@types/d3-force": "^3.0.10",
|
|
76
|
+
"@types/node": "^26.1.0",
|
|
77
|
+
"d3-force": "^3.0.0",
|
|
78
|
+
"esbuild": "^0.28.1",
|
|
79
|
+
"node-gyp": "^12.4.0",
|
|
80
|
+
"tree-sitter": "^0.21.1",
|
|
81
|
+
"tree-sitter-go": "^0.23.4",
|
|
82
|
+
"tree-sitter-java": "^0.23.5",
|
|
83
|
+
"tree-sitter-kotlin": "^0.3.8",
|
|
84
|
+
"tree-sitter-php": "^0.23.4",
|
|
85
|
+
"tree-sitter-python": "^0.21.0",
|
|
86
|
+
"tree-sitter-r": "npm:@davisvaughan/tree-sitter-r@^1.3.0",
|
|
87
|
+
"tree-sitter-swift": "^0.7.1",
|
|
88
|
+
"tree-sitter-typescript": "^0.23.2",
|
|
89
|
+
"tsx": "^4.22.4",
|
|
90
|
+
"typescript": "^6.0.3"
|
|
91
|
+
},
|
|
92
|
+
"allowScripts": {
|
|
93
|
+
"tree-sitter@0.21.1": true,
|
|
94
|
+
"tree-sitter-typescript@0.23.2": true,
|
|
95
|
+
"tree-sitter-python@0.21.0": true,
|
|
96
|
+
"tree-sitter-go@0.23.4": true,
|
|
97
|
+
"tree-sitter-javascript@0.23.1": true,
|
|
98
|
+
"tree-sitter-java@0.23.5": true,
|
|
99
|
+
"esbuild@0.28.2": true,
|
|
100
|
+
"fsevents@2.3.3": true,
|
|
101
|
+
"tree-sitter-kotlin@0.3.8": true,
|
|
102
|
+
"tree-sitter-php@0.23.12": true,
|
|
103
|
+
"@davisvaughan/tree-sitter-r@1.3.0": true,
|
|
104
|
+
"tree-sitter-swift@0.7.1": true,
|
|
105
|
+
"onnxruntime-node": true,
|
|
106
|
+
"protobufjs": true,
|
|
107
|
+
"better-sqlite3": true
|
|
108
|
+
},
|
|
109
|
+
"overrides": {
|
|
110
|
+
"tree-sitter-swift": {
|
|
111
|
+
"tree-sitter": "$tree-sitter"
|
|
112
|
+
},
|
|
113
|
+
"js-yaml": {
|
|
114
|
+
"argparse": "^2.0.1"
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compiles the depth-tier grammars whose npm package ships no .wasm into
|
|
3
|
+
* src/graph/grammars/, and records every depth grammar's .wasm in grammars.json.
|
|
4
|
+
*
|
|
5
|
+
* The depth tier parses on web-tree-sitter (src/graph/depth-parser.ts) with the
|
|
6
|
+
* exact grammar versions the native addons were built from. Most of those packages
|
|
7
|
+
* ship a .wasm next to the addon; python, kotlin and swift don't, so this builds
|
|
8
|
+
* theirs from the package's own src/ (parser.c and scanner.c, never regenerated
|
|
9
|
+
* from grammar.js) with the tree-sitter CLI. The output is committed, so a build
|
|
10
|
+
* needs no compiler: `npm run build` only copies it (scripts/vendor-grammars.mjs).
|
|
11
|
+
*
|
|
12
|
+
* swift's scanner relies on behaviour wasm32 doesn't share with the native addon,
|
|
13
|
+
* so its copy is patched first (PATCHES, below). Without the patches its parses
|
|
14
|
+
* go wrong after the first file.
|
|
15
|
+
*
|
|
16
|
+
* grammars.json pins the bytes test/depth-parity.ts last passed with: for each
|
|
17
|
+
* .wasm, the package version and the file's sha256 (and for a built one, the hash
|
|
18
|
+
* of the C it was built from). test/depth-grammars.test.ts fails when any of that
|
|
19
|
+
* drifts, so bumping a grammar package means running this, then the parity check
|
|
20
|
+
* against real repos.
|
|
21
|
+
*
|
|
22
|
+
* The build is reproducible: the same package and CLI give the same bytes. The CLI
|
|
23
|
+
* fetches wasi-sdk on first use (about 600 MB under ~/.cache/tree-sitter).
|
|
24
|
+
*
|
|
25
|
+
* Usage: node scripts/build-grammar-wasm.mjs build all three, record all
|
|
26
|
+
* node scripts/build-grammar-wasm.mjs --record record only, build nothing
|
|
27
|
+
*/
|
|
28
|
+
import { execFileSync } from "node:child_process";
|
|
29
|
+
import { createHash } from "node:crypto";
|
|
30
|
+
import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
31
|
+
import { createRequire } from "node:module";
|
|
32
|
+
import { dirname, join } from "node:path";
|
|
33
|
+
import { fileURLToPath } from "node:url";
|
|
34
|
+
import { GRAMMARS } from "./vendor-grammars.mjs";
|
|
35
|
+
|
|
36
|
+
/** The tree-sitter CLI that compiles them. */
|
|
37
|
+
const CLI = "0.27.1";
|
|
38
|
+
|
|
39
|
+
/** Source edits applied to the copy that is compiled, never to node_modules:
|
|
40
|
+
* [file under src/, exact text, replacement]. */
|
|
41
|
+
export const PATCHES = {
|
|
42
|
+
"tree-sitter-swift": [
|
|
43
|
+
// The `!` operator's suppressor mask is bit 32 of a uint64_t; wasm32's
|
|
44
|
+
// `unsigned long` is 32 bits.
|
|
45
|
+
["scanner.c", "1UL << FAKE_TRY_BANG", "1ULL << FAKE_TRY_BANG"],
|
|
46
|
+
// The mask is tested with `1 << suppressor`, an int shift past bit 31. The
|
|
47
|
+
// native addon is built at -O3, where that undefined shift vectorizes into a
|
|
48
|
+
// test that passes for every index: the addon drops the scanner's `!` whenever
|
|
49
|
+
// any symbol is valid, which is always, since `!` itself is. So `x!.y` parses
|
|
50
|
+
// its `!` with the grammar's own lexer. Dropping the test reproduces that.
|
|
51
|
+
["scanner.c", "if (!(suppressing_symbols & 1 << suppressor)) {", "if (0) {"],
|
|
52
|
+
// calloc(0, …) may return NULL in wasm, and the scanner then keeps its state at
|
|
53
|
+
// address 0, where other writes clobber it.
|
|
54
|
+
["scanner.c", "calloc(0, sizeof(struct ScannerState))", "calloc(1, sizeof(struct ScannerState))"],
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const root = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
59
|
+
const builtDir = join(root, "src", "graph", "grammars");
|
|
60
|
+
const require = createRequire(join(root, "package.json"));
|
|
61
|
+
|
|
62
|
+
/** sha256 over a grammar's C sources as published, the part the .wasm is made of. */
|
|
63
|
+
export function sourceHash(pkgDir) {
|
|
64
|
+
const h = createHash("sha256");
|
|
65
|
+
for (const f of ["parser.c", "scanner.c"]) {
|
|
66
|
+
const p = join(pkgDir, "src", f);
|
|
67
|
+
if (existsSync(p)) h.update(f).update(readFileSync(p));
|
|
68
|
+
}
|
|
69
|
+
return h.digest("hex");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export const sha256 = (path) => createHash("sha256").update(readFileSync(path)).digest("hex");
|
|
73
|
+
|
|
74
|
+
function compile(module, pkg, file) {
|
|
75
|
+
// A copy, so neither the patches nor the CLI's build files touch node_modules.
|
|
76
|
+
const work = join(root, "node_modules", ".cache", "grammar-wasm", module);
|
|
77
|
+
rmSync(work, { recursive: true, force: true });
|
|
78
|
+
mkdirSync(work, { recursive: true });
|
|
79
|
+
for (const f of ["src", "grammar.js", "package.json", "tree-sitter.json"]) {
|
|
80
|
+
if (existsSync(join(pkg, f))) cpSync(join(pkg, f), join(work, f), { recursive: true });
|
|
81
|
+
}
|
|
82
|
+
for (const [name, from, to] of PATCHES[module] ?? []) {
|
|
83
|
+
const p = join(work, "src", name);
|
|
84
|
+
const text = readFileSync(p, "utf8");
|
|
85
|
+
if (!text.includes(from)) throw new Error(`${module}: patch target not found in src/${name}: ${from}`);
|
|
86
|
+
writeFileSync(p, text.replace(from, to));
|
|
87
|
+
}
|
|
88
|
+
execFileSync("npx", ["--yes", `tree-sitter-cli@${CLI}`, "build", "--wasm", "-o", join(builtDir, file), "."], {
|
|
89
|
+
cwd: work,
|
|
90
|
+
stdio: "inherit",
|
|
91
|
+
shell: process.platform === "win32",
|
|
92
|
+
});
|
|
93
|
+
rmSync(work, { recursive: true, force: true });
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
97
|
+
const recordOnly = process.argv.includes("--record");
|
|
98
|
+
const manifest = {};
|
|
99
|
+
for (const { module, files, built } of GRAMMARS) {
|
|
100
|
+
const pkg = dirname(require.resolve(`${module}/package.json`));
|
|
101
|
+
const { version } = require(`${module}/package.json`);
|
|
102
|
+
for (const file of files) {
|
|
103
|
+
if (built && !recordOnly) compile(module, pkg, file);
|
|
104
|
+
const path = built ? join(builtDir, file) : join(pkg, file);
|
|
105
|
+
manifest[file] = built
|
|
106
|
+
? { module, version, cli: CLI, source: sourceHash(pkg), patches: (PATCHES[module] ?? []).length, sha256: sha256(path) }
|
|
107
|
+
: { module, version, sha256: sha256(path) };
|
|
108
|
+
console.log(`${built && !recordOnly ? "built" : "recorded"} ${file} (${module}@${version})`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
writeFileSync(join(builtDir, "grammars.json"), JSON.stringify(manifest, null, 2) + "\n");
|
|
112
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bundles the viewer into dist/viewer/ (app.js via esbuild + copied static
|
|
3
|
+
* assets). Runs as part of `npm run build`; the bundle ships in the package
|
|
4
|
+
* so `graft viz` needs no install or build step at runtime.
|
|
5
|
+
*/
|
|
6
|
+
import { build } from "esbuild";
|
|
7
|
+
import { mkdirSync, copyFileSync, readdirSync } from "node:fs";
|
|
8
|
+
import { dirname, join } from "node:path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
|
|
11
|
+
const root = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
12
|
+
const outDir = join(root, "dist", "viewer");
|
|
13
|
+
mkdirSync(outDir, { recursive: true });
|
|
14
|
+
|
|
15
|
+
await build({
|
|
16
|
+
entryPoints: [join(root, "viewer", "main.ts")],
|
|
17
|
+
bundle: true,
|
|
18
|
+
minify: true,
|
|
19
|
+
format: "esm",
|
|
20
|
+
target: "es2022",
|
|
21
|
+
outfile: join(outDir, "app.js"),
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
for (const asset of ["index.html", "style.css"]) {
|
|
25
|
+
copyFileSync(join(root, "viewer", asset), join(outDir, asset));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
console.log("viewer bundle → dist/viewer/");
|
|
29
|
+
|
|
30
|
+
// The generic (breadth) tier's tags.scm query files are runtime assets — tsc
|
|
31
|
+
// doesn't emit non-TS files, so copy them into dist so the published package
|
|
32
|
+
// (which ships `dist` only) can load them. generic.ts resolves dist/graph/queries
|
|
33
|
+
// first, then falls back to src/graph/queries for local dev.
|
|
34
|
+
const scmSrc = join(root, "src", "graph", "queries");
|
|
35
|
+
const scmOut = join(root, "dist", "graph", "queries");
|
|
36
|
+
mkdirSync(scmOut, { recursive: true });
|
|
37
|
+
let scmCount = 0;
|
|
38
|
+
for (const f of readdirSync(scmSrc)) {
|
|
39
|
+
if (f.endsWith(".scm")) {
|
|
40
|
+
copyFileSync(join(scmSrc, f), join(scmOut, f));
|
|
41
|
+
scmCount++;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
console.log(`grammar queries → dist/graph/queries/ (${scmCount} .scm)`);
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph-quality report + invariant check for a built graph (`graft/.graph/wiring.json`).
|
|
3
|
+
*
|
|
4
|
+
* node scripts/graph-quality.mjs <repo-dir-or-wiring.json> [--json] [--strict]
|
|
5
|
+
*
|
|
6
|
+
* Tier-0 of the quality strategy: needs no external oracle. Reports the graph's
|
|
7
|
+
* shape (nodes by kind/origin, edges by relation/confidence, resolution rate) and
|
|
8
|
+
* asserts structural INVARIANTS that must always hold:
|
|
9
|
+
* - no dangling edge endpoints (every source is a node; every target is a node
|
|
10
|
+
* or a deliberately-unresolved external string)
|
|
11
|
+
* - valid spans (`Lx-Ly`, x<=y, within file line count where known)
|
|
12
|
+
* - unique node ids; non-empty names; kinds in the allowed set
|
|
13
|
+
* - no self-loop call edges
|
|
14
|
+
* Exits non-zero with --strict when any invariant fails (CI gate).
|
|
15
|
+
*/
|
|
16
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
17
|
+
import { join } from "node:path";
|
|
18
|
+
|
|
19
|
+
const KINDS = new Set(["file","class","function","method","interface","type","enum","struct","module","constant","variable"]);
|
|
20
|
+
const RELATIONS = new Set(["contains","calls","imports","references","implements","extends"]);
|
|
21
|
+
const CONFIDENCE = new Set(["lsp_resolved","lsp_dispatch","extracted","inferred"]);
|
|
22
|
+
|
|
23
|
+
const arg = process.argv[2] ?? ".";
|
|
24
|
+
const json = process.argv.includes("--json");
|
|
25
|
+
const strict = process.argv.includes("--strict");
|
|
26
|
+
const wpath = arg.endsWith(".json") ? arg
|
|
27
|
+
: [join(arg, "graft", ".graph", "wiring.json"), join(arg, "graft", "wiring.json")].find(existsSync);
|
|
28
|
+
if (!wpath || !existsSync(wpath)) { console.error(`no graph found at ${arg} (run \`graft build\` first)`); process.exit(2); }
|
|
29
|
+
|
|
30
|
+
const g = JSON.parse(readFileSync(wpath, "utf8"));
|
|
31
|
+
const nodes = g.nodes ?? [], edges = g.edges ?? [];
|
|
32
|
+
const ids = new Set(nodes.map((n) => n.id));
|
|
33
|
+
|
|
34
|
+
const bump = (m, k) => m.set(k, (m.get(k) ?? 0) + 1);
|
|
35
|
+
const byKind = new Map(), byOrigin = new Map(), byRel = new Map(), byConf = new Map();
|
|
36
|
+
for (const n of nodes) { bump(byKind, n.kind); bump(byOrigin, n.origin ?? "?"); }
|
|
37
|
+
for (const e of edges) { bump(byRel, e.relation); bump(byConf, e.confidence); }
|
|
38
|
+
|
|
39
|
+
// ── invariants ──
|
|
40
|
+
const problems = [];
|
|
41
|
+
const seen = new Set();
|
|
42
|
+
for (const n of nodes) {
|
|
43
|
+
if (seen.has(n.id)) problems.push(`dup id: ${n.id}`); seen.add(n.id);
|
|
44
|
+
if (!n.name || !String(n.name).trim()) problems.push(`empty name: ${n.id}`);
|
|
45
|
+
if (!KINDS.has(n.kind)) problems.push(`bad kind '${n.kind}': ${n.id}`);
|
|
46
|
+
const m = /^L(\d+)-L(\d+)$/.exec(n.span ?? "");
|
|
47
|
+
if (!m) problems.push(`bad span '${n.span}': ${n.id}`);
|
|
48
|
+
else if (Number(m[1]) > Number(m[2])) problems.push(`inverted span ${n.span}: ${n.id}`);
|
|
49
|
+
}
|
|
50
|
+
// an edge target may be a node id OR a deliberately-unresolved external string
|
|
51
|
+
// (import specifier / bare heritage name / unresolved Java annotation type);
|
|
52
|
+
// only calls/contains must point at real nodes.
|
|
53
|
+
let dangling = 0, selfLoops = 0, unresolvedExternal = 0;
|
|
54
|
+
for (const e of edges) {
|
|
55
|
+
if (!RELATIONS.has(e.relation)) problems.push(`bad relation '${e.relation}'`);
|
|
56
|
+
if (!CONFIDENCE.has(e.confidence)) problems.push(`bad confidence '${e.confidence}'`);
|
|
57
|
+
if (!ids.has(e.source)) { problems.push(`dangling source: ${e.source}`); dangling++; }
|
|
58
|
+
const targetIsNode = ids.has(e.target);
|
|
59
|
+
if (!targetIsNode) {
|
|
60
|
+
if (e.relation === "imports" || e.relation === "extends" || e.relation === "implements" || e.relation === "references") unresolvedExternal++;
|
|
61
|
+
else { problems.push(`dangling ${e.relation} target: ${e.source} → ${e.target}`); dangling++; }
|
|
62
|
+
}
|
|
63
|
+
if (e.relation === "calls" && e.source === e.target) selfLoops++;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ── resolution / connectivity metrics ──
|
|
67
|
+
const calls = edges.filter((e) => e.relation === "calls");
|
|
68
|
+
const resolvedCalls = calls.filter((e) => ids.has(e.target)).length;
|
|
69
|
+
const withEdge = new Set();
|
|
70
|
+
for (const e of edges) { if (e.relation !== "contains") { withEdge.add(e.source); if (ids.has(e.target)) withEdge.add(e.target); } }
|
|
71
|
+
const symbolNodes = nodes.filter((n) => n.kind !== "file");
|
|
72
|
+
const orphans = symbolNodes.filter((n) => !withEdge.has(n.id)).length;
|
|
73
|
+
|
|
74
|
+
const report = {
|
|
75
|
+
graph: wpath,
|
|
76
|
+
nodes: nodes.length,
|
|
77
|
+
symbolNodes: symbolNodes.length,
|
|
78
|
+
edges: edges.length,
|
|
79
|
+
byKind: Object.fromEntries([...byKind].sort((a,b)=>b[1]-a[1])),
|
|
80
|
+
byOrigin: Object.fromEntries(byOrigin),
|
|
81
|
+
byRelation: Object.fromEntries(byRel),
|
|
82
|
+
byConfidence: Object.fromEntries(byConf),
|
|
83
|
+
resolution: {
|
|
84
|
+
calls: calls.length,
|
|
85
|
+
resolvedToNode: resolvedCalls,
|
|
86
|
+
resolvedPct: calls.length ? Math.round((resolvedCalls / calls.length) * 100) : null,
|
|
87
|
+
unresolvedExternalImports: unresolvedExternal,
|
|
88
|
+
},
|
|
89
|
+
connectivity: {
|
|
90
|
+
orphanSymbolNodes: orphans,
|
|
91
|
+
orphanPct: symbolNodes.length ? Math.round((orphans / symbolNodes.length) * 100) : null,
|
|
92
|
+
},
|
|
93
|
+
invariants: {
|
|
94
|
+
ok: problems.length === 0,
|
|
95
|
+
danglingEdges: dangling,
|
|
96
|
+
selfLoopCalls: selfLoops,
|
|
97
|
+
violations: problems.length,
|
|
98
|
+
sample: problems.slice(0, 15),
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
if (json) { console.log(JSON.stringify(report, null, 2)); }
|
|
103
|
+
else {
|
|
104
|
+
const p = report;
|
|
105
|
+
console.log(`graph-quality — ${p.graph}`);
|
|
106
|
+
console.log(` nodes ${p.nodes} (${p.symbolNodes} symbols) · edges ${p.edges}`);
|
|
107
|
+
console.log(` kinds: ${Object.entries(p.byKind).map(([k,v])=>`${k}=${v}`).join(" ")}`);
|
|
108
|
+
console.log(` origin: ${Object.entries(p.byOrigin).map(([k,v])=>`${k}=${v}`).join(" ")}`);
|
|
109
|
+
console.log(` relations: ${Object.entries(p.byRelation).map(([k,v])=>`${k}=${v}`).join(" ")}`);
|
|
110
|
+
console.log(` confidence: ${Object.entries(p.byConfidence).map(([k,v])=>`${k}=${v}`).join(" ")}`);
|
|
111
|
+
console.log(` calls resolved: ${p.resolution.resolvedToNode}/${p.resolution.calls} (${p.resolution.resolvedPct}%)`);
|
|
112
|
+
console.log(` orphan symbols: ${p.connectivity.orphanSymbolNodes}/${p.symbolNodes} (${p.connectivity.orphanPct}%)`);
|
|
113
|
+
console.log(` INVARIANTS: ${p.invariants.ok ? "OK ✓" : `FAIL ✗ (${p.invariants.violations} violations, ${p.invariants.danglingEdges} dangling)`}`);
|
|
114
|
+
if (!p.invariants.ok) for (const s of p.invariants.sample) console.log(` - ${s}`);
|
|
115
|
+
if (p.invariants.selfLoopCalls) console.log(` note: ${p.invariants.selfLoopCalls} self-loop calls`);
|
|
116
|
+
}
|
|
117
|
+
if (strict && !report.invariants.ok) process.exit(1);
|