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,2 @@
|
|
|
1
|
+
var mt={part_of:"structure",contains:"structure",uses:"dependency",depends_on:"dependency",calls:"dependency",imports:"dependency",produces:"dependency",configures:"dependency",validates:"dependency",extends:"contract",implements:"contract",references:"association"};function F(e){return mt[e]??"association"}var $e={structure:85,dependency:145,contract:150,association:185};function ee(e){return F(e)==="structure"?"part of":e==="calls"||e==="uses"||e==="depends_on"||e==="imports"?"uses":e.replace(/_/g," ")}var Le={"part of":"where does this live? (contains, part of)",uses:"what breaks if the target changes? (calls, uses, depends on, imports)",produces:"where does this output come from?",configures:"what changes its behavior without a code change?",validates:"what checks or judges this? (tests, drift checks, scoring)",extends:"what contract must this honor? (inheritance)",implements:"what contract must this honor? (interface)",references:"mentioned but never called \u2014 possible dead coupling"},gt={system:"--sys",concept:"--con",file:"--fil",api:"--api",changed:"--fil",affected:"--sys"},vt={file:"--k-file",class:"--k-class",function:"--k-fn",method:"--k-method",interface:"--k-iface",type:"--k-type",enum:"--k-enum"};function R(e,t){return(e==="code"?vt:gt)[t]??"--edge"}function k(e){return getComputedStyle(document.documentElement).getPropertyValue(e).trim()}var X=globalThis.__GRAFT_DATA__;async function Ae(){return X?.contextGraph?X.contextGraph:await(await fetch("/api/context-graph")).json()}async function Te(){let e;if(X){if(!X.codeGraph)return null;e=X.codeGraph}else{let r=await fetch("/api/code-graph");if(!r.ok)return null;e=await r.json()}let t=e.nodes.map(r=>({id:r.id,name:r.name,type:r.kind,summary:r.summary??r.signature??"",sources:[`${r.path} \xB7 ${r.span}`]})),n=new Set(t.map(r=>r.id)),i=e.edges.filter(r=>n.has(r.source)&&n.has(r.target)).map(r=>({source:r.source,target:r.target,relation:r.relation,confidence:r.confidence}));return{meta:{nodeCount:t.length,edgeCount:i.length},nodes:t,edges:i}}function Se(e){if(X)return;let t=new EventSource("/events");t.onmessage=n=>{n.data==="change"&&e()}}function ce(e,t){var n,i=1;e==null&&(e=0),t==null&&(t=0);function r(){var o,a=n.length,h,d=0,s=0;for(o=0;o<a;++o)h=n[o],d+=h.x,s+=h.y;for(d=(d/a-e)*i,s=(s/a-t)*i,o=0;o<a;++o)h=n[o],h.x-=d,h.y-=s}return r.initialize=function(o){n=o},r.x=function(o){return arguments.length?(e=+o,r):e},r.y=function(o){return arguments.length?(t=+o,r):t},r.strength=function(o){return arguments.length?(i=+o,r):i},r}function Ge(e){let t=+this._x.call(null,e),n=+this._y.call(null,e);return Ve(this.cover(t,n),t,n,e)}function Ve(e,t,n,i){if(isNaN(t)||isNaN(n))return e;var r,o=e._root,a={data:i},h=e._x0,d=e._y0,s=e._x1,l=e._y1,g,c,f,v,p,u,m,y;if(!o)return e._root=a,e;for(;o.length;)if((p=t>=(g=(h+s)/2))?h=g:s=g,(u=n>=(c=(d+l)/2))?d=c:l=c,r=o,!(o=o[m=u<<1|p]))return r[m]=a,e;if(f=+e._x.call(null,o.data),v=+e._y.call(null,o.data),t===f&&n===v)return a.next=o,r?r[m]=a:e._root=a,e;do r=r?r[m]=new Array(4):e._root=new Array(4),(p=t>=(g=(h+s)/2))?h=g:s=g,(u=n>=(c=(d+l)/2))?d=c:l=c;while((m=u<<1|p)===(y=(v>=c)<<1|f>=g));return r[y]=o,r[m]=a,e}function ze(e){var t,n,i=e.length,r,o,a=new Array(i),h=new Array(i),d=1/0,s=1/0,l=-1/0,g=-1/0;for(n=0;n<i;++n)isNaN(r=+this._x.call(null,t=e[n]))||isNaN(o=+this._y.call(null,t))||(a[n]=r,h[n]=o,r<d&&(d=r),r>l&&(l=r),o<s&&(s=o),o>g&&(g=o));if(d>l||s>g)return this;for(this.cover(d,s).cover(l,g),n=0;n<i;++n)Ve(this,a[n],h[n],e[n]);return this}function De(e,t){if(isNaN(e=+e)||isNaN(t=+t))return this;var n=this._x0,i=this._y0,r=this._x1,o=this._y1;if(isNaN(n))r=(n=Math.floor(e))+1,o=(i=Math.floor(t))+1;else{for(var a=r-n||1,h=this._root,d,s;n>e||e>=r||i>t||t>=o;)switch(s=(t<i)<<1|e<n,d=new Array(4),d[s]=h,h=d,a*=2,s){case 0:r=n+a,o=i+a;break;case 1:n=r-a,o=i+a;break;case 2:r=n+a,i=o-a;break;case 3:n=r-a,i=o-a;break}this._root&&this._root.length&&(this._root=h)}return this._x0=n,this._y0=i,this._x1=r,this._y1=o,this}function He(){var e=[];return this.visit(function(t){if(!t.length)do e.push(t.data);while(t=t.next)}),e}function Oe(e){return arguments.length?this.cover(+e[0][0],+e[0][1]).cover(+e[1][0],+e[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]}function L(e,t,n,i,r){this.node=e,this.x0=t,this.y0=n,this.x1=i,this.y1=r}function Ie(e,t,n){var i,r=this._x0,o=this._y0,a,h,d,s,l=this._x1,g=this._y1,c=[],f=this._root,v,p;for(f&&c.push(new L(f,r,o,l,g)),n==null?n=1/0:(r=e-n,o=t-n,l=e+n,g=t+n,n*=n);v=c.pop();)if(!(!(f=v.node)||(a=v.x0)>l||(h=v.y0)>g||(d=v.x1)<r||(s=v.y1)<o))if(f.length){var u=(a+d)/2,m=(h+s)/2;c.push(new L(f[3],u,m,d,s),new L(f[2],a,m,u,s),new L(f[1],u,h,d,m),new L(f[0],a,h,u,m)),(p=(t>=m)<<1|e>=u)&&(v=c[c.length-1],c[c.length-1]=c[c.length-1-p],c[c.length-1-p]=v)}else{var y=e-+this._x.call(null,f.data),b=t-+this._y.call(null,f.data),x=y*y+b*b;if(x<n){var M=Math.sqrt(n=x);r=e-M,o=t-M,l=e+M,g=t+M,i=f.data}}return i}function Re(e){if(isNaN(l=+this._x.call(null,e))||isNaN(g=+this._y.call(null,e)))return this;var t,n=this._root,i,r,o,a=this._x0,h=this._y0,d=this._x1,s=this._y1,l,g,c,f,v,p,u,m;if(!n)return this;if(n.length)for(;;){if((v=l>=(c=(a+d)/2))?a=c:d=c,(p=g>=(f=(h+s)/2))?h=f:s=f,t=n,!(n=n[u=p<<1|v]))return this;if(!n.length)break;(t[u+1&3]||t[u+2&3]||t[u+3&3])&&(i=t,m=u)}for(;n.data!==e;)if(r=n,!(n=n.next))return this;return(o=n.next)&&delete n.next,r?(o?r.next=o:delete r.next,this):t?(o?t[u]=o:delete t[u],(n=t[0]||t[1]||t[2]||t[3])&&n===(t[3]||t[2]||t[1]||t[0])&&!n.length&&(i?i[m]=n:this._root=n),this):(this._root=o,this)}function Be(e){for(var t=0,n=e.length;t<n;++t)this.remove(e[t]);return this}function Pe(){return this._root}function je(){var e=0;return this.visit(function(t){if(!t.length)do++e;while(t=t.next)}),e}function We(e){var t=[],n,i=this._root,r,o,a,h,d;for(i&&t.push(new L(i,this._x0,this._y0,this._x1,this._y1));n=t.pop();)if(!e(i=n.node,o=n.x0,a=n.y0,h=n.x1,d=n.y1)&&i.length){var s=(o+h)/2,l=(a+d)/2;(r=i[3])&&t.push(new L(r,s,l,h,d)),(r=i[2])&&t.push(new L(r,o,l,s,d)),(r=i[1])&&t.push(new L(r,s,a,h,l)),(r=i[0])&&t.push(new L(r,o,a,s,l))}return this}function Xe(e){var t=[],n=[],i;for(this._root&&t.push(new L(this._root,this._x0,this._y0,this._x1,this._y1));i=t.pop();){var r=i.node;if(r.length){var o,a=i.x0,h=i.y0,d=i.x1,s=i.y1,l=(a+d)/2,g=(h+s)/2;(o=r[0])&&t.push(new L(o,a,h,l,g)),(o=r[1])&&t.push(new L(o,l,h,d,g)),(o=r[2])&&t.push(new L(o,a,g,l,s)),(o=r[3])&&t.push(new L(o,l,g,d,s))}n.push(i)}for(;i=n.pop();)e(i.node,i.x0,i.y0,i.x1,i.y1);return this}function Fe(e){return e[0]}function Ye(e){return arguments.length?(this._x=e,this):this._x}function qe(e){return e[1]}function Ke(e){return arguments.length?(this._y=e,this):this._y}function B(e,t,n){var i=new de(t??Fe,n??qe,NaN,NaN,NaN,NaN);return e==null?i:i.addAll(e)}function de(e,t,n,i,r,o){this._x=e,this._y=t,this._x0=n,this._y0=i,this._x1=r,this._y1=o,this._root=void 0}function Qe(e){for(var t={data:e.data},n=t;e=e.next;)n=n.next={data:e.data};return t}var S=B.prototype=de.prototype;S.copy=function(){var e=new de(this._x,this._y,this._x0,this._y0,this._x1,this._y1),t=this._root,n,i;if(!t)return e;if(!t.length)return e._root=Qe(t),e;for(n=[{source:t,target:e._root=new Array(4)}];t=n.pop();)for(var r=0;r<4;++r)(i=t.source[r])&&(i.length?n.push({source:i,target:t.target[r]=new Array(4)}):t.target[r]=Qe(i));return e};S.add=Ge;S.addAll=ze;S.cover=De;S.data=He;S.extent=Oe;S.find=Ie;S.remove=Re;S.removeAll=Be;S.root=Pe;S.size=je;S.visit=We;S.visitAfter=Xe;S.x=Ye;S.y=Ke;function D(e){return function(){return e}}function z(e){return(e()-.5)*1e-6}function yt(e){return e.x+e.vx}function xt(e){return e.y+e.vy}function ue(e){var t,n,i,r=1,o=1;typeof e!="function"&&(e=D(e==null?1:+e));function a(){for(var s,l=t.length,g,c,f,v,p,u,m=0;m<o;++m)for(g=B(t,yt,xt).visitAfter(h),s=0;s<l;++s)c=t[s],p=n[c.index],u=p*p,f=c.x+c.vx,v=c.y+c.vy,g.visit(y);function y(b,x,M,T,G){var C=b.data,V=b.r,$=p+V;if(C){if(C.index>c.index){var O=f-C.x-C.vx,I=v-C.y-C.vy,H=O*O+I*I;H<$*$&&(O===0&&(O=z(i),H+=O*O),I===0&&(I=z(i),H+=I*I),H=($-(H=Math.sqrt(H)))/H*r,c.vx+=(O*=H)*($=(V*=V)/(u+V)),c.vy+=(I*=H)*$,C.vx-=O*($=1-$),C.vy-=I*$)}return}return x>f+$||T<f-$||M>v+$||G<v-$}}function h(s){if(s.data)return s.r=n[s.data.index];for(var l=s.r=0;l<4;++l)s[l]&&s[l].r>s.r&&(s.r=s[l].r)}function d(){if(t){var s,l=t.length,g;for(n=new Array(l),s=0;s<l;++s)g=t[s],n[g.index]=+e(g,s,t)}}return a.initialize=function(s,l){t=s,i=l,d()},a.iterations=function(s){return arguments.length?(o=+s,a):o},a.strength=function(s){return arguments.length?(r=+s,a):r},a.radius=function(s){return arguments.length?(e=typeof s=="function"?s:D(+s),d(),a):e},a}function wt(e){return e.index}function Ze(e,t){var n=e.get(t);if(!n)throw new Error("node not found: "+t);return n}function fe(e){var t=wt,n=g,i,r=D(30),o,a,h,d,s,l=1;e==null&&(e=[]);function g(u){return 1/Math.min(h[u.source.index],h[u.target.index])}function c(u){for(var m=0,y=e.length;m<l;++m)for(var b=0,x,M,T,G,C,V,$;b<y;++b)x=e[b],M=x.source,T=x.target,G=T.x+T.vx-M.x-M.vx||z(s),C=T.y+T.vy-M.y-M.vy||z(s),V=Math.sqrt(G*G+C*C),V=(V-o[b])/V*u*i[b],G*=V,C*=V,T.vx-=G*($=d[b]),T.vy-=C*$,M.vx+=G*($=1-$),M.vy+=C*$}function f(){if(a){var u,m=a.length,y=e.length,b=new Map(a.map((M,T)=>[t(M,T,a),M])),x;for(u=0,h=new Array(m);u<y;++u)x=e[u],x.index=u,typeof x.source!="object"&&(x.source=Ze(b,x.source)),typeof x.target!="object"&&(x.target=Ze(b,x.target)),h[x.source.index]=(h[x.source.index]||0)+1,h[x.target.index]=(h[x.target.index]||0)+1;for(u=0,d=new Array(y);u<y;++u)x=e[u],d[u]=h[x.source.index]/(h[x.source.index]+h[x.target.index]);i=new Array(y),v(),o=new Array(y),p()}}function v(){if(a)for(var u=0,m=e.length;u<m;++u)i[u]=+n(e[u],u,e)}function p(){if(a)for(var u=0,m=e.length;u<m;++u)o[u]=+r(e[u],u,e)}return c.initialize=function(u,m){a=u,s=m,f()},c.links=function(u){return arguments.length?(e=u,f(),c):e},c.id=function(u){return arguments.length?(t=u,c):t},c.iterations=function(u){return arguments.length?(l=+u,c):l},c.strength=function(u){return arguments.length?(n=typeof u=="function"?u:D(+u),v(),c):n},c.distance=function(u){return arguments.length?(r=typeof u=="function"?u:D(+u),p(),c):r},c}var bt={value:()=>{}};function Je(){for(var e=0,t=arguments.length,n={},i;e<t;++e){if(!(i=arguments[e]+"")||i in n||/[\s.]/.test(i))throw new Error("illegal type: "+i);n[i]=[]}return new te(n)}function te(e){this._=e}function kt(e,t){return e.trim().split(/^|\s+/).map(function(n){var i="",r=n.indexOf(".");if(r>=0&&(i=n.slice(r+1),n=n.slice(0,r)),n&&!t.hasOwnProperty(n))throw new Error("unknown type: "+n);return{type:n,name:i}})}te.prototype=Je.prototype={constructor:te,on:function(e,t){var n=this._,i=kt(e+"",n),r,o=-1,a=i.length;if(arguments.length<2){for(;++o<a;)if((r=(e=i[o]).type)&&(r=_t(n[r],e.name)))return r;return}if(t!=null&&typeof t!="function")throw new Error("invalid callback: "+t);for(;++o<a;)if(r=(e=i[o]).type)n[r]=Ue(n[r],e.name,t);else if(t==null)for(r in n)n[r]=Ue(n[r],e.name,null);return this},copy:function(){var e={},t=this._;for(var n in t)e[n]=t[n].slice();return new te(e)},call:function(e,t){if((r=arguments.length-2)>0)for(var n=new Array(r),i=0,r,o;i<r;++i)n[i]=arguments[i+2];if(!this._.hasOwnProperty(e))throw new Error("unknown type: "+e);for(o=this._[e],i=0,r=o.length;i<r;++i)o[i].value.apply(t,n)},apply:function(e,t,n){if(!this._.hasOwnProperty(e))throw new Error("unknown type: "+e);for(var i=this._[e],r=0,o=i.length;r<o;++r)i[r].value.apply(t,n)}};function _t(e,t){for(var n=0,i=e.length,r;n<i;++n)if((r=e[n]).name===t)return r.value}function Ue(e,t,n){for(var i=0,r=e.length;i<r;++i)if(e[i].name===t){e[i]=bt,e=e.slice(0,i).concat(e.slice(i+1));break}return n!=null&&e.push({name:t,value:n}),e}var he=Je;var Y=0,Q=0,K=0,tt=1e3,ne,Z,re=0,P=0,ie=0,U=typeof performance=="object"&&performance.now?performance:Date,nt=typeof window=="object"&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(e){setTimeout(e,17)};function ge(){return P||(nt(Et),P=U.now()+ie)}function Et(){P=0}function pe(){this._call=this._time=this._next=null}pe.prototype=oe.prototype={constructor:pe,restart:function(e,t,n){if(typeof e!="function")throw new TypeError("callback is not a function");n=(n==null?ge():+n)+(t==null?0:+t),!this._next&&Z!==this&&(Z?Z._next=this:ne=this,Z=this),this._call=e,this._time=n,me()},stop:function(){this._call&&(this._call=null,this._time=1/0,me())}};function oe(e,t,n){var i=new pe;return i.restart(e,t,n),i}function rt(){ge(),++Y;for(var e=ne,t;e;)(t=P-e._time)>=0&&e._call.call(void 0,t),e=e._next;--Y}function et(){P=(re=U.now())+ie,Y=Q=0;try{rt()}finally{Y=0,Nt(),P=0}}function Mt(){var e=U.now(),t=e-re;t>tt&&(ie-=t,re=e)}function Nt(){for(var e,t=ne,n,i=1/0;t;)t._call?(i>t._time&&(i=t._time),e=t,t=t._next):(n=t._next,t._next=null,t=e?e._next=n:ne=n);Z=e,me(i)}function me(e){if(!Y){Q&&(Q=clearTimeout(Q));var t=e-P;t>24?(e<1/0&&(Q=setTimeout(et,e-U.now()-ie)),K&&(K=clearInterval(K))):(K||(re=U.now(),K=setInterval(Mt,tt)),Y=1,nt(et))}}function it(){let e=1;return()=>(e=(1664525*e+1013904223)%4294967296)/4294967296}function ot(e){return e.x}function st(e){return e.y}var Ct=10,$t=Math.PI*(3-Math.sqrt(5));function ve(e){var t,n=1,i=.001,r=1-Math.pow(i,1/300),o=0,a=.6,h=new Map,d=oe(g),s=he("tick","end"),l=it();e==null&&(e=[]);function g(){c(),s.call("tick",t),n<i&&(d.stop(),s.call("end",t))}function c(p){var u,m=e.length,y;p===void 0&&(p=1);for(var b=0;b<p;++b)for(n+=(o-n)*r,h.forEach(function(x){x(n)}),u=0;u<m;++u)y=e[u],y.fx==null?y.x+=y.vx*=a:(y.x=y.fx,y.vx=0),y.fy==null?y.y+=y.vy*=a:(y.y=y.fy,y.vy=0);return t}function f(){for(var p=0,u=e.length,m;p<u;++p){if(m=e[p],m.index=p,m.fx!=null&&(m.x=m.fx),m.fy!=null&&(m.y=m.fy),isNaN(m.x)||isNaN(m.y)){var y=Ct*Math.sqrt(.5+p),b=p*$t;m.x=y*Math.cos(b),m.y=y*Math.sin(b)}(isNaN(m.vx)||isNaN(m.vy))&&(m.vx=m.vy=0)}}function v(p){return p.initialize&&p.initialize(e,l),p}return f(),t={tick:c,restart:function(){return d.restart(g),t},stop:function(){return d.stop(),t},nodes:function(p){return arguments.length?(e=p,f(),h.forEach(v),t):e},alpha:function(p){return arguments.length?(n=+p,t):n},alphaMin:function(p){return arguments.length?(i=+p,t):i},alphaDecay:function(p){return arguments.length?(r=+p,t):+r},alphaTarget:function(p){return arguments.length?(o=+p,t):o},velocityDecay:function(p){return arguments.length?(a=1-p,t):1-a},randomSource:function(p){return arguments.length?(l=p,h.forEach(v),t):l},force:function(p,u){return arguments.length>1?(u==null?h.delete(p):h.set(p,v(u)),t):h.get(p)},find:function(p,u,m){var y=0,b=e.length,x,M,T,G,C;for(m==null?m=1/0:m*=m,y=0;y<b;++y)G=e[y],x=p-G.x,M=u-G.y,T=x*x+M*M,T<m&&(C=G,m=T);return C},on:function(p,u){return arguments.length>1?(s.on(p,u),t):s.on(p)}}}function ye(){var e,t,n,i,r=D(-30),o,a=1,h=1/0,d=.81;function s(f){var v,p=e.length,u=B(e,ot,st).visitAfter(g);for(i=f,v=0;v<p;++v)t=e[v],u.visit(c)}function l(){if(e){var f,v=e.length,p;for(o=new Array(v),f=0;f<v;++f)p=e[f],o[p.index]=+r(p,f,e)}}function g(f){var v=0,p,u,m=0,y,b,x;if(f.length){for(y=b=x=0;x<4;++x)(p=f[x])&&(u=Math.abs(p.value))&&(v+=p.value,m+=u,y+=u*p.x,b+=u*p.y);f.x=y/m,f.y=b/m}else{p=f,p.x=p.data.x,p.y=p.data.y;do v+=o[p.data.index];while(p=p.next)}f.value=v}function c(f,v,p,u){if(!f.value)return!0;var m=f.x-t.x,y=f.y-t.y,b=u-v,x=m*m+y*y;if(b*b/d<x)return x<h&&(m===0&&(m=z(n),x+=m*m),y===0&&(y=z(n),x+=y*y),x<a&&(x=Math.sqrt(a*x)),t.vx+=m*f.value*i/x,t.vy+=y*f.value*i/x),!0;if(f.length||x>=h)return;(f.data!==t||f.next)&&(m===0&&(m=z(n),x+=m*m),y===0&&(y=z(n),x+=y*y),x<a&&(x=Math.sqrt(a*x)));do f.data!==t&&(b=o[f.data.index]*i/x,t.vx+=m*b,t.vy+=y*b);while(f=f.next)}return s.initialize=function(f,v){e=f,n=v,l()},s.strength=function(f){return arguments.length?(r=typeof f=="function"?f:D(+f),l(),s):r},s.distanceMin=function(f){return arguments.length?(a=f*f,s):Math.sqrt(a)},s.distanceMax=function(f){return arguments.length?(h=f*f,s):Math.sqrt(h)},s.theta=function(f){return arguments.length?(d=f*f,s):Math.sqrt(d)},s}function A(e){return e.replace(/&/g,"&").replace(/</g,"<")}function Lt(e){let t=e.lines.map(n=>`<div class="ev-l ${n.sign==="+"?"add":n.sign==="-"?"del":"ctx"}"><span class="ev-n">${n.n??""}</span><span class="ev-s">${n.sign===" "?"":n.sign}</span><span class="ev-t">${A(n.text)}</span></div>`).join("");return`<div class="ev"><div class="ev-h mono">${A(e.label)}${e.note?` <span class="ev-note">${A(e.note)}</span>`:""}</div><div class="ev-b mono">${t}</div>`+(e.more?`<div class="ev-more">+ ${e.more} more lines</div>`:"")+"</div>"}function xe(e){let t=e.split(/[\s._-]+/).filter(Boolean);return(t.length>=2?t[0][0]+t[1][0]:(t[0]??"?").slice(0,2)).toUpperCase()}function At(e,t=Date.now()){let n=Date.parse(`${e}T00:00:00Z`);if(!Number.isFinite(n))return e;let i=Math.max(0,Math.round((t-n)/864e5));if(i<1)return"today";if(i===1)return"yesterday";if(i<31)return`${i}d ago`;let r=Math.round(i/30);return r<24?`${r}mo ago`:`${Math.round(i/365)}y ago`}function Tt(e){let t=e.map(r=>{let o=r.handle?`@${A(r.handle)}`:A(r.name),a=r.handle?"own-name mono":"own-name";return`<div class="own"><span class="av">${A(xe(r.handle??r.name))}</span><span class="own-txt"><span class="${a}">${o}</span><span class="own-why">${r.commits} commit${r.commits===1?"":"s"} here \xB7 last ${A(At(r.last))}</span></span></div>`}).join(""),n=e.filter(r=>!r.handle),i=n.length?`<div class="own-note">\u26A0 ${A(n.map(r=>r.name).join(", "))} ${n.length===1?"has":"have"} no GitHub handle in their commit email.</div>`:"";return`<div class="owners">${t}${i}</div>`}function at(e,t,n,i,r){if(!i||!t){e.innerHTML='<div class="empty">Select a node to view details</div>';return}let o=t.nodes.find(c=>c.id===i);if(!o){e.innerHTML='<div class="empty">Select a node to view details</div>';return}let a=k(R(n,o.type)),h=c=>t.nodes.find(f=>f.id===c)?.name??c,d=t.edges.filter(c=>c.source===i),s=t.edges.filter(c=>c.target===i),l=`<span class="d-type"><span class="sw" style="background:${a}"></span>${A(o.type)}</span>`;if(l+=`<h3>${A(o.name)}</h3>`,o.summary&&(l+=`<p class="summary">${A(o.summary)}</p>`),o.owners?.length&&(l+=`<div class="d-label"><span class="dot" style="background:var(--con)"></span>Who knows this \xB7 ${o.owners.length}</div>`,l+=Tt(o.owners)),o.evidence?.length){l+=`<div class="d-label">Code \xB7 ${o.evidence.length}</div>`;for(let f of o.evidence)l+=Lt(f);let c=o.sources.length-o.evidence.length;c>0&&(l+=`<div class="src mono">+ ${c} more, not shown</div>`)}else if(o.sources.length){l+=`<div class="d-label">Sources \xB7 ${o.sources.length}</div>`;for(let c of o.sources)l+=`<div class="src mono">${A(c)}</div>`}let g=(c,f,v,p)=>{if(c.length){l+=`<div class="d-label"><span class="dot" style="background:${f}"></span>${v} \xB7 ${c.length}</div>`;for(let u of c)l+=`<button class="lnk" data-go="${A(p(u))}"><span class="rel">${A(u.relation.replace(/_/g," "))}</span> <span class="to">${A(h(p(u)))}</span>`+(u.description?`<div class="desc">${A(u.description)}</div>`:"")+"</button>"}};g(d,k("--fil"),"Depends on",c=>c.target),g(s,k("--accent"),"Depended on by",c=>c.source),e.innerHTML=l,e.querySelectorAll("[data-go]").forEach(c=>{c.addEventListener("click",()=>r(c.dataset.go))})}var St="http://www.w3.org/2000/svg",Gt=2;function N(e,t){let n=document.createElementNS(St,e);for(let[i,r]of Object.entries(t))n.setAttribute(i,String(r));return n}function Vt(e){let t=e.owners??[];if(t.length===0)return null;let n=t.slice(0,Gt),i=t.length-n.length,r=[...n.map(a=>xe(a.handle??a.name)),...i>0?[`+${i}`]:[]],o=N("g",{"pointer-events":"none"});return r.forEach((a,h)=>{let d=e.r*.72+h*13,s=-e.r*.72+h*8;o.appendChild(N("circle",{cx:d,cy:s,r:8,fill:k("--panel"),stroke:k("--con"),"stroke-width":1.2}));let l=N("text",{x:d,y:s+3,"text-anchor":"middle","font-size":7.5,"font-weight":700,fill:k("--con")});l.textContent=a;let g=N("title",{});g.textContent=t.map(c=>`${c.handle?`@${c.handle}`:c.name} \u2014 ${c.commits} commits`).join(`
|
|
2
|
+
`),o.append(l,g)}),o}var se=class{svg;defs;viewport;sim=null;nodes=[];edges=[];edgeEls=[];nodeEls=[];view={x:0,y:0,k:1};panMoved=!1;tab="context";selected=null;query="";hiddenRels={};hiddenTypes={};showOwners=!0;onSelect=()=>{};constructor(t){this.svg=t,this.buildChrome(),this.bindPanZoom()}buildChrome(){this.svg.textContent="",this.defs=N("defs",{}),this.svg.appendChild(this.defs),this.viewport=N("g",{}),this.svg.appendChild(this.viewport),this.svg.addEventListener("click",()=>{if(this.panMoved){this.panMoved=!1;return}this.select(null)})}ensureMarkers(){this.defs.textContent="";let t=N("marker",{id:"arr",viewBox:"0 0 10 10",refX:8,refY:5,markerWidth:4.5,markerHeight:4.5,orient:"auto-start-reverse"});t.appendChild(N("path",{d:"M2,1.5L8.5,5L2,8.5",fill:"none",stroke:k("--edge"),"stroke-width":1.8,"stroke-linecap":"round","stroke-linejoin":"round",opacity:.75}));let n=N("marker",{id:"arrH",viewBox:"0 0 12 12",refX:10,refY:6,markerWidth:6.5,markerHeight:6.5,orient:"auto-start-reverse"});n.appendChild(N("path",{d:"M1.5,1.5L10.5,6L1.5,10.5z",fill:k("--canvas"),stroke:k("--edge"),"stroke-width":1.4}));let i=N("marker",{id:"arrOut",viewBox:"0 0 10 10",refX:8,refY:5,markerWidth:5,markerHeight:5,orient:"auto-start-reverse"});i.appendChild(N("path",{d:"M1,1L9,5L1,9z",fill:k("--fil")}));let r=N("marker",{id:"arrIn",viewBox:"0 0 10 10",refX:8,refY:5,markerWidth:5,markerHeight:5,orient:"auto-start-reverse"});r.appendChild(N("path",{d:"M1,1L9,5L1,9z",fill:k("--accent")}));for(let o of[t,n,i,r])this.defs.appendChild(o)}setData(t,n){this.tab=n;let i=new Map(this.nodes.map(d=>[d.id,d])),r={};for(let d of t.edges)r[d.source]=(r[d.source]??0)+1,r[d.target]=(r[d.target]??0)+1;let o=this.svg.clientWidth||800,a=this.svg.clientHeight||600;this.nodes=t.nodes.map((d,s)=>{let l=i.get(d.id),g=s/Math.max(1,t.nodes.length)*Math.PI*2,c=r[d.id]??0;return{id:d.id,name:d.name,type:d.type,owners:d.owners,deg:c,r:11+Math.min(13,c*2.6),x:l?.x??o/2+Math.cos(g)*Math.min(o,a)/4,y:l?.y??a/2+Math.sin(g)*Math.min(o,a)/4,vx:l?.vx??0,vy:l?.vy??0}});let h=new Map(this.nodes.map(d=>[d.id,d]));this.edges=t.edges.map(d=>({source:h.get(d.source),target:h.get(d.target),relation:d.relation,description:d.description,confidence:d.confidence})).filter(d=>d.source&&d.target),this.sim?.stop(),this.sim=ve(this.nodes).force("charge",ye().strength(-220)).force("link",fe(this.edges).distance(d=>$e[F(d.relation)]).strength(.5)).force("center",ce(o/2,a/2)).force("collide",ue().radius(d=>d.r+6)).on("tick",()=>this.tick()),this.buildElements(),this.restyle()}buildElements(){this.ensureMarkers(),this.viewport.textContent="",this.edgeEls=this.edges.map(t=>{let n=N("path",{fill:"none","stroke-linecap":"round"}),i=N("title",{});i.textContent=t.relation.replace(/_/g," ")+(t.description?` \u2014 ${t.description}`:""),n.appendChild(i);let r=N("text",{"text-anchor":"middle","font-size":9.5,"font-weight":700,"stroke-width":3,"paint-order":"stroke",display:"none"});return r.textContent=t.relation.replace(/_/g," "),this.viewport.appendChild(n),this.viewport.appendChild(r),{path:n,label:r,edge:t}}),this.nodeEls=this.nodes.map(t=>{let n=N("g",{cursor:"pointer"}),i=N("circle",{fill:"none","stroke-width":1.6,opacity:0,r:t.r+5}),r=N("circle",{r:t.r,opacity:.92}),o=N("text",{y:t.r+15,"text-anchor":"middle","font-size":11.5,"font-weight":600});o.textContent=t.name;let a=Vt(t);return n.append(i,r,o),a&&n.appendChild(a),n.addEventListener("click",h=>{h.stopPropagation(),this.select(t.id)}),this.bindDrag(n,t),this.viewport.appendChild(n),{group:n,circle:r,ring:i,label:o,badges:a,node:t}})}tick(){for(let{path:t,label:n,edge:i}of this.edgeEls){let r=i.source,o=i.target,a=(o.x??0)-(r.x??0),h=(o.y??0)-(r.y??0),d=Math.sqrt(a*a+h*h)||1,s=a/d,l=h/d,g=(r.x??0)+s*(r.r+2),c=(r.y??0)+l*(r.r+2),f=(o.x??0)-s*(o.r+6),v=(o.y??0)-l*(o.r+6),p=(g+f)/2-l*10,u=(c+v)/2+s*10;t.setAttribute("d",`M${g},${c} Q${p},${u} ${f},${v}`),n.setAttribute("x",String((g+f)/2-l*14)),n.setAttribute("y",String((c+v)/2+s*14))}for(let{group:t,node:n}of this.nodeEls)t.setAttribute("transform",`translate(${n.x??0},${n.y??0})`)}restyle(){this.ensureMarkers();let t=new Set;if(this.selected)for(let r of this.edges)r.source.id===this.selected&&t.add(r.target.id),r.target.id===this.selected&&t.add(r.source.id);let n=this.query.toLowerCase(),i=r=>!this.hiddenTypes[r.type];for(let{path:r,label:o,edge:a}of this.edgeEls){let h=i(a.source)&&i(a.target)&&!this.hiddenRels[ee(a.relation)];if(r.style.display=h?"":"none",o.setAttribute("display","none"),!h)continue;let d=F(a.relation),s=k("--edge"),l=1.3,g="none",c=.5,f="url(#arr)";d==="structure"?(l=2.4,c=.32,f="none"):d==="dependency"?(l=1.5,c=.55):d==="contract"?(c=.55,f="url(#arrH)"):(g="2 5",l=1.2,c=.28,f="none"),a.confidence==="inferred"&&(g="5 4"),n&&(c=.12);let v=this.selected?a.source.id===this.selected?"out":a.target.id===this.selected?"in":"far":"none";v==="out"?(s=k("--fil"),c=.95,l+=.7,f="url(#arrOut)"):v==="in"?(s=k("--accent"),c=.95,l+=.7,f="url(#arrIn)"):v==="far"&&(c=.06),r.setAttribute("stroke",s),r.setAttribute("stroke-width",String(l)),r.setAttribute("stroke-dasharray",g),r.setAttribute("opacity",String(c)),f==="none"?r.removeAttribute("marker-end"):r.setAttribute("marker-end",f),(v==="out"||v==="in")&&(o.removeAttribute("display"),o.setAttribute("fill",s),o.setAttribute("stroke",k("--canvas")))}for(let{group:r,circle:o,ring:a,label:h,badges:d,node:s}of this.nodeEls){let l=i(s);if(r.style.display=l?"":"none",!l)continue;let c=!n||s.name.toLowerCase().includes(n)?1:.22;this.selected&&s.id!==this.selected&&!t.has(s.id)&&(c=Math.min(c,.2)),r.setAttribute("opacity",String(c));let f=k(R(this.tab,s.type));o.setAttribute("fill",f),a.setAttribute("stroke",f),a.setAttribute("opacity",s.id===this.selected?"0.55":"0"),h.setAttribute("fill",k("--ink")),d&&(d.style.display=this.showOwners?"":"none")}}select(t){this.selected=t,this.restyle(),this.onSelect(t)}focus(t){let n=this.nodes.find(o=>o.id===t);if(!n)return;let i=this.svg.clientWidth,r=this.svg.clientHeight;this.view.k=Math.max(this.view.k,1.4),this.view.x=i/2-(n.x??0)*this.view.k,this.view.y=r/2-(n.y??0)*this.view.k,this.applyView(),this.select(t)}firstMatch(){let t=this.query.toLowerCase();return this.nodes.find(n=>!this.hiddenTypes[n.type]&&n.name.toLowerCase().includes(t))}applyView(){this.viewport.setAttribute("transform",`translate(${this.view.x},${this.view.y}) scale(${this.view.k})`)}zoomBy(t){let n=this.svg.clientWidth/2,i=this.svg.clientHeight/2,r=Math.max(.35,Math.min(3,this.view.k*t));this.view.x=n-(n-this.view.x)*(r/this.view.k),this.view.y=i-(i-this.view.y)*(r/this.view.k),this.view.k=r,this.applyView()}resetView(){this.view={x:0,y:0,k:1},this.applyView()}reheat(){this.sim?.alpha(.6).restart()}bindDrag(t,n){t.addEventListener("pointerdown",i=>{i.stopPropagation(),t.setPointerCapture(i.pointerId);let r=a=>{let h=this.svg.getBoundingClientRect();n.fx=(a.clientX-h.left-this.view.x)/this.view.k,n.fy=(a.clientY-h.top-this.view.y)/this.view.k,this.sim?.alphaTarget(.25).restart()},o=()=>{n.fx=null,n.fy=null,this.sim?.alphaTarget(0),t.removeEventListener("pointermove",r),t.removeEventListener("pointerup",o)};t.addEventListener("pointermove",r),t.addEventListener("pointerup",o)})}bindPanZoom(){let n=null,i={x:0,y:0};this.svg.addEventListener("pointerdown",r=>{n={x:r.clientX-this.view.x,y:r.clientY-this.view.y},i={x:r.clientX,y:r.clientY},this.panMoved=!1}),this.svg.addEventListener("pointermove",r=>{n&&(!this.panMoved&&Math.hypot(r.clientX-i.x,r.clientY-i.y)>4&&(this.panMoved=!0),this.view.x=r.clientX-n.x,this.view.y=r.clientY-n.y,this.applyView())}),window.addEventListener("pointerup",()=>{n=null}),this.svg.addEventListener("wheel",r=>{r.preventDefault();let o=this.svg.getBoundingClientRect(),a=r.clientX-o.left,h=r.clientY-o.top,d=Math.max(.35,Math.min(3,this.view.k*Math.exp(-r.deltaY*.0016)));this.view.x=a-(a-this.view.x)*(d/this.view.k),this.view.y=h-(h-this.view.y)*(d/this.view.k),this.view.k=d,this.applyView()},{passive:!1})}};function we(e){return e.replace(/&/g,"&").replace(/</g,"<")}function q(e,t,n,i,r){let o=s=>t.edges.filter(l=>l.relation==="contains"&&l.source===s).map(l=>t.nodes.find(g=>g.id===l.target)).filter(l=>!!l),a=s=>{let l=o(s);return l.length+l.reduce((g,c)=>g+a(c.id),0)},h=t.nodes.filter(s=>s.type==="file"),d=s=>{let l=o(s.id),g=i[s.id]!==!1,c=`<button class="tree-row${g?" open":""}${n===s.id?" sel":""}" data-id="${we(s.id)}" data-haskids="${l.length?1:0}"><span class="chev">${l.length?"\u25B6":""}</span><span class="k" style="background:${k(R("code",s.type))}"></span><span class="t${s.type==="file"?" mono":""}">${we(s.name)}</span><span class="badge">${l.length?a(s.id)+" sym":we(s.type)}</span></button>`;return l.length&&g&&(c+=`<div class="tree-kids">${l.map(d).join("")}</div>`),c};e.innerHTML='<div class="tree-tools"><button data-tool="expand">Expand all</button><button data-tool="collapse">Collapse all</button></div>'+h.map(d).join(""),e.querySelectorAll(".tree-row").forEach(s=>{s.addEventListener("click",()=>{let l=s.dataset.id;s.dataset.haskids==="1"&&(i[l]=i[l]===!1,q(e,t,l,i,r)),r(l)})}),e.querySelector('[data-tool="expand"]')?.addEventListener("click",()=>{for(let s of Object.keys(i))delete i[s];q(e,t,n,i,r)}),e.querySelector('[data-tool="collapse"]')?.addEventListener("click",()=>{for(let s of t.nodes)i[s.id]=!1;q(e,t,n,i,r)})}var _=e=>document.getElementById(e),E={tab:"context",context:null,code:null,outlineOpen:{}},w=new se(_("graphSvg"));function J(){return E.tab==="context"?E.context:E.code}function Ee(){return E.tab==="code"||E.tab==="outline"?"code":"context"}function Me(){let e=_("edgeChips");e.innerHTML='<span class="cap">Edges</span>';let t=J();if(!t)return;let n=new Map;for(let r of t.edges){let o=ee(r.relation);n.set(o,(n.get(o)??0)+1)}let i=[...n.keys()].sort((r,o)=>{let a=h=>h==="part of"?0:h==="uses"?1:2;return a(r)-a(o)||r.localeCompare(o)});for(let r of i){let o=document.createElement("button");o.type="button",o.className="echip"+(w.hiddenRels[r]?"":" on"),o.innerHTML=`${zt(r)} ${r} <span style="opacity:.55">${n.get(r)}</span>`,o.title=(Le[r]??`"${r}" edges`)+" \u2014 click to "+(w.hiddenRels[r]?"show":"hide"),o.addEventListener("click",()=>{w.hiddenRels[r]=!w.hiddenRels[r],Me(),w.restyle(),Ne()}),e.appendChild(o)}}function zt(e){let t=e==="part of"?"structure":e==="uses"?"dependency":F(e.replace(/ /g,"_"));return{structure:'<svg width="20" height="8" aria-hidden="true"><line x1="1" y1="4" x2="19" y2="4" stroke="currentColor" stroke-width="3" opacity=".5"/></svg>',dependency:'<svg width="20" height="8" aria-hidden="true"><line x1="1" y1="4" x2="14" y2="4" stroke="currentColor" stroke-width="1.6"/><path d="M14,1 L19,4 L14,7 z" fill="currentColor"/></svg>',contract:'<svg width="20" height="8" aria-hidden="true"><line x1="1" y1="4" x2="13" y2="4" stroke="currentColor" stroke-width="1.4"/><path d="M13,1 L19,4 L13,7 z" fill="none" stroke="currentColor" stroke-width="1.2"/></svg>',association:'<svg width="20" height="8" aria-hidden="true"><line x1="1" y1="4" x2="19" y2="4" stroke="currentColor" stroke-width="1.4" stroke-dasharray="2 4" opacity=".7"/></svg>'}[t]}function ae(){let e=_("legend");e.innerHTML="";let t=J();if(!t)return;let n=new Map;for(let r of t.nodes)n.set(r.type,(n.get(r.type)??0)+1);for(let[r,o]of n){let a=document.createElement("button");a.type="button",a.className="lchip"+(w.hiddenTypes[r]?" off":""),a.innerHTML=`<span class="sw" style="background:${k(R(Ee(),r))}"></span>${r} <span style="color:var(--muted);font-weight:500">${o}</span>`,a.addEventListener("click",()=>{w.hiddenTypes[r]=!w.hiddenTypes[r],ae(),w.restyle(),Ne()}),e.appendChild(a)}if(t.nodes.some(r=>r.owners?.length)){let r=document.createElement("button");r.type="button",r.className="lchip lchip-people"+(w.showOwners?"":" off"),r.innerHTML=`<span class="sw" style="background:${k("--con")}"></span>people`,r.title="Show who has worked on each area",r.addEventListener("click",()=>{w.showOwners=!w.showOwners,ae(),w.restyle()}),e.appendChild(r)}}function Ne(){let e=J();if(!e){_("lcount").textContent="";return}let t=e.nodes.filter(n=>!w.hiddenTypes[n.type]).length;_("lcount").textContent=`${t} / ${e.nodes.length} nodes shown`}function Dt(){let e=_("counts");if(E.tab==="outline"&&E.code){let t=E.code.nodes.filter(n=>n.type==="file").length;e.textContent=`${t} files \xB7 ${E.code.nodes.length} symbols`}else{let t=J();e.textContent=t?`${t.meta.nodeCount} nodes \xB7 ${t.meta.edgeCount} links`:""}}function j(e){at(_("detail"),E.tab==="context"?E.context:E.code,Ee(),e,t=>{E.tab==="outline"?(j(t),q(_("tree"),E.code,t,E.outlineOpen,j)):w.focus(t)})}w.onSelect=e=>j(e);function dt(e){E.tab=e,document.querySelectorAll(".tab").forEach(i=>{i.setAttribute("aria-selected",i.dataset.tab===e?"true":"false")});let t=e==="outline";_("canvasWrap").hidden=t,_("outlineView").hidden=!t,w.hiddenRels={},w.hiddenTypes={},w.selected=null,j(null);let n=_("graphEmpty");if(e==="outline")E.code?q(_("tree"),E.code,null,E.outlineOpen,j):(_("outlineView").hidden=!0,_("canvasWrap").hidden=!1,lt('No code graph yet \u2014 run <code>graft graph</code> to generate <span class="mono">graph.json</span>.'));else{let i=J();!i||i.nodes.length===0?lt(i?.meta.emptyNote?Ht(i.meta.emptyNote):e==="code"?'No code graph yet \u2014 run <code>graft graph</code> to generate <span class="mono">graph.json</span>.':"No context graph \u2014 run <code>graft init</code> first."):(n.hidden=!0,w.resetView(),w.setData(i,Ee()),w.reheat())}Me(),ae(),Ne(),Dt()}function Ht(e){return e.replace(/&/g,"&").replace(/</g,"<")}function lt(e){let t=_("graphEmpty");t.innerHTML=e,t.hidden=!1}document.querySelectorAll(".tab").forEach(e=>{e.addEventListener("click",()=>dt(e.dataset.tab))});var ke=_("search");ke.addEventListener("input",()=>{w.query=ke.value.trim(),w.restyle()});ke.addEventListener("keydown",e=>{if(e.key==="Enter"&&w.query){let t=w.firstMatch();t&&w.focus(t.id)}});_("zin").addEventListener("click",()=>w.zoomBy(1.25));_("zout").addEventListener("click",()=>w.zoomBy(1/1.25));_("zreset").addEventListener("click",()=>w.resetView());var ut="graft-viz-theme",ct=localStorage.getItem(ut);ct&&document.documentElement.setAttribute("data-theme",ct);_("themeBtn").addEventListener("click",()=>{let e=document.documentElement,t=e.getAttribute("data-theme"),n=window.matchMedia("(prefers-color-scheme: dark)").matches,r=(t?t==="dark":n)?"light":"dark";e.setAttribute("data-theme",r),localStorage.setItem(ut,r),w.restyle(),Me(),ae(),j(w.selected)});var ft="graft-viz-detail-w",_e=220,Ot=document.documentElement,It=e=>Math.min(Math.max(_e,Math.round(window.innerWidth*.6)),Math.max(_e,Math.round(e)));function Ce(e,t=!0){let n=It(e);Ot.style.setProperty("--detail-w",`${n}px`),t&&localStorage.setItem(ft,String(n))}var be=Number(localStorage.getItem(ft));Number.isFinite(be)&&be>=_e&&Ce(be,!1);var W=_("detailResizer"),le=!1;W.addEventListener("pointerdown",e=>{let t=e;le=!0,W.setPointerCapture(t.pointerId),document.body.style.cursor="col-resize",e.preventDefault()});W.addEventListener("pointermove",e=>{le&&Ce(window.innerWidth-e.clientX)});var ht=e=>{if(le){le=!1,document.body.style.cursor="";try{W.releasePointerCapture(e.pointerId)}catch{}w.reheat()}};W.addEventListener("pointerup",ht);W.addEventListener("pointercancel",ht);W.addEventListener("keydown",e=>{let t=e;if(t.key!=="ArrowLeft"&&t.key!=="ArrowRight")return;let n=t.shiftKey?40:16,i=_("detail").getBoundingClientRect().width;Ce(i+(t.key==="ArrowLeft"?n:-n)),w.reheat(),e.preventDefault()});async function pt(){let[e,t]=await Promise.all([Ae(),Te()]);E.context=e,E.code=t;let n=[e.meta.repoName,e.meta.subtitle].filter(Boolean).join(" \xB7 ");_("repoName").textContent=n,document.title=`graft viz \u2014 ${n}`;let i=e.meta.tabs;i&&document.querySelectorAll(".tab").forEach(o=>{o.hidden=!i.includes(o.dataset.tab)});let r=e.meta.defaultTab;dt(r&&r!==E.tab?r:E.tab)}Se(()=>{let e=w.selected;pt().then(()=>{e&&(w.selected=e,w.restyle(),j(e))})});pt();
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>trail viz</title>
|
|
7
|
+
<link rel="stylesheet" href="/style.css">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<header class="appbar">
|
|
11
|
+
<div class="brand"><b>trail</b><span id="repoName"></span></div>
|
|
12
|
+
<div class="counts" id="counts"></div>
|
|
13
|
+
<nav class="tabs" role="tablist" id="tabs">
|
|
14
|
+
<button class="tab" role="tab" aria-selected="true" data-tab="context">Context</button>
|
|
15
|
+
<button class="tab" role="tab" aria-selected="false" data-tab="code">Code</button>
|
|
16
|
+
<button class="tab" role="tab" aria-selected="false" data-tab="outline">Outline</button>
|
|
17
|
+
</nav>
|
|
18
|
+
<div class="searchbox">
|
|
19
|
+
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.3-4.3"/></svg>
|
|
20
|
+
<input id="search" type="search" placeholder="Search nodes…" aria-label="Search nodes">
|
|
21
|
+
</div>
|
|
22
|
+
<button class="iconbtn" id="themeBtn" title="Toggle theme" aria-label="Toggle theme">
|
|
23
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M21 12.8A9 9 0 1 1 11.2 3 7 7 0 0 0 21 12.8z"/></svg>
|
|
24
|
+
</button>
|
|
25
|
+
</header>
|
|
26
|
+
|
|
27
|
+
<main class="stage" id="stage">
|
|
28
|
+
<div class="canvas-wrap" id="canvasWrap">
|
|
29
|
+
<svg class="graph" id="graphSvg" role="img" aria-label="Force-directed graph"></svg>
|
|
30
|
+
<div class="edgestyle" id="edgeChips"><span class="cap">Edges</span></div>
|
|
31
|
+
<div class="lcount" id="lcount"></div>
|
|
32
|
+
<div class="legend" id="legend"></div>
|
|
33
|
+
<div class="zoomctl">
|
|
34
|
+
<button class="iconbtn" id="zin" aria-label="Zoom in">+</button>
|
|
35
|
+
<button class="iconbtn" id="zout" aria-label="Zoom out">−</button>
|
|
36
|
+
<button class="iconbtn" id="zreset" aria-label="Reset view">⟲</button>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="emptytab" id="graphEmpty" hidden></div>
|
|
39
|
+
</div>
|
|
40
|
+
<div class="outline" id="outlineView" hidden>
|
|
41
|
+
<div class="tree" id="tree"></div>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="resizer" id="detailResizer" role="separator" aria-orientation="vertical" aria-label="Resize details panel" tabindex="0" title="Drag to resize"></div>
|
|
44
|
+
<aside class="detail" id="detail"><div class="empty">Select a node to view details</div></aside>
|
|
45
|
+
</main>
|
|
46
|
+
|
|
47
|
+
<script type="module" src="/app.js"></script>
|
|
48
|
+
</body>
|
|
49
|
+
</html>
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/* graft viz — design tokens + app styles.
|
|
2
|
+
Visual reference of record: docs/superpowers/specs/2026-07-15-graft-viz-design.md */
|
|
3
|
+
:root{
|
|
4
|
+
--bg:#F4F6F6; --panel:#FFFFFF; --panel2:#FBFCFC; --ink:#17191B; --muted:#6B7278;
|
|
5
|
+
--border:#E2E6E7; --border2:#EDF0F1; --accent:#546FFF; --accent-ink:#546FFF;
|
|
6
|
+
--chip:#F0F3F3;
|
|
7
|
+
--sys:#4A7DF0; --con:#A06BDB; --fil:#D98E2B; --api:#C95CB8;
|
|
8
|
+
--k-file:#D98E2B; --k-class:#4A7DF0; --k-fn:#4F86C6; --k-method:#3AA7C9; --k-iface:#A06BDB; --k-type:#C95CB8; --k-enum:#B69B3D;
|
|
9
|
+
--edge:#9AA4A9; --canvas:#F8FAFA;
|
|
10
|
+
}
|
|
11
|
+
@media (prefers-color-scheme: dark){
|
|
12
|
+
:root{
|
|
13
|
+
--bg:#0E1012; --panel:#15181B; --panel2:#111417; --ink:#E7E9EA; --muted:#8B9298;
|
|
14
|
+
--border:#252B30; --border2:#1D2226; --accent:#7B8FFF; --accent-ink:#7B8FFF;
|
|
15
|
+
--chip:#1C2125;
|
|
16
|
+
--sys:#6B94F5; --con:#B487E0; --fil:#E0A04A; --api:#D183C9;
|
|
17
|
+
--k-file:#E0A04A; --k-class:#6B94F5; --k-fn:#7EAEDD; --k-method:#56B9D8; --k-iface:#B487E0; --k-type:#D183C9; --k-enum:#D4BB5E;
|
|
18
|
+
--edge:#4A545B; --canvas:#101315;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
:root[data-theme="dark"]{
|
|
22
|
+
--bg:#0E1012; --panel:#15181B; --panel2:#111417; --ink:#E7E9EA; --muted:#8B9298;
|
|
23
|
+
--border:#252B30; --border2:#1D2226; --accent:#7B8FFF; --accent-ink:#7B8FFF;
|
|
24
|
+
--chip:#1C2125;
|
|
25
|
+
--sys:#6B94F5; --con:#B487E0; --fil:#E0A04A; --api:#D183C9;
|
|
26
|
+
--k-file:#E0A04A; --k-class:#6B94F5; --k-fn:#7EAEDD; --k-method:#56B9D8; --k-iface:#B487E0; --k-type:#D183C9; --k-enum:#D4BB5E;
|
|
27
|
+
--edge:#4A545B; --canvas:#101315;
|
|
28
|
+
}
|
|
29
|
+
:root[data-theme="light"]{
|
|
30
|
+
--bg:#F4F6F6; --panel:#FFFFFF; --panel2:#FBFCFC; --ink:#17191B; --muted:#6B7278;
|
|
31
|
+
--border:#E2E6E7; --border2:#EDF0F1; --accent:#546FFF; --accent-ink:#546FFF;
|
|
32
|
+
--chip:#F0F3F3;
|
|
33
|
+
--sys:#4A7DF0; --con:#A06BDB; --fil:#D98E2B; --api:#C95CB8;
|
|
34
|
+
--k-file:#D98E2B; --k-class:#4A7DF0; --k-fn:#4F86C6; --k-method:#3AA7C9; --k-iface:#A06BDB; --k-type:#C95CB8; --k-enum:#B69B3D;
|
|
35
|
+
--edge:#9AA4A9; --canvas:#F8FAFA;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
*{box-sizing:border-box}
|
|
39
|
+
[hidden]{display:none !important}
|
|
40
|
+
html,body{margin:0;padding:0;height:100%}
|
|
41
|
+
body{
|
|
42
|
+
display:flex;flex-direction:column;
|
|
43
|
+
background:var(--bg);color:var(--ink);
|
|
44
|
+
font-family:"Avenir Next","Segoe UI",system-ui,-apple-system,sans-serif;
|
|
45
|
+
font-size:15px;line-height:1.55;-webkit-font-smoothing:antialiased;
|
|
46
|
+
}
|
|
47
|
+
.mono{font-family:ui-monospace,"SF Mono",SFMono-Regular,Menlo,Consolas,monospace}
|
|
48
|
+
button:focus-visible,input:focus-visible,.tree-row:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
|
|
49
|
+
|
|
50
|
+
.appbar{display:flex;align-items:center;gap:14px;padding:10px 16px;border-bottom:1px solid var(--border);background:var(--panel);flex:none}
|
|
51
|
+
.brand{display:flex;align-items:baseline;gap:8px;flex:none}
|
|
52
|
+
.brand b{font-weight:700;letter-spacing:-.01em}
|
|
53
|
+
.brand span{color:var(--muted);font-size:13px}
|
|
54
|
+
.counts{color:var(--muted);font-size:12.5px;font-variant-numeric:tabular-nums;flex:none}
|
|
55
|
+
.tabs{display:flex;background:var(--chip);border-radius:9px;padding:3px;gap:2px;margin-left:auto;flex:none}
|
|
56
|
+
.tab{border:0;background:transparent;color:var(--muted);font:inherit;font-size:13px;font-weight:600;padding:5px 14px;border-radius:7px;cursor:pointer}
|
|
57
|
+
.tab:hover{color:var(--ink)}
|
|
58
|
+
.tab[aria-selected="true"]{background:var(--panel);color:var(--ink);box-shadow:0 1px 3px rgba(0,0,0,.12)}
|
|
59
|
+
.searchbox{position:relative;flex:none}
|
|
60
|
+
.searchbox input{width:190px;padding:6px 10px 6px 30px;border:1px solid var(--border);border-radius:8px;background:var(--panel2);color:var(--ink);font:inherit;font-size:13px;outline:none}
|
|
61
|
+
.searchbox input:focus{border-color:var(--accent)}
|
|
62
|
+
.searchbox svg{position:absolute;left:9px;top:50%;transform:translateY(-50%);opacity:.45}
|
|
63
|
+
.iconbtn{border:1px solid var(--border);background:var(--panel2);color:var(--ink);border-radius:8px;width:32px;height:32px;cursor:pointer;display:grid;place-items:center;flex:none;font:inherit;font-size:14px}
|
|
64
|
+
.iconbtn:hover{border-color:var(--muted)}
|
|
65
|
+
|
|
66
|
+
.stage{display:flex;flex:1;min-height:0;background:var(--canvas)}
|
|
67
|
+
.canvas-wrap{position:relative;flex:1;min-width:0}
|
|
68
|
+
svg.graph{display:block;width:100%;height:100%;cursor:grab}
|
|
69
|
+
svg.graph:active{cursor:grabbing}
|
|
70
|
+
|
|
71
|
+
.edgestyle{position:absolute;top:12px;left:14px;display:flex;align-items:center;gap:5px;flex-wrap:wrap;max-width:75%}
|
|
72
|
+
.edgestyle .cap{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);font-weight:700;margin-right:3px}
|
|
73
|
+
.echip{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--border);background:var(--panel);color:var(--muted);border-radius:16px;padding:3px 10px;font:inherit;font-size:11.5px;font-weight:600;cursor:pointer}
|
|
74
|
+
.echip:hover{color:var(--ink)}
|
|
75
|
+
.echip.on{color:var(--ink)}
|
|
76
|
+
.echip:not(.on){opacity:.45}
|
|
77
|
+
|
|
78
|
+
.legend{position:absolute;left:14px;bottom:14px;display:flex;gap:6px;flex-wrap:wrap;max-width:70%}
|
|
79
|
+
.lchip{display:flex;align-items:center;gap:6px;font-size:12px;font-weight:600;color:var(--ink);background:var(--panel);border:1px solid var(--border);border-radius:20px;padding:4px 11px;cursor:pointer;user-select:none;font-family:inherit}
|
|
80
|
+
.lchip .sw{width:9px;height:9px;border-radius:50%}
|
|
81
|
+
.lchip.off{opacity:.38}
|
|
82
|
+
.lcount{position:absolute;left:14px;bottom:52px;font-size:11.5px;color:var(--muted);font-variant-numeric:tabular-nums}
|
|
83
|
+
.zoomctl{position:absolute;right:14px;bottom:14px;display:flex;flex-direction:column;gap:6px}
|
|
84
|
+
.zoomctl .iconbtn{background:var(--panel)}
|
|
85
|
+
|
|
86
|
+
.resizer{flex:none;width:9px;margin:0 -4px;z-index:6;cursor:col-resize;position:relative;touch-action:none}
|
|
87
|
+
.resizer::before{content:"";position:absolute;top:0;bottom:0;left:4px;width:1px;background:var(--border)}
|
|
88
|
+
.resizer:hover::before,.resizer:focus-visible::before{left:3px;width:3px;background:var(--accent)}
|
|
89
|
+
.resizer:focus-visible{outline:none}
|
|
90
|
+
.detail{width:var(--detail-w,300px);flex:none;border-left:1px solid var(--border);background:var(--panel);overflow-y:auto;padding:18px 18px 24px}
|
|
91
|
+
.detail .empty{color:var(--muted);font-size:13.5px;text-align:center;margin-top:200px}
|
|
92
|
+
.d-type{display:inline-flex;align-items:center;gap:6px;font-size:11px;letter-spacing:.1em;text-transform:uppercase;font-weight:700;padding:3px 10px;border-radius:20px;background:var(--chip)}
|
|
93
|
+
.d-type .sw{width:8px;height:8px;border-radius:50%}
|
|
94
|
+
.detail h3{margin:10px 0 6px;font-size:17px;letter-spacing:-.01em}
|
|
95
|
+
.detail p.summary{font-size:13.5px;color:var(--ink);margin:0 0 16px;white-space:pre-line}
|
|
96
|
+
.d-label{font-size:10.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--muted);font-weight:700;margin:16px 0 7px;display:flex;align-items:center;gap:5px}
|
|
97
|
+
.d-label .dot{display:inline-block;width:7px;height:7px;border-radius:50%}
|
|
98
|
+
.src{font-size:12px;color:var(--muted);padding:3px 0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
99
|
+
.lnk{display:block;width:100%;text-align:left;border:1px solid var(--border2);background:var(--panel2);border-radius:8px;padding:7px 10px;margin-bottom:6px;cursor:pointer;font:inherit;color:var(--ink)}
|
|
100
|
+
.lnk:hover{border-color:var(--accent)}
|
|
101
|
+
.lnk .rel{font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;color:var(--accent-ink);font-weight:700}
|
|
102
|
+
.lnk .to{font-size:13px;font-weight:600}
|
|
103
|
+
.lnk .desc{font-size:12px;color:var(--muted)}
|
|
104
|
+
|
|
105
|
+
.outline{flex:1;display:flex;min-width:0}
|
|
106
|
+
.tree{flex:1;overflow-y:auto;padding:14px 8px 20px 14px;background:var(--panel)}
|
|
107
|
+
.tree-tools{display:flex;gap:14px;font-size:12.5px;color:var(--muted);padding:2px 8px 10px}
|
|
108
|
+
.tree-tools button{border:0;background:none;color:var(--accent-ink);font:inherit;font-size:12.5px;cursor:pointer;padding:0}
|
|
109
|
+
.tree-row{display:flex;align-items:center;gap:7px;padding:4px 8px;border-radius:7px;cursor:pointer;border:0;background:none;width:100%;text-align:left;font:inherit;color:var(--ink)}
|
|
110
|
+
.tree-row:hover{background:var(--chip)}
|
|
111
|
+
.tree-row.sel{background:var(--chip)}
|
|
112
|
+
.tree-row .chev{width:14px;flex:none;color:var(--muted);font-size:10px;transition:transform .12s}
|
|
113
|
+
.tree-row.open .chev{transform:rotate(90deg)}
|
|
114
|
+
.tree-row .k{width:9px;height:9px;border-radius:3px;flex:none}
|
|
115
|
+
.tree-row .t{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13.5px}
|
|
116
|
+
.tree-row .badge{margin-left:auto;font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums;flex:none}
|
|
117
|
+
.tree-kids{margin-left:19px;border-left:1px solid var(--border2);padding-left:4px}
|
|
118
|
+
|
|
119
|
+
.emptytab{position:absolute;inset:0;display:grid;place-items:center;color:var(--muted);font-size:14px;text-align:center;padding:30px;background:var(--canvas)}
|
|
120
|
+
.emptytab code{background:var(--chip);padding:2px 8px;border-radius:6px;font-family:ui-monospace,"SF Mono",Menlo,Consolas,monospace;font-size:.9em}
|
|
121
|
+
|
|
122
|
+
@media (prefers-reduced-motion:reduce){ .tree-row .chev{transition:none} }
|
|
123
|
+
@media (max-width:760px){ .detail,.resizer{display:none} .searchbox input{width:120px} .counts{display:none} }
|
|
124
|
+
/* Evidence blocks: a snippet under a node, so a panel shows the change rather
|
|
125
|
+
than a line number the reader has to go and look up. */
|
|
126
|
+
.ev{margin:7px 0 11px;border:1px solid var(--line);border-radius:7px;overflow:hidden}
|
|
127
|
+
.ev-h{font-size:11px;padding:5px 8px;background:var(--chip);color:var(--fg);border-bottom:1px solid var(--line);overflow-wrap:anywhere}
|
|
128
|
+
.ev-note{color:var(--muted);font-style:italic}
|
|
129
|
+
.ev-b{font-size:11.5px;padding:4px 0;overflow-x:auto}
|
|
130
|
+
.ev-l{display:flex;gap:8px;padding:1px 8px}
|
|
131
|
+
.ev-n{color:var(--muted);opacity:.65;min-width:2.6em;text-align:right;user-select:none;flex:none}
|
|
132
|
+
.ev-s{width:.7em;user-select:none;flex:none}
|
|
133
|
+
/* Wrapped, not scrolled: the panel is ~280px and a diff line is longer than
|
|
134
|
+
that, so a horizontal scrollbar per hunk would hide the half that matters. */
|
|
135
|
+
.ev-t{flex:1;white-space:pre-wrap;overflow-wrap:anywhere}
|
|
136
|
+
.ev-l.add{background:color-mix(in srgb,var(--ok,#2E9E6B) 11%,transparent)}
|
|
137
|
+
.ev-l.del{background:color-mix(in srgb,var(--warn,#D9534F) 10%,transparent)}
|
|
138
|
+
.ev-l.add .ev-s{color:var(--ok,#2E9E6B)}
|
|
139
|
+
.ev-l.del .ev-s{color:var(--warn,#D9534F)}
|
|
140
|
+
.ev-more{font-size:11px;color:var(--muted);padding:3px 9px 5px}
|
|
141
|
+
|
|
142
|
+
/* ---- contributors: who has worked on an area (blast --export-viz) ---- */
|
|
143
|
+
.lchip.lchip-people{border-color:var(--con);color:var(--con)}
|
|
144
|
+
.owners{display:flex;flex-direction:column;gap:2px;margin:6px 0 2px}
|
|
145
|
+
.own{display:flex;align-items:center;gap:9px;padding:6px 8px;border-radius:7px;background:var(--panel2);border:1px solid var(--border2)}
|
|
146
|
+
.av{
|
|
147
|
+
width:25px;height:25px;border-radius:50%;flex:none;display:grid;place-items:center;
|
|
148
|
+
font-family:ui-monospace,"SF Mono",SFMono-Regular,Menlo,Consolas,monospace;
|
|
149
|
+
font-size:10px;font-weight:700;color:var(--con);background:var(--chip);border:1px solid var(--con);
|
|
150
|
+
}
|
|
151
|
+
.own-txt{display:flex;flex-direction:column;min-width:0;gap:1px}
|
|
152
|
+
.own-name{font-size:12.5px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
153
|
+
.own-why{font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums}
|
|
154
|
+
.own-note{font-size:11px;color:var(--muted);padding:3px 8px 0;line-height:1.45}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
export interface VizNode {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
type: string;
|
|
5
|
+
summary: string;
|
|
6
|
+
sources: string[];
|
|
7
|
+
/** Code to show under the node, in place of `sources`. Set by
|
|
8
|
+
* `blast --export-viz`, where every node stands for real changed lines. */
|
|
9
|
+
evidence?: Evidence[];
|
|
10
|
+
/** Who has worked on this area, best first. Set by `blast --export-viz`. */
|
|
11
|
+
owners?: NodeOwner[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* One contributor on a node, as the exported page carries them.
|
|
15
|
+
*
|
|
16
|
+
* `last` is an ISO day rather than "9d ago" so the page stays truthful when it is
|
|
17
|
+
* opened a fortnight after it was published — the viewer does the arithmetic at
|
|
18
|
+
* read time. `handle` is absent whenever git carried no GitHub address for them,
|
|
19
|
+
* and the viewer must then render the name unlinked.
|
|
20
|
+
*/
|
|
21
|
+
export interface NodeOwner {
|
|
22
|
+
name: string;
|
|
23
|
+
handle?: string;
|
|
24
|
+
commits: number;
|
|
25
|
+
/** `YYYY-MM-DD` of their most recent commit in this area. */
|
|
26
|
+
last: string;
|
|
27
|
+
}
|
|
28
|
+
export interface VizEdge {
|
|
29
|
+
source: string;
|
|
30
|
+
target: string;
|
|
31
|
+
relation: string;
|
|
32
|
+
description?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* One line of code shown under a node, with the sign git gave it (` ` for an
|
|
36
|
+
* unchanged line quoted as context — the affected side has no diff to show).
|
|
37
|
+
*/
|
|
38
|
+
export interface EvidenceLine {
|
|
39
|
+
/** Post-image line number; a deleted line has none. */
|
|
40
|
+
n: number | null;
|
|
41
|
+
sign: "+" | "-" | " ";
|
|
42
|
+
text: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* A snippet a panel shows instead of a bare path.
|
|
46
|
+
*
|
|
47
|
+
* A reviewer reading "src/blast/blast-cli.ts · L172-L193" has to go and open the
|
|
48
|
+
* file to learn anything; the same block with four lines of the actual change in
|
|
49
|
+
* it answers the question where they are standing.
|
|
50
|
+
*/
|
|
51
|
+
export interface Evidence {
|
|
52
|
+
/** `symbol · path:12-34` — grep-able, because a span alone is not. */
|
|
53
|
+
label: string;
|
|
54
|
+
/** Why these lines are here, e.g. `calls blastVizGraph` or `added`. */
|
|
55
|
+
note?: string;
|
|
56
|
+
lines: EvidenceLine[];
|
|
57
|
+
/** Lines the cap dropped, so a folded hunk says so rather than lying. */
|
|
58
|
+
more?: number;
|
|
59
|
+
}
|
|
60
|
+
export interface VizGraph {
|
|
61
|
+
meta: {
|
|
62
|
+
nodeCount: number;
|
|
63
|
+
edgeCount: number;
|
|
64
|
+
skippedFiles: number;
|
|
65
|
+
droppedEdges: number;
|
|
66
|
+
/** Why there is nothing to draw, when there is nothing to draw. A published
|
|
67
|
+
* page cannot answer a question a reader asks of the console, so an empty
|
|
68
|
+
* canvas has to say what it means — see `blastVizGraph`. */
|
|
69
|
+
emptyNote?: string;
|
|
70
|
+
};
|
|
71
|
+
nodes: VizNode[];
|
|
72
|
+
edges: VizEdge[];
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Legacy vague verbs → the concrete verb they usually mean. Keeps old
|
|
76
|
+
* `.context/` folders readable without regeneration; the synthesizer itself
|
|
77
|
+
* is constrained to the closed vocabulary going forward.
|
|
78
|
+
*/
|
|
79
|
+
export declare const NORMALIZE_RELATION: Record<string, string>;
|
|
80
|
+
export declare function normalizeRelation(rel: string): string;
|
|
81
|
+
/** Read a context dir and assemble the render-ready graph document. */
|
|
82
|
+
export declare function assembleContextGraph(contextDir: string): VizGraph;
|
|
83
|
+
//# sourceMappingURL=assemble.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assemble.d.ts","sourceRoot":"","sources":["../../src/viz/assemble.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;+EAC2E;IAC3E,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;IACtB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjB,IAAI,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE;QACJ,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB;;oEAE4D;QAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,KAAK,EAAE,OAAO,EAAE,CAAC;CAClB;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAKrD,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAErD;AAoBD,uEAAuE;AACvE,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,CAmDjE"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assembles the viz-facing JSON for the context graph: reads every `.md` node
|
|
3
|
+
* file in a context dir (frontmatter = node + edges) and produces a single
|
|
4
|
+
* `{meta, nodes, edges}` document the viewer can render directly.
|
|
5
|
+
*
|
|
6
|
+
* Design rules (see docs/superpowers/specs/2026-07-15-graft-viz-design.md):
|
|
7
|
+
* - relations are normalized into the closed verb vocabulary — vague LLM
|
|
8
|
+
* softeners map to the concrete verb they usually mean
|
|
9
|
+
* - edges whose target slug doesn't exist are dropped (LLM output can dangle)
|
|
10
|
+
* - a node file with unparseable frontmatter is skipped, never fatal
|
|
11
|
+
* - both drop counts are reported in `meta` so the UI can say so
|
|
12
|
+
*/
|
|
13
|
+
import { readFileSync, readdirSync, existsSync } from "node:fs";
|
|
14
|
+
import { join } from "node:path";
|
|
15
|
+
import { matter } from "../util/front-matter.js";
|
|
16
|
+
/**
|
|
17
|
+
* Legacy vague verbs → the concrete verb they usually mean. Keeps old
|
|
18
|
+
* `.context/` folders readable without regeneration; the synthesizer itself
|
|
19
|
+
* is constrained to the closed vocabulary going forward.
|
|
20
|
+
*/
|
|
21
|
+
export const NORMALIZE_RELATION = {
|
|
22
|
+
influences: "configures",
|
|
23
|
+
supports: "validates",
|
|
24
|
+
defines: "validates",
|
|
25
|
+
measures: "validates",
|
|
26
|
+
};
|
|
27
|
+
export function normalizeRelation(rel) {
|
|
28
|
+
return NORMALIZE_RELATION[rel] ?? rel;
|
|
29
|
+
}
|
|
30
|
+
const GEN_START = "<!-- context:generated:start -->";
|
|
31
|
+
const GEN_END = "<!-- context:generated:end -->";
|
|
32
|
+
const SUMMARY_MAX = 500;
|
|
33
|
+
/** Pull the prose summary out of a node body's generated block. */
|
|
34
|
+
function extractSummary(body) {
|
|
35
|
+
let text = body;
|
|
36
|
+
const start = text.indexOf(GEN_START);
|
|
37
|
+
const end = text.indexOf(GEN_END);
|
|
38
|
+
if (start >= 0 && end > start)
|
|
39
|
+
text = text.slice(start + GEN_START.length, end);
|
|
40
|
+
// Keep only the Summary section if headings are present.
|
|
41
|
+
const related = text.indexOf("## Related");
|
|
42
|
+
if (related >= 0)
|
|
43
|
+
text = text.slice(0, related);
|
|
44
|
+
text = text.replace(/^##\s+Summary\s*$/m, "");
|
|
45
|
+
text = text.trim();
|
|
46
|
+
return text.length > SUMMARY_MAX ? text.slice(0, SUMMARY_MAX).trimEnd() + "…" : text;
|
|
47
|
+
}
|
|
48
|
+
/** Read a context dir and assemble the render-ready graph document. */
|
|
49
|
+
export function assembleContextGraph(contextDir) {
|
|
50
|
+
const nodes = [];
|
|
51
|
+
const rawEdges = [];
|
|
52
|
+
let skippedFiles = 0;
|
|
53
|
+
if (existsSync(contextDir)) {
|
|
54
|
+
for (const entry of readdirSync(contextDir).sort()) {
|
|
55
|
+
if (!entry.endsWith(".md"))
|
|
56
|
+
continue;
|
|
57
|
+
let parsed;
|
|
58
|
+
try {
|
|
59
|
+
parsed = matter(readFileSync(join(contextDir, entry), "utf8"));
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
skippedFiles++;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const fm = parsed.data;
|
|
66
|
+
const id = String(fm.slug ?? entry.replace(/\.md$/, ""));
|
|
67
|
+
const sources = Array.isArray(fm.sources) ? fm.sources : [];
|
|
68
|
+
const links = Array.isArray(fm.links) ? fm.links : [];
|
|
69
|
+
nodes.push({
|
|
70
|
+
id,
|
|
71
|
+
name: String(fm.name ?? id),
|
|
72
|
+
type: String(fm.type ?? "concept"),
|
|
73
|
+
summary: extractSummary(parsed.content),
|
|
74
|
+
sources: sources.map((s) => s.path),
|
|
75
|
+
});
|
|
76
|
+
for (const link of links) {
|
|
77
|
+
if (!link || typeof link.to !== "string")
|
|
78
|
+
continue;
|
|
79
|
+
rawEdges.push({
|
|
80
|
+
source: id,
|
|
81
|
+
target: link.to,
|
|
82
|
+
relation: normalizeRelation(String(link.relation ?? "uses")),
|
|
83
|
+
...(link.description ? { description: link.description } : {}),
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const known = new Set(nodes.map((n) => n.id));
|
|
89
|
+
const edges = rawEdges.filter((e) => known.has(e.source) && known.has(e.target));
|
|
90
|
+
return {
|
|
91
|
+
meta: {
|
|
92
|
+
nodeCount: nodes.length,
|
|
93
|
+
edgeCount: edges.length,
|
|
94
|
+
skippedFiles,
|
|
95
|
+
droppedEdges: rawEdges.length - edges.length,
|
|
96
|
+
},
|
|
97
|
+
nodes,
|
|
98
|
+
edges,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=assemble.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assemble.js","sourceRoot":"","sources":["../../src/viz/assemble.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAwB,MAAM,yBAAyB,CAAC;AAkFvE;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA2B;IACxD,UAAU,EAAE,YAAY;IACxB,QAAQ,EAAE,WAAW;IACrB,OAAO,EAAE,WAAW;IACpB,QAAQ,EAAE,WAAW;CACtB,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,OAAO,kBAAkB,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;AACxC,CAAC;AAED,MAAM,SAAS,GAAG,kCAAkC,CAAC;AACrD,MAAM,OAAO,GAAG,gCAAgC,CAAC;AACjD,MAAM,WAAW,GAAG,GAAG,CAAC;AAExB,mEAAmE;AACnE,SAAS,cAAc,CAAC,IAAY;IAClC,IAAI,IAAI,GAAG,IAAI,CAAC;IAChB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,KAAK,IAAI,CAAC,IAAI,GAAG,GAAG,KAAK;QAAE,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChF,yDAAyD;IACzD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC3C,IAAI,OAAO,IAAI,CAAC;QAAE,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAChD,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;IAC9C,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IACnB,OAAO,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AACvF,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,oBAAoB,CAAC,UAAkB;IACrD,MAAM,KAAK,GAAc,EAAE,CAAC;IAC5B,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,IAAI,YAAY,GAAG,CAAC,CAAC;IAErB,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACnD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAAE,SAAS;YACrC,IAAI,MAAuB,CAAC;YAC5B,IAAI,CAAC;gBACH,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;YACjE,CAAC;YAAC,MAAM,CAAC;gBACP,YAAY,EAAE,CAAC;gBACf,SAAS;YACX,CAAC;YACD,MAAM,EAAE,GAAG,MAAM,CAAC,IAA+B,CAAC;YAClD,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;YACzD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,OAAuB,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7E,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,KAAoB,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE;gBACF,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;gBAC3B,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,IAAI,SAAS,CAAC;gBAClC,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC;gBACvC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;aACpC,CAAC,CAAC;YACH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ;oBAAE,SAAS;gBACnD,QAAQ,CAAC,IAAI,CAAC;oBACZ,MAAM,EAAE,EAAE;oBACV,MAAM,EAAE,IAAI,CAAC,EAAE;oBACf,QAAQ,EAAE,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,CAAC;oBAC5D,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC/D,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAEjF,OAAO;QACL,IAAI,EAAE;YACJ,SAAS,EAAE,KAAK,CAAC,MAAM;YACvB,SAAS,EAAE,KAAK,CAAC,MAAM;YACvB,YAAY;YACZ,YAAY,EAAE,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM;SAC7C;QACD,KAAK;QACL,KAAK;KACN,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type VizGraph } from "./assemble.js";
|
|
2
|
+
export interface VizExportOptions {
|
|
3
|
+
contextDir: string;
|
|
4
|
+
/** Where index.html, app.js and style.css were bundled (dist/viewer). */
|
|
5
|
+
viewerDir: string;
|
|
6
|
+
/** Directory to write index.html into. Created if absent. */
|
|
7
|
+
outDir: string;
|
|
8
|
+
repoName: string;
|
|
9
|
+
/** Shown in the appbar beside the repo name — e.g. "PR #151". */
|
|
10
|
+
subtitle?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Context graph to inline instead of assembling one from the deep tier's concept
|
|
13
|
+
* files. `graft blast --export-viz` passes the blast radius itself, which is how a
|
|
14
|
+
* PR gets a Context tab worth opening without a `--deep` build.
|
|
15
|
+
*/
|
|
16
|
+
contextGraph?: VizGraph;
|
|
17
|
+
/**
|
|
18
|
+
* Tabs the page offers. Default: all three.
|
|
19
|
+
*
|
|
20
|
+
* A blast page passes `["context"]`. The Code tab there is the repo's whole
|
|
21
|
+
* wiring graph — 1,377 nodes on graft itself, a hairball that answers nothing
|
|
22
|
+
* about the pull request, and ~95% of the exported megabyte — and Outline is the
|
|
23
|
+
* repo's file tree. Dropping them makes the page a tenth of the size and removes
|
|
24
|
+
* two tabs a reviewer has no reason to open.
|
|
25
|
+
*/
|
|
26
|
+
tabs?: Array<"context" | "code" | "outline">;
|
|
27
|
+
}
|
|
28
|
+
export interface VizExportResult {
|
|
29
|
+
file: string;
|
|
30
|
+
bytes: number;
|
|
31
|
+
contextNodes: number;
|
|
32
|
+
codeNodes: number;
|
|
33
|
+
/** Tab the exported page opens on — see the reasoning in {@link exportViz}. */
|
|
34
|
+
defaultTab: "context" | "code";
|
|
35
|
+
/** Tabs written into the page. */
|
|
36
|
+
tabs: Array<"context" | "code" | "outline">;
|
|
37
|
+
}
|
|
38
|
+
export declare function exportViz(opts: VizExportOptions): VizExportResult;
|
|
39
|
+
//# sourceMappingURL=export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/viz/export.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAwB,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEpE,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,SAAS,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,YAAY,CAAC,EAAE,QAAQ,CAAC;IACxB;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC;CAC9C;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,UAAU,EAAE,SAAS,GAAG,MAAM,CAAC;IAC/B,kCAAkC;IAClC,IAAI,EAAE,KAAK,CAAC,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC;CAC7C;AAmCD,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,eAAe,CAmDjE"}
|