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,258 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tier-2 pass: attach the LLM meaning layer (`summary` + `crux`) to nodes.
|
|
3
|
+
*
|
|
4
|
+
* graph.json is its own cache — the committed file already holds every node's
|
|
5
|
+
* summary/crux from a prior run. So this pass is diff-driven:
|
|
6
|
+
*
|
|
7
|
+
* - cache hit — a prior node with the same id, same `body_hash`, and
|
|
8
|
+
* `summary_state:"ready"` → carry its summary/crux over, no LLM call.
|
|
9
|
+
* - stale — a prior ready summary whose body has since changed → keep the
|
|
10
|
+
* old text as a hint but mark it "stale". Recomputed only if an LLM is given.
|
|
11
|
+
* - pending — new or never-summarized node → one LLM call when an LLM is
|
|
12
|
+
* given, otherwise left "pending".
|
|
13
|
+
*
|
|
14
|
+
* Passing no summarizer runs the cache/stale bookkeeping alone (no calls, no
|
|
15
|
+
* cost) — which is what a plain `graph` build does, so it never wipes the
|
|
16
|
+
* meaning layer a previous `--llm` run produced.
|
|
17
|
+
*
|
|
18
|
+
* The LLM returns line numbers into the slice it was shown; we consume them here,
|
|
19
|
+
* once, to cut `crux.code` verbatim from the source. `crux.span` is a pointer
|
|
20
|
+
* only and is never used to re-slice.
|
|
21
|
+
*/
|
|
22
|
+
import { formatCruxMiss, formatCruxMissDetail } from "../ai/crux.js";
|
|
23
|
+
import { LlmFailureGate } from "../ai/failure.js";
|
|
24
|
+
/** Cap on the stored crux: an over-long pick is trimmed to its leading slice. */
|
|
25
|
+
const MAX_CRUX_LINES = 12;
|
|
26
|
+
/** Files summarized at once. Each is an independent LLM call; order is preserved. */
|
|
27
|
+
const DEFAULT_CONCURRENCY = 5;
|
|
28
|
+
/** How often the crux pass flushes partial progress to disk. Read at call time (not
|
|
29
|
+
* module load) so a test seam `GRAFT_CRUX_CHECKPOINT_MS=0` (flush on every completed
|
|
30
|
+
* file) takes effect. */
|
|
31
|
+
function checkpointMs() {
|
|
32
|
+
return Number(process.env.GRAFT_CRUX_CHECKPOINT_MS ?? 15000);
|
|
33
|
+
}
|
|
34
|
+
export async function enrichGraph(nodes, prior, sources, opts = {}) {
|
|
35
|
+
const stats = {
|
|
36
|
+
cached: 0,
|
|
37
|
+
computed: 0,
|
|
38
|
+
stale: 0,
|
|
39
|
+
pending: 0,
|
|
40
|
+
errors: [],
|
|
41
|
+
failedFiles: 0,
|
|
42
|
+
skippedFiles: 0,
|
|
43
|
+
};
|
|
44
|
+
// Which nodes actually need an LLM call this run (after cache carry-over).
|
|
45
|
+
const dirty = [];
|
|
46
|
+
for (const node of nodes) {
|
|
47
|
+
const was = prior.get(node.id);
|
|
48
|
+
if (was?.summary_state === "ready" && was.body_hash === node.body_hash) {
|
|
49
|
+
node.summary = was.summary;
|
|
50
|
+
node.crux = was.crux;
|
|
51
|
+
node.summary_state = "ready";
|
|
52
|
+
stats.cached++;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
// needs computing; seed with the old summary as a stale hint when one exists.
|
|
56
|
+
if (was && was.summary) {
|
|
57
|
+
node.summary = was.summary;
|
|
58
|
+
node.crux = was.crux;
|
|
59
|
+
node.summary_state = "stale";
|
|
60
|
+
}
|
|
61
|
+
dirty.push(node);
|
|
62
|
+
}
|
|
63
|
+
if (!opts.summarizer) {
|
|
64
|
+
for (const node of dirty) {
|
|
65
|
+
if (node.summary_state === "stale")
|
|
66
|
+
stats.stale++;
|
|
67
|
+
else
|
|
68
|
+
stats.pending++;
|
|
69
|
+
}
|
|
70
|
+
return stats;
|
|
71
|
+
}
|
|
72
|
+
// One LLM call per file: group the dirty nodes by the file they live in.
|
|
73
|
+
const byFile = new Map();
|
|
74
|
+
for (const node of dirty) {
|
|
75
|
+
if (!sources.has(node.path))
|
|
76
|
+
continue;
|
|
77
|
+
const arr = byFile.get(node.path);
|
|
78
|
+
if (arr)
|
|
79
|
+
arr.push(node);
|
|
80
|
+
else
|
|
81
|
+
byFile.set(node.path, [node]);
|
|
82
|
+
}
|
|
83
|
+
// Each file is an independent LLM call, so run several in flight at once —
|
|
84
|
+
// the slow part is the round-trip, not local work. Files never share state:
|
|
85
|
+
// one file's nodes and source stand alone, so parallelism can't corrupt the
|
|
86
|
+
// per-file line numbers the crux slicing depends on. `stats` mutation is safe
|
|
87
|
+
// because JS is single-threaded — increments run between awaits, never during.
|
|
88
|
+
const summarizer = opts.summarizer;
|
|
89
|
+
const files = [...byFile.keys()];
|
|
90
|
+
const limit = Math.max(1, opts.concurrency ?? DEFAULT_CONCURRENCY);
|
|
91
|
+
let done = 0;
|
|
92
|
+
const flushEvery = checkpointMs();
|
|
93
|
+
let lastCheckpoint = Date.now();
|
|
94
|
+
// Shared with the concept pass (`context/build.ts`), so both agree on when a
|
|
95
|
+
// provider has stopped working. Counted across the whole pass, not per worker:
|
|
96
|
+
// with `-j 5` the interleaving is what a user sees as "everything is failing now".
|
|
97
|
+
const gate = new LlmFailureGate();
|
|
98
|
+
await mapWithConcurrency(files, limit, async (path) => {
|
|
99
|
+
const fileNodes = byFile.get(path);
|
|
100
|
+
const source = sources.get(path);
|
|
101
|
+
const lineCount = source.split("\n").length;
|
|
102
|
+
// Once the pass is fatal, the remaining files are not attempted: every call
|
|
103
|
+
// would fail the same way, and on a metered gateway each one still costs a
|
|
104
|
+
// request. They are counted so the caller can report what was left undone.
|
|
105
|
+
if (gate.stopped) {
|
|
106
|
+
gate.skip();
|
|
107
|
+
for (const node of fileNodes) {
|
|
108
|
+
if (node.summary_state === "stale")
|
|
109
|
+
stats.stale++;
|
|
110
|
+
else
|
|
111
|
+
stats.pending++;
|
|
112
|
+
}
|
|
113
|
+
// Still reported, so the caller's progress counter reaches `total` instead of
|
|
114
|
+
// freezing at the file that broke — the abort is announced by the build's
|
|
115
|
+
// summary, not by a stalled line.
|
|
116
|
+
opts.onProgress?.({ index: done++, total: files.length, node: path });
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const refs = fileNodes.map((n) => {
|
|
120
|
+
const [startLine, endLine] = spanLines(n.span, lineCount);
|
|
121
|
+
return { id: n.id, kind: n.kind, signature: n.signature, startLine, endLine };
|
|
122
|
+
});
|
|
123
|
+
const { results, error, quality } = await collectFileCrux(summarizer, path, source, refs);
|
|
124
|
+
let fileError = error;
|
|
125
|
+
if (fileError) {
|
|
126
|
+
stats.errors.push(`${path}: ${fileError}${cruxMissDetail(summarizer)}`);
|
|
127
|
+
gate.record(fileError, { quality });
|
|
128
|
+
}
|
|
129
|
+
let applied = 0;
|
|
130
|
+
for (const node of fileNodes) {
|
|
131
|
+
const r = results.size > 0 ? results.get(node.id) : undefined;
|
|
132
|
+
// Empty / whitespace-only summaries are not success: caching them as
|
|
133
|
+
// `ready` made the next `--deep` a permanent cache hit (#172).
|
|
134
|
+
if (!r || !r.summary.trim()) {
|
|
135
|
+
// whole-file call failed, the model skipped this symbol, or it returned
|
|
136
|
+
// an empty summary: keep what it had and leave it retryable.
|
|
137
|
+
if (node.summary_state === "stale")
|
|
138
|
+
stats.stale++;
|
|
139
|
+
else
|
|
140
|
+
stats.pending++;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
node.summary = r.summary;
|
|
144
|
+
node.crux = buildCrux(r, node, source, lineCount);
|
|
145
|
+
node.summary_state = "ready";
|
|
146
|
+
stats.computed++;
|
|
147
|
+
applied++;
|
|
148
|
+
}
|
|
149
|
+
if (!fileError && refs.length > 0 && applied === 0) {
|
|
150
|
+
// collectFileCrux already labels a total miss; this catches "got entries
|
|
151
|
+
// but every summary was blank" so the CLI's #127 degraded-exit path fires.
|
|
152
|
+
fileError = cruxMissMessage(summarizer, "empty-parsed");
|
|
153
|
+
stats.errors.push(`${path}: ${fileError}${cruxMissDetail(summarizer)}`);
|
|
154
|
+
gate.record(fileError, { quality: true });
|
|
155
|
+
}
|
|
156
|
+
else if (!fileError) {
|
|
157
|
+
gate.succeeded();
|
|
158
|
+
}
|
|
159
|
+
// Report on completion so the counter climbs monotonically under concurrency.
|
|
160
|
+
opts.onProgress?.({ index: done++, total: files.length, node: path });
|
|
161
|
+
// Flush partial crux to disk periodically, so a killed --deep run keeps what it
|
|
162
|
+
// has already computed (#128). Throttled by wall-clock; the caller's checkpoint
|
|
163
|
+
// writes wiring.json atomically, and the next run folds it back in by body_hash.
|
|
164
|
+
if (opts.checkpoint && Date.now() - lastCheckpoint >= flushEvery) {
|
|
165
|
+
lastCheckpoint = Date.now();
|
|
166
|
+
opts.checkpoint();
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
stats.failedFiles = gate.failed;
|
|
170
|
+
stats.skippedFiles = gate.skipped;
|
|
171
|
+
stats.fatal = gate.fatal;
|
|
172
|
+
return stats;
|
|
173
|
+
}
|
|
174
|
+
/** Run `fn` over `items` with at most `limit` in flight, preserving result order. */
|
|
175
|
+
async function mapWithConcurrency(items, limit, fn) {
|
|
176
|
+
const results = new Array(items.length);
|
|
177
|
+
let next = 0;
|
|
178
|
+
const workers = Array.from({ length: Math.min(limit, items.length) }, async () => {
|
|
179
|
+
while (next < items.length) {
|
|
180
|
+
const i = next++;
|
|
181
|
+
results[i] = await fn(items[i], i);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
await Promise.all(workers);
|
|
185
|
+
return results;
|
|
186
|
+
}
|
|
187
|
+
function cruxMissMessage(summarizer, fallback) {
|
|
188
|
+
const miss = summarizer.lastMiss;
|
|
189
|
+
return formatCruxMiss(miss?.kind ?? fallback, miss?.finishReason ?? null);
|
|
190
|
+
}
|
|
191
|
+
/** The echoed id behind an `id-mismatch`, as an indented second line; "" otherwise. */
|
|
192
|
+
function cruxMissDetail(summarizer) {
|
|
193
|
+
const detail = formatCruxMissDetail(summarizer.lastMiss);
|
|
194
|
+
return detail ? `\n ${detail}` : "";
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Describe every requested definition in a file, re-asking for any the model
|
|
198
|
+
* omits (it sometimes drops entries from a batch). Returns whatever it collected
|
|
199
|
+
* plus the last error, if any — partial results are kept, not discarded.
|
|
200
|
+
*/
|
|
201
|
+
async function collectFileCrux(summarizer, path, source, refs) {
|
|
202
|
+
const results = new Map();
|
|
203
|
+
let missing = refs;
|
|
204
|
+
let error;
|
|
205
|
+
for (let attempt = 0; attempt < 2 && missing.length > 0; attempt++) {
|
|
206
|
+
try {
|
|
207
|
+
const list = await summarizer.describeFile({ path, source, nodes: missing });
|
|
208
|
+
for (const r of list)
|
|
209
|
+
if (!results.has(r.id))
|
|
210
|
+
results.set(r.id, r);
|
|
211
|
+
missing = refs.filter((r) => !results.has(r.id));
|
|
212
|
+
}
|
|
213
|
+
catch (err) {
|
|
214
|
+
error = err instanceof Error ? err.message : String(err);
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// A total miss used to return `{ results: ∅ }` with no error — enrich left
|
|
219
|
+
// every node `pending`, the CLI exited 0, and `graft check` told the user to
|
|
220
|
+
// re-run `--deep` forever (#172). Surface it as a failure like a thrown error.
|
|
221
|
+
// Content-quality, not quota: count the file, keep going (#235).
|
|
222
|
+
if (!error && refs.length > 0 && results.size === 0) {
|
|
223
|
+
return { results, error: cruxMissMessage(summarizer, "empty-toolCalls"), quality: true };
|
|
224
|
+
}
|
|
225
|
+
return { results, error };
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Cut the crux text verbatim from the file using the model's file-absolute line
|
|
229
|
+
* range, clamped to the node's own span. Returns null when the model reported no
|
|
230
|
+
* distinct crux (0/0) or gave an unusable range.
|
|
231
|
+
*/
|
|
232
|
+
function buildCrux(r, node, source, lineCount) {
|
|
233
|
+
// 0/0 (or an invalid range) is the model saying "nothing to highlight here".
|
|
234
|
+
if (r.crux_start < 1 || r.crux_end < r.crux_start)
|
|
235
|
+
return null;
|
|
236
|
+
const [nodeStart, nodeEnd] = spanLines(node.span, lineCount);
|
|
237
|
+
const start = Math.max(nodeStart, Math.min(r.crux_start, nodeEnd));
|
|
238
|
+
let end = Math.max(start, Math.min(r.crux_end, nodeEnd));
|
|
239
|
+
// Keep the crux readable: if the model pointed at a big region, store its
|
|
240
|
+
// leading slice (the anchor it chose) rather than the whole blob — still the
|
|
241
|
+
// most important part, and the full definition is reachable via node.span.
|
|
242
|
+
if (end - start + 1 > MAX_CRUX_LINES)
|
|
243
|
+
end = start + MAX_CRUX_LINES - 1;
|
|
244
|
+
const code = source.split("\n").slice(start - 1, end).join("\n");
|
|
245
|
+
if (!code.trim())
|
|
246
|
+
return null;
|
|
247
|
+
return { code, span: `L${start}-L${end}` };
|
|
248
|
+
}
|
|
249
|
+
/** Parse a `"L12-L30"` span into a clamped [start, end] line pair (1-based). */
|
|
250
|
+
function spanLines(span, fileLines) {
|
|
251
|
+
const m = /^L(\d+)-L(\d+)$/.exec(span);
|
|
252
|
+
if (!m)
|
|
253
|
+
return [1, fileLines];
|
|
254
|
+
const start = Math.max(1, Math.min(Number(m[1]), fileLines));
|
|
255
|
+
const end = Math.max(start, Math.min(Number(m[2]), fileLines));
|
|
256
|
+
return [start, end];
|
|
257
|
+
}
|
|
258
|
+
//# sourceMappingURL=enrich.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enrich.js","sourceRoot":"","sources":["../../src/graph/enrich.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { RawEdge } from "./extract.js";
|
|
2
|
+
import type { NodeV1 } from "./types.js";
|
|
3
|
+
export declare const EXTRACT_CACHE_PREFIX = "extract";
|
|
4
|
+
export interface ExtractEntry {
|
|
5
|
+
size: number;
|
|
6
|
+
mtimeMs: number;
|
|
7
|
+
/** sha256 of the file's bytes — the same value as its `kind:"file"` node's `body_hash`. */
|
|
8
|
+
hash: string;
|
|
9
|
+
nodes: NodeV1[];
|
|
10
|
+
rawEdges: RawEdge[];
|
|
11
|
+
/** Set when this file couldn't be read or parsed. The entry exists anyway so the
|
|
12
|
+
* freshness probe doesn't flag the file as new on every query; replaying it
|
|
13
|
+
* re-reports the same error and contributes no nodes, exactly as a cold build
|
|
14
|
+
* would. */
|
|
15
|
+
error?: string;
|
|
16
|
+
/** The breadth-tier grammar that parsed this file standing in for its depth-tier
|
|
17
|
+
* one, whose grammar didn't load. Absent for every other file. The entry is
|
|
18
|
+
* replayed only while the same stand-in would parse it again. */
|
|
19
|
+
via?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ExtractCache {
|
|
22
|
+
version: number;
|
|
23
|
+
/** Identity of the extractor that produced these entries. */
|
|
24
|
+
extractor: string;
|
|
25
|
+
/** repo-relative source path → its last parse. */
|
|
26
|
+
files: Record<string, ExtractEntry>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Where this graft's memo lives: `<outDir>/.cache/extract.<stamp>.json`.
|
|
30
|
+
*
|
|
31
|
+
* The stamp is in the *filename*, not just inside the file, so two grafts working
|
|
32
|
+
* on one repo keep separate memos instead of evicting each other. That is the
|
|
33
|
+
* default install, not an exotic case: `graft init` wires the MCP server as
|
|
34
|
+
* `npx -y @nanonets/graft` (which resolves the latest published version) while the
|
|
35
|
+
* Claude Code hooks run the locally installed one. The moment those two versions
|
|
36
|
+
* differ, a single shared file means the prompt hook and every MCP retrieval take
|
|
37
|
+
* turns rejecting each other's entries and cold-re-parsing the whole repo — the memo
|
|
38
|
+
* would never help anyone.
|
|
39
|
+
*
|
|
40
|
+
* Null stamp → null path → no memo at all. See {@link extractorStamp}.
|
|
41
|
+
*/
|
|
42
|
+
export declare function extractCachePath(outDir: string): string | null;
|
|
43
|
+
/** Keep `.cache/` from growing a file per version forever: after writing, drop all
|
|
44
|
+
* but the newest `keep` files sharing a prefix. Best-effort and never fatal — this
|
|
45
|
+
* is a cache directory, and a failure here costs disk, not correctness. */
|
|
46
|
+
export declare function pruneSidecars(cacheDir: string, prefix: string, keep?: number): void;
|
|
47
|
+
/**
|
|
48
|
+
* Identity of the code that produces the cached parses. Both sidecars key on it,
|
|
49
|
+
* so *anything* that can change extraction output has to change this string.
|
|
50
|
+
*
|
|
51
|
+
* Content-hashed over every sibling module in this directory, plus the package
|
|
52
|
+
* version. Two earlier instincts are deliberately rejected:
|
|
53
|
+
*
|
|
54
|
+
* - **Not a timestamp.** This was `mtime:size` of `extract.js` alone, which is
|
|
55
|
+
* wrong in both directions. Too loose: the parse of `db.count()` depends on
|
|
56
|
+
* `bindings.ts` deciding that `db` is a `UserRepo` (that answer is stored *in*
|
|
57
|
+
* the cached entry, as an edge's `recvType`), and fixing a binding bug leaves
|
|
58
|
+
* `extract.js`'s emitted bytes untouched — so any build that skips rewriting
|
|
59
|
+
* unchanged output keeps the old stamp and silently replays pre-fix edges. Too
|
|
60
|
+
* tight: a rebuild that rewrites identical content moves the mtime and throws
|
|
61
|
+
* away the whole memo for nothing.
|
|
62
|
+
* - **Not a hand-kept list of modules.** A list is correct exactly until someone
|
|
63
|
+
* moves parse logic into a module nobody added to it, and the failure is silent.
|
|
64
|
+
*
|
|
65
|
+
* Hashing the directory over-invalidates a little — editing any `graph/` module
|
|
66
|
+
* costs one cold rebuild — which is no more often than a version bump already
|
|
67
|
+
* costs, and always in the safe direction. The package version is folded in so a
|
|
68
|
+
* tree-sitter grammar upgrade (which changes parse output without changing any of
|
|
69
|
+
* graft's own files) invalidates too.
|
|
70
|
+
*
|
|
71
|
+
* Measured at ~0.5ms for 21 files / 556KB, paid once per process.
|
|
72
|
+
*
|
|
73
|
+
* **Null when no identity can be established at all**, and that is deliberately not
|
|
74
|
+
* a string. It used to return `"unknown"` on failure — but `"unknown"` was then
|
|
75
|
+
* *written into the sidecars as a real identity*, and every later run compared equal
|
|
76
|
+
* to it, so any environment where stamping fails (a `pkg`/`bun-compile` single-file
|
|
77
|
+
* build, an asar-style read, a directory that can't be listed) permanently lost the
|
|
78
|
+
* ability to notice an extractor change. A sentinel that doubles as a valid value
|
|
79
|
+
* silently disables the whole mechanism. Null forces callers to decide instead, and
|
|
80
|
+
* {@link extractCachePath} decides not to have a memo.
|
|
81
|
+
*/
|
|
82
|
+
export declare function extractorStamp(): string | null;
|
|
83
|
+
/**
|
|
84
|
+
* Hash every `ext` file in `dir`, plus `version`. Null when the directory holds no
|
|
85
|
+
* such file. Separated from {@link extractorStamp} so a test can prove the property
|
|
86
|
+
* that matters: a change to *any* module in the directory moves the stamp, not just
|
|
87
|
+
* the one the old implementation happened to watch.
|
|
88
|
+
*/
|
|
89
|
+
export declare function stampDir(dir: string, ext: string, version?: string): string | null;
|
|
90
|
+
export declare function emptyExtractCache(): ExtractCache;
|
|
91
|
+
/** The cache for `outDir`, or an empty one when it's absent, unparseable, written by
|
|
92
|
+
* a different cache version, or when this graft has no identity to key on (then
|
|
93
|
+
* every build is cold, which is slow but never wrong). The stamp is in the filename,
|
|
94
|
+
* so the `extractor` field is a second check rather than the only one. */
|
|
95
|
+
export declare function readExtractCache(outDir: string): ExtractCache;
|
|
96
|
+
/** Best-effort write — a full graph is already on disk by the time this runs, so an
|
|
97
|
+
* unwritable cache dir must never fail the build (it only costs the next build its
|
|
98
|
+
* reuse). Returns false when nothing was written, including the deliberate case of
|
|
99
|
+
* having no extractor identity: a parse we can't attribute must never be replayed. */
|
|
100
|
+
export declare function writeExtractCache(outDir: string, cache: ExtractCache): boolean;
|
|
101
|
+
//# sourceMappingURL=extract-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-cache.d.ts","sourceRoot":"","sources":["../../src/graph/extract-cache.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAIzC,eAAO,MAAM,oBAAoB,YAAY,CAAC;AAE9C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,2FAA2F;IAC3F,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB;;;gBAGY;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;qEAEiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACrC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG9D;AAED;;2EAE2E;AAC3E,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,SAAI,GAAG,IAAI,CAa9E;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAG9C;AAoBD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,SAAK,GAAG,MAAM,GAAG,IAAI,CAU9E;AAYD,wBAAgB,iBAAiB,IAAI,YAAY,CAEhD;AAED;;;0EAG0E;AAC1E,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAS7D;AAED;;;sFAGsF;AACtF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAU9E"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-file memo for Tier-1 extraction — `<outDir>/.cache/extract.json`.
|
|
3
|
+
*
|
|
4
|
+
* `extractFile` is pure and file-local (`rel`, `source`, `lang` → `{nodes,
|
|
5
|
+
* rawEdges}`), which is the whole trick: an unchanged file's parse result can be
|
|
6
|
+
* replayed from disk instead of re-running tree-sitter. That turns
|
|
7
|
+
* {@link buildGraph} from "always re-parse the repo" (~4.6ms/file) into "re-parse
|
|
8
|
+
* only what moved", which is what makes a rebuild cheap enough to run *before*
|
|
9
|
+
* every query (see `graph/refresh.ts`).
|
|
10
|
+
*
|
|
11
|
+
* Everything downstream of extraction (edge resolution, enrichment, the graph
|
|
12
|
+
* write, the ask sidecar, cards) still runs over the whole merged node set, so no
|
|
13
|
+
* other invariant changes — an incremental build must produce a byte-identical
|
|
14
|
+
* `wiring.json` to a cold one.
|
|
15
|
+
*
|
|
16
|
+
* Crucially the cached nodes keep `body_text`: `writeGraph` strips it before
|
|
17
|
+
* serializing, so `wiring.json` can never be the reuse source — the ask sidecar
|
|
18
|
+
* needs a body for every node, including the ones we didn't re-parse.
|
|
19
|
+
*
|
|
20
|
+
* Lives under `.cache/` (gitignored, regenerate-anytime) next to `ask-index.json`
|
|
21
|
+
* and `summaries.json`. Two things invalidate the whole file: a bump of
|
|
22
|
+
* {@link CACHE_VERSION} for a change of on-disk shape, and a change to the
|
|
23
|
+
* extraction code itself, caught by content-hashing it — see
|
|
24
|
+
* {@link extractorStamp}. Neither asks anyone to remember to bump anything.
|
|
25
|
+
*/
|
|
26
|
+
import { readFileSync, readdirSync, rmSync, statSync } from "node:fs";
|
|
27
|
+
import { createHash } from "node:crypto";
|
|
28
|
+
import { fileURLToPath } from "node:url";
|
|
29
|
+
import { dirname, extname, join } from "node:path";
|
|
30
|
+
import { CACHE_DIR } from "../context/node-file.js";
|
|
31
|
+
import { readJson, writeJsonAtomic } from "../util/state.js";
|
|
32
|
+
/** Bump when the on-disk shape below changes. */
|
|
33
|
+
const CACHE_VERSION = 1;
|
|
34
|
+
export const EXTRACT_CACHE_PREFIX = "extract";
|
|
35
|
+
/**
|
|
36
|
+
* Where this graft's memo lives: `<outDir>/.cache/extract.<stamp>.json`.
|
|
37
|
+
*
|
|
38
|
+
* The stamp is in the *filename*, not just inside the file, so two grafts working
|
|
39
|
+
* on one repo keep separate memos instead of evicting each other. That is the
|
|
40
|
+
* default install, not an exotic case: `graft init` wires the MCP server as
|
|
41
|
+
* `npx -y @nanonets/graft` (which resolves the latest published version) while the
|
|
42
|
+
* Claude Code hooks run the locally installed one. The moment those two versions
|
|
43
|
+
* differ, a single shared file means the prompt hook and every MCP retrieval take
|
|
44
|
+
* turns rejecting each other's entries and cold-re-parsing the whole repo — the memo
|
|
45
|
+
* would never help anyone.
|
|
46
|
+
*
|
|
47
|
+
* Null stamp → null path → no memo at all. See {@link extractorStamp}.
|
|
48
|
+
*/
|
|
49
|
+
export function extractCachePath(outDir) {
|
|
50
|
+
const stamp = extractorStamp();
|
|
51
|
+
return stamp === null ? null : join(outDir, CACHE_DIR, `${EXTRACT_CACHE_PREFIX}.${stamp}.json`);
|
|
52
|
+
}
|
|
53
|
+
/** Keep `.cache/` from growing a file per version forever: after writing, drop all
|
|
54
|
+
* but the newest `keep` files sharing a prefix. Best-effort and never fatal — this
|
|
55
|
+
* is a cache directory, and a failure here costs disk, not correctness. */
|
|
56
|
+
export function pruneSidecars(cacheDir, prefix, keep = 2) {
|
|
57
|
+
try {
|
|
58
|
+
const mine = readdirSync(cacheDir)
|
|
59
|
+
.filter((f) => f.startsWith(`${prefix}.`) && f.endsWith(".json"))
|
|
60
|
+
.map((f) => {
|
|
61
|
+
const full = join(cacheDir, f);
|
|
62
|
+
return { full, mtimeMs: statSync(full).mtimeMs };
|
|
63
|
+
})
|
|
64
|
+
.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
65
|
+
for (const f of mine.slice(keep))
|
|
66
|
+
rmSync(f.full, { force: true });
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
/* nothing here is load-bearing */
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** Computed once per process — this can't change under a running process without
|
|
73
|
+
* the module graph itself being swapped, and a long-lived MCP server holding the
|
|
74
|
+
* identity of the code it actually loaded is the correct answer anyway.
|
|
75
|
+
* `undefined` = not computed yet; `null` = computed, and there is no identity. */
|
|
76
|
+
let memoizedStamp;
|
|
77
|
+
/**
|
|
78
|
+
* Identity of the code that produces the cached parses. Both sidecars key on it,
|
|
79
|
+
* so *anything* that can change extraction output has to change this string.
|
|
80
|
+
*
|
|
81
|
+
* Content-hashed over every sibling module in this directory, plus the package
|
|
82
|
+
* version. Two earlier instincts are deliberately rejected:
|
|
83
|
+
*
|
|
84
|
+
* - **Not a timestamp.** This was `mtime:size` of `extract.js` alone, which is
|
|
85
|
+
* wrong in both directions. Too loose: the parse of `db.count()` depends on
|
|
86
|
+
* `bindings.ts` deciding that `db` is a `UserRepo` (that answer is stored *in*
|
|
87
|
+
* the cached entry, as an edge's `recvType`), and fixing a binding bug leaves
|
|
88
|
+
* `extract.js`'s emitted bytes untouched — so any build that skips rewriting
|
|
89
|
+
* unchanged output keeps the old stamp and silently replays pre-fix edges. Too
|
|
90
|
+
* tight: a rebuild that rewrites identical content moves the mtime and throws
|
|
91
|
+
* away the whole memo for nothing.
|
|
92
|
+
* - **Not a hand-kept list of modules.** A list is correct exactly until someone
|
|
93
|
+
* moves parse logic into a module nobody added to it, and the failure is silent.
|
|
94
|
+
*
|
|
95
|
+
* Hashing the directory over-invalidates a little — editing any `graph/` module
|
|
96
|
+
* costs one cold rebuild — which is no more often than a version bump already
|
|
97
|
+
* costs, and always in the safe direction. The package version is folded in so a
|
|
98
|
+
* tree-sitter grammar upgrade (which changes parse output without changing any of
|
|
99
|
+
* graft's own files) invalidates too.
|
|
100
|
+
*
|
|
101
|
+
* Measured at ~0.5ms for 21 files / 556KB, paid once per process.
|
|
102
|
+
*
|
|
103
|
+
* **Null when no identity can be established at all**, and that is deliberately not
|
|
104
|
+
* a string. It used to return `"unknown"` on failure — but `"unknown"` was then
|
|
105
|
+
* *written into the sidecars as a real identity*, and every later run compared equal
|
|
106
|
+
* to it, so any environment where stamping fails (a `pkg`/`bun-compile` single-file
|
|
107
|
+
* build, an asar-style read, a directory that can't be listed) permanently lost the
|
|
108
|
+
* ability to notice an extractor change. A sentinel that doubles as a valid value
|
|
109
|
+
* silently disables the whole mechanism. Null forces callers to decide instead, and
|
|
110
|
+
* {@link extractCachePath} decides not to have a memo.
|
|
111
|
+
*/
|
|
112
|
+
export function extractorStamp() {
|
|
113
|
+
if (memoizedStamp === undefined)
|
|
114
|
+
memoizedStamp = computeStamp();
|
|
115
|
+
return memoizedStamp;
|
|
116
|
+
}
|
|
117
|
+
function computeStamp() {
|
|
118
|
+
try {
|
|
119
|
+
const self = fileURLToPath(import.meta.url);
|
|
120
|
+
// `.js` when running from `dist/`, `.ts` under tsx — take the extension from
|
|
121
|
+
// our own filename rather than guessing which layout we're in.
|
|
122
|
+
const dir = dirname(self);
|
|
123
|
+
const hashed = stampDir(dir, extname(self), packageVersion(dir) ?? "");
|
|
124
|
+
if (hashed)
|
|
125
|
+
return hashed;
|
|
126
|
+
// Couldn't read the modules (bundled into one file, say). The version alone is
|
|
127
|
+
// a weaker identity — it can't see a local edit — but it still turns over on
|
|
128
|
+
// every upgrade, which is the case that ships broken parses to users.
|
|
129
|
+
const v = packageVersion(dir);
|
|
130
|
+
return v ? `v${v}` : null;
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Hash every `ext` file in `dir`, plus `version`. Null when the directory holds no
|
|
138
|
+
* such file. Separated from {@link extractorStamp} so a test can prove the property
|
|
139
|
+
* that matters: a change to *any* module in the directory moves the stamp, not just
|
|
140
|
+
* the one the old implementation happened to watch.
|
|
141
|
+
*/
|
|
142
|
+
export function stampDir(dir, ext, version = "") {
|
|
143
|
+
const files = readdirSync(dir).filter((f) => f.endsWith(ext)).sort();
|
|
144
|
+
if (!files.length)
|
|
145
|
+
return null;
|
|
146
|
+
const h = createHash("sha256");
|
|
147
|
+
h.update(version);
|
|
148
|
+
for (const f of files) {
|
|
149
|
+
h.update(f); // a rename is a change, even at identical content
|
|
150
|
+
h.update(readFileSync(join(dir, f)));
|
|
151
|
+
}
|
|
152
|
+
return h.digest("hex").slice(0, 16);
|
|
153
|
+
}
|
|
154
|
+
/** graft's own version, or null when it can't be read. */
|
|
155
|
+
function packageVersion(graphDir) {
|
|
156
|
+
try {
|
|
157
|
+
const pkg = JSON.parse(readFileSync(join(graphDir, "..", "..", "package.json"), "utf8"));
|
|
158
|
+
return pkg.version ?? null;
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
export function emptyExtractCache() {
|
|
165
|
+
return { version: CACHE_VERSION, extractor: extractorStamp() ?? "", files: {} };
|
|
166
|
+
}
|
|
167
|
+
/** The cache for `outDir`, or an empty one when it's absent, unparseable, written by
|
|
168
|
+
* a different cache version, or when this graft has no identity to key on (then
|
|
169
|
+
* every build is cold, which is slow but never wrong). The stamp is in the filename,
|
|
170
|
+
* so the `extractor` field is a second check rather than the only one. */
|
|
171
|
+
export function readExtractCache(outDir) {
|
|
172
|
+
const path = extractCachePath(outDir);
|
|
173
|
+
const stamp = extractorStamp();
|
|
174
|
+
if (path === null || stamp === null)
|
|
175
|
+
return emptyExtractCache();
|
|
176
|
+
const c = readJson(path);
|
|
177
|
+
if (!c || c.version !== CACHE_VERSION || c.extractor !== stamp || typeof c.files !== "object") {
|
|
178
|
+
return emptyExtractCache();
|
|
179
|
+
}
|
|
180
|
+
return { version: c.version, extractor: c.extractor, files: c.files ?? {} };
|
|
181
|
+
}
|
|
182
|
+
/** Best-effort write — a full graph is already on disk by the time this runs, so an
|
|
183
|
+
* unwritable cache dir must never fail the build (it only costs the next build its
|
|
184
|
+
* reuse). Returns false when nothing was written, including the deliberate case of
|
|
185
|
+
* having no extractor identity: a parse we can't attribute must never be replayed. */
|
|
186
|
+
export function writeExtractCache(outDir, cache) {
|
|
187
|
+
const path = extractCachePath(outDir);
|
|
188
|
+
if (path === null)
|
|
189
|
+
return false;
|
|
190
|
+
try {
|
|
191
|
+
writeJsonAtomic(path, cache, true);
|
|
192
|
+
pruneSidecars(join(outDir, CACHE_DIR), EXTRACT_CACHE_PREFIX);
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=extract-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-cache.js","sourceRoot":"","sources":["../../src/graph/extract-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAI7D,iDAAiD;AACjD,MAAM,aAAa,GAAG,CAAC,CAAC;AACxB,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAAC;AA4B9C;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAC/B,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,oBAAoB,IAAI,KAAK,OAAO,CAAC,CAAC;AAClG,CAAC;AAED;;2EAE2E;AAC3E,MAAM,UAAU,aAAa,CAAC,QAAgB,EAAE,MAAc,EAAE,IAAI,GAAG,CAAC;IACtE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,CAAC;aAC/B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;aAChE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACT,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;YAC/B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QACnD,CAAC,CAAC;aACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;QACzC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,CAAC;IAAC,MAAM,CAAC;QACP,kCAAkC;IACpC,CAAC;AACH,CAAC;AAED;;;kFAGkF;AAClF,IAAI,aAAwC,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,UAAU,cAAc;IAC5B,IAAI,aAAa,KAAK,SAAS;QAAE,aAAa,GAAG,YAAY,EAAE,CAAC;IAChE,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,SAAS,YAAY;IACnB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5C,6EAA6E;QAC7E,+DAA+D;QAC/D,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QACvE,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAC1B,+EAA+E;QAC/E,6EAA6E;QAC7E,sEAAsE;QACtE,MAAM,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QAC9B,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAW,EAAE,GAAW,EAAE,OAAO,GAAG,EAAE;IAC7D,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACrE,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAC/B,MAAM,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,kDAAkD;QAC/D,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACtC,CAAC;AAED,0DAA0D;AAC1D,SAAS,cAAc,CAAC,QAAgB;IACtC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAyB,CAAC;QACjH,OAAO,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAClF,CAAC;AAED;;;0EAG0E;AAC1E,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,MAAM,IAAI,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAC/B,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,iBAAiB,EAAE,CAAC;IAChE,MAAM,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IACvC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,KAAK,aAAa,IAAI,CAAC,CAAC,SAAS,KAAK,KAAK,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9F,OAAO,iBAAiB,EAAE,CAAC;IAC7B,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;AAC9E,CAAC;AAED;;;sFAGsF;AACtF,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,KAAmB;IACnE,MAAM,IAAI,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAChC,IAAI,CAAC;QACH,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QACnC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,oBAAoB,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|