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,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lays out the `@trailhq/trail-code` package from this repo's build, in build/trail/.
|
|
3
|
+
*
|
|
4
|
+
* trail and graft are one program under two names, published as two packages
|
|
5
|
+
* from the same `dist/`:
|
|
6
|
+
*
|
|
7
|
+
* @trailhq/trail-code bin: trail → dist/bin/trail.js
|
|
8
|
+
* @nanonets/graft bin: graft → dist/bin/graft.js (this repo's package.json)
|
|
9
|
+
*
|
|
10
|
+
* Each package ships exactly one command, so installing both never clashes on
|
|
11
|
+
* a bin name, and `graft upgrade` installs both. @nanonets/graft stays a full
|
|
12
|
+
* package rather than a pointer: the hook shims committed in thousands of repos
|
|
13
|
+
* resolve `@nanonets/graft/dist/claude/*` by path, and 78% of active installs
|
|
14
|
+
* are on versions older than the one that knows about trail.
|
|
15
|
+
*
|
|
16
|
+
* Usage, after `npm run build` (and the telemetry key stamp, when publishing):
|
|
17
|
+
* node scripts/pack-trail.mjs
|
|
18
|
+
* npm publish build/trail --access public
|
|
19
|
+
*/
|
|
20
|
+
import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
21
|
+
import { dirname, join, resolve } from 'node:path';
|
|
22
|
+
import { fileURLToPath } from 'node:url';
|
|
23
|
+
|
|
24
|
+
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
25
|
+
const out = join(root, 'build', 'trail');
|
|
26
|
+
|
|
27
|
+
if (!existsSync(join(root, 'dist', 'bin', 'trail.js'))) {
|
|
28
|
+
console.error('✗ dist/bin/trail.js not found — run `npm run build` first');
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
|
|
33
|
+
const trail = {
|
|
34
|
+
...pkg,
|
|
35
|
+
name: '@trailhq/trail-code',
|
|
36
|
+
description:
|
|
37
|
+
"Your team's shared memory for coding agents: a code map on your machine, and the learnings, decisions and skills your whole team shares. Formerly graft.",
|
|
38
|
+
keywords: [...new Set(['trail', ...(pkg.keywords ?? [])])],
|
|
39
|
+
bin: { trail: 'dist/bin/trail.js' },
|
|
40
|
+
// Built already; nothing to compile in the published tree.
|
|
41
|
+
scripts: { postinstall: pkg.scripts.postinstall },
|
|
42
|
+
};
|
|
43
|
+
delete trail.devDependencies;
|
|
44
|
+
|
|
45
|
+
rmSync(out, { recursive: true, force: true });
|
|
46
|
+
mkdirSync(out, { recursive: true });
|
|
47
|
+
for (const f of pkg.files) {
|
|
48
|
+
const from = join(root, f);
|
|
49
|
+
if (existsSync(from)) cpSync(from, join(out, f), { recursive: true });
|
|
50
|
+
}
|
|
51
|
+
writeFileSync(join(out, 'package.json'), JSON.stringify(trail, null, 2) + '\n');
|
|
52
|
+
console.log(`✓ ${trail.name}@${trail.version} laid out in ${out}`);
|
|
53
|
+
console.log(' publish it with: npm publish build/trail --access public');
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Prints a one-line nudge after install, and records the anonymous `install`
|
|
2
|
+
// event. Never fails the install.
|
|
3
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
4
|
+
import { spawn } from 'node:child_process';
|
|
5
|
+
import { dirname, join } from 'node:path';
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
7
|
+
|
|
8
|
+
const root = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
9
|
+
|
|
10
|
+
// The same code ships as `trail-code` (the `trail` command, this fork) as
|
|
11
|
+
// `@trailhq/trail-code` (the same command, upstream) and as @nanonets/graft
|
|
12
|
+
// (`graft`, its old name). The install event and the nudge say which one this is.
|
|
13
|
+
let pkgName = '@nanonets/graft';
|
|
14
|
+
try {
|
|
15
|
+
pkgName = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8')).name ?? pkgName;
|
|
16
|
+
} catch { /* the graft defaults */ }
|
|
17
|
+
const isTrail = pkgName === 'trail-code' || pkgName === '@trailhq/trail-code';
|
|
18
|
+
if (isTrail) process.env.TRAIL_INVOKED_AS = 'trail';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Record the install, then hand the queue straight to a detached child.
|
|
22
|
+
*
|
|
23
|
+
* Sending here rather than letting the daily flush pick it up is the entire
|
|
24
|
+
* point of the event: the machine we most want to count is the one that installs
|
|
25
|
+
* graft and never runs a command, and that machine never reaches a flush. The
|
|
26
|
+
* child is detached with stdio ignored, so npm waits on no socket and an offline
|
|
27
|
+
* install looks like any other.
|
|
28
|
+
*
|
|
29
|
+
* Every gate still applies — a fork or a local build has no key, and CI,
|
|
30
|
+
* `DO_NOT_TRACK` and `graft telemetry disable` all close it. See TELEMETRY.md.
|
|
31
|
+
*/
|
|
32
|
+
async function recordInstall() {
|
|
33
|
+
// `dist/` is absent when this runs from a clone, where `prepare` builds AFTER
|
|
34
|
+
// postinstall. Nothing to record there, and a fork has no key regardless.
|
|
35
|
+
const entry = join(root, 'dist', 'telemetry', 'index.js');
|
|
36
|
+
const cli = join(root, 'dist', 'cli.js');
|
|
37
|
+
if (!existsSync(entry) || !existsSync(cli)) return;
|
|
38
|
+
const mod = await import(pathToFileURL(entry).href);
|
|
39
|
+
// A `dist/` from an older version has no such export. Absent, not broken.
|
|
40
|
+
if (typeof mod.trackInstallIfNew !== 'function') return;
|
|
41
|
+
// npm sets this for `npm i -g`; only its value 'true' means global.
|
|
42
|
+
mod.trackInstallIfNew({ global: process.env.npm_config_global === 'true' });
|
|
43
|
+
const child = spawn(process.execPath, [cli, '_telemetry-flush'], {
|
|
44
|
+
detached: true,
|
|
45
|
+
stdio: 'ignore',
|
|
46
|
+
});
|
|
47
|
+
child.unref();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
if (process.env.CI) process.exit(0);
|
|
52
|
+
const dir = process.env.INIT_CWD || process.cwd();
|
|
53
|
+
// Its own catch: the nudge is the part a user sees, and a telemetry fault must
|
|
54
|
+
// not be able to silence it.
|
|
55
|
+
try { await recordInstall(); } catch { /* telemetry is never worth an error */ }
|
|
56
|
+
if (existsSync(join(dir, '.claude', 'helpers', 'graft-statusline.cjs'))) process.exit(0);
|
|
57
|
+
if (existsSync(join(dir, '.claude', 'helpers', 'trail-statusline.cjs'))) process.exit(0);
|
|
58
|
+
console.log(
|
|
59
|
+
isTrail
|
|
60
|
+
? '\n Trail installed. Run `trail init` in a repo to wire it into your agents.\n'
|
|
61
|
+
: '\n Graft installed. Run `npx graft init` to enable the Claude Code integration (statusline + hooks + auto-sync).\n',
|
|
62
|
+
);
|
|
63
|
+
} catch {
|
|
64
|
+
/* never fail an install */
|
|
65
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runs the test suite without depending on shell glob expansion.
|
|
3
|
+
*
|
|
4
|
+
* `node --test test/*.test.ts` needs the *shell* to expand that glob, and on
|
|
5
|
+
* Windows nothing does: npm runs scripts through `cmd.exe` regardless of the
|
|
6
|
+
* shell that invoked npm, and Node's `--test` only accepts glob patterns itself
|
|
7
|
+
* from Node 21 (this package supports >=20). The literal pattern reaches Node as
|
|
8
|
+
* a filename and it exits with `Could not find '…\test\*.test.ts'` — so the
|
|
9
|
+
* Windows CI leg reported failure while actually running zero tests.
|
|
10
|
+
*
|
|
11
|
+
* Enumerating the files here instead means `npm test` behaves identically in
|
|
12
|
+
* cmd.exe, PowerShell, bash and CI, on any supported Node.
|
|
13
|
+
*/
|
|
14
|
+
import { mkdtempSync, readdirSync, rmSync } from "node:fs";
|
|
15
|
+
import { tmpdir } from "node:os";
|
|
16
|
+
import { spawnSync } from "node:child_process";
|
|
17
|
+
import { dirname, join, resolve } from "node:path";
|
|
18
|
+
import { fileURLToPath } from "node:url";
|
|
19
|
+
|
|
20
|
+
const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
21
|
+
const testDir = join(repoRoot, "test");
|
|
22
|
+
|
|
23
|
+
// Sorted so a failure is reported in the same order on every platform and run.
|
|
24
|
+
const files = readdirSync(testDir)
|
|
25
|
+
.filter((f) => f.endsWith(".test.ts"))
|
|
26
|
+
.sort()
|
|
27
|
+
.map((f) => join(testDir, f));
|
|
28
|
+
|
|
29
|
+
if (files.length === 0) {
|
|
30
|
+
console.error(`✗ no test files found in ${testDir}`);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Several tests `git init` a scratch repo and `git commit` into it to exercise the
|
|
35
|
+
// incremental/submodule/ingest git paths. Those commits inherit the developer's
|
|
36
|
+
// global git config — so a contributor who signs commits (gpg, or gitsign, whose
|
|
37
|
+
// x509 flow opens a browser for OIDC on EVERY commit) gets a signing storm from a
|
|
38
|
+
// run that has nothing to do with their identity. Inject config via GIT_CONFIG_*
|
|
39
|
+
// (git merges these over the user's config for this process tree only) so test
|
|
40
|
+
// commits never sign, without touching anyone's global settings.
|
|
41
|
+
const gitEnv = {
|
|
42
|
+
GIT_CONFIG_COUNT: "2",
|
|
43
|
+
GIT_CONFIG_KEY_0: "commit.gpgsign", GIT_CONFIG_VALUE_0: "false",
|
|
44
|
+
GIT_CONFIG_KEY_1: "tag.gpgsign", GIT_CONFIG_VALUE_1: "false",
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// Tests make thousands of scratch repos and homes under the temp folder and
|
|
48
|
+
// don't all remove them: a day of runs left over 50,000 folders (6 GB). Give the
|
|
49
|
+
// run its own temp folder and remove it at the end, whatever the outcome.
|
|
50
|
+
const runTmp = mkdtempSync(join(tmpdir(), "trail-test-run-"));
|
|
51
|
+
const tmpEnv = { TMPDIR: runTmp, TEMP: runTmp, TMP: runTmp };
|
|
52
|
+
|
|
53
|
+
// A graft repo moves to trail when a session opens on a machine with the trail
|
|
54
|
+
// command, so a contributor who has trail installed would see test repos move.
|
|
55
|
+
// Off for the run; the tests of the move turn it back on.
|
|
56
|
+
const result = spawnSync(process.execPath, ["--import", "tsx", "--test", ...files], {
|
|
57
|
+
cwd: repoRoot,
|
|
58
|
+
stdio: "inherit",
|
|
59
|
+
env: { ...process.env, ...gitEnv, ...tmpEnv, GRAFT_NO_TRAIL_SWITCH: "1" },
|
|
60
|
+
});
|
|
61
|
+
try {
|
|
62
|
+
rmSync(runTmp, { recursive: true, force: true });
|
|
63
|
+
} catch {
|
|
64
|
+
/* best effort: a locked file on Windows must not fail the run */
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (result.error) {
|
|
68
|
+
console.error(`✗ could not start the test runner: ${result.error.message}`);
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
// A signal-killed run reports null status; treat anything non-zero as failure.
|
|
72
|
+
process.exit(result.status ?? 1);
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bakes the PostHog key into the built `dist/telemetry/key.js` at publish time.
|
|
3
|
+
*
|
|
4
|
+
* This is what makes "forks never send" true by construction rather than by
|
|
5
|
+
* policy. The key exists only in the published tarball: the repository holds an
|
|
6
|
+
* empty string, so a clone, a fork, a CI build, and a contributor's local
|
|
7
|
+
* `npm run build` all produce a graft whose telemetry module short-circuits on
|
|
8
|
+
* the very first check.
|
|
9
|
+
*
|
|
10
|
+
* Runs from `prepare`, after `npm run build`. Without GRAFT_POSTHOG_KEY in the
|
|
11
|
+
* environment it changes nothing, and warns only when npm is packing or
|
|
12
|
+
* publishing — publishing a telemetry-less build is a valid thing to do, and it
|
|
13
|
+
* must never be a hard failure at the moment someone is trying to ship.
|
|
14
|
+
*/
|
|
15
|
+
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
|
|
16
|
+
import { dirname, join, resolve } from 'node:path';
|
|
17
|
+
import { fileURLToPath } from 'node:url';
|
|
18
|
+
|
|
19
|
+
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
20
|
+
const target = join(root, 'dist', 'telemetry', 'key.js');
|
|
21
|
+
|
|
22
|
+
const key = process.env.GRAFT_POSTHOG_KEY ?? '';
|
|
23
|
+
const host = process.env.GRAFT_POSTHOG_HOST ?? '';
|
|
24
|
+
|
|
25
|
+
if (!key) {
|
|
26
|
+
// `prepare` also runs on every `npm install` in a clone, where no key is expected.
|
|
27
|
+
if (['publish', 'pack'].includes(process.env.npm_command ?? '')) {
|
|
28
|
+
console.warn('⚠ GRAFT_POSTHOG_KEY not set — publishing a build that sends no telemetry.');
|
|
29
|
+
}
|
|
30
|
+
process.exit(0);
|
|
31
|
+
}
|
|
32
|
+
if (!existsSync(target)) {
|
|
33
|
+
console.warn(`⚠ ${target} not found — did the build run? Skipping the telemetry key stamp.`);
|
|
34
|
+
process.exit(0);
|
|
35
|
+
}
|
|
36
|
+
// A key with a quote or a newline in it would break the generated literal (and
|
|
37
|
+
// is not a PostHog key). Refuse rather than emit something that won't parse.
|
|
38
|
+
if (!/^[A-Za-z0-9_-]+$/.test(key)) {
|
|
39
|
+
console.error('✗ GRAFT_POSTHOG_KEY contains characters that are not valid in a project key.');
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
if (host && !/^https:\/\/[A-Za-z0-9.-]+(:\d+)?$/.test(host)) {
|
|
43
|
+
console.error('✗ GRAFT_POSTHOG_HOST must be a plain https origin, e.g. https://eu.i.posthog.com');
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const src = readFileSync(target, 'utf8');
|
|
48
|
+
let out = src.replace(/const BAKED_KEY = ['"][^'"]*['"];/, `const BAKED_KEY = '${key}';`);
|
|
49
|
+
if (host) out = out.replace(/const BAKED_HOST = ['"][^'"]*['"];/, `const BAKED_HOST = '${host}';`);
|
|
50
|
+
|
|
51
|
+
if (out === src) {
|
|
52
|
+
console.error('✗ could not find BAKED_KEY in dist/telemetry/key.js — the stamp target moved.');
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
writeFileSync(target, out);
|
|
56
|
+
console.log(`✓ telemetry key stamped into dist/telemetry/key.js${host ? ` (host ${host})` : ''}`);
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Saved vs said": how often does the agent actually TELL the user what graft saved?
|
|
3
|
+
*
|
|
4
|
+
* node scripts/tally-audit.mjs [transcript-dir] [--json]
|
|
5
|
+
*
|
|
6
|
+
* `savedTokens` (src/claude/state.ts) counts what graft *computed* — every
|
|
7
|
+
* `[graft] tokens saved ≈ N` footer the PostToolUse accumulator swept up. This
|
|
8
|
+
* script measures the other half, offline and in full detail: of the turns that
|
|
9
|
+
* used graft, how many closed with the one-line tally SKILL.md asks for, was the
|
|
10
|
+
* number right, and did it name the call count.
|
|
11
|
+
*
|
|
12
|
+
* The shipped metric (`graft_turns_bucket` / `reported_turns_bucket` on
|
|
13
|
+
* `session_summary`) is the same ratio at bucket resolution, which is all that
|
|
14
|
+
* can cross the wire. Run this locally when the aggregate says something
|
|
15
|
+
* surprising and you need to see which turns and why.
|
|
16
|
+
*
|
|
17
|
+
* Reads Claude Code's own transcript JSONL, which defaults to
|
|
18
|
+
* ~/.claude/projects/<slugified-cwd>/. Nothing leaves the machine.
|
|
19
|
+
*/
|
|
20
|
+
import { readFileSync, readdirSync, existsSync } from "node:fs";
|
|
21
|
+
import { join } from "node:path";
|
|
22
|
+
import { homedir } from "node:os";
|
|
23
|
+
|
|
24
|
+
const SAVED_FOOTER = /\[graft\] tokens saved ≈ ([\d,]+)/g;
|
|
25
|
+
const TALLY = /graft\s+saved\s*[~≈]?\s*([\d,.]+)\s*(k|m)?\s*(?:tok|tokens)/i;
|
|
26
|
+
const CALLS = /(\d+)\s*calls?/i;
|
|
27
|
+
/** How far past the tally to look for its call count. The tally is one line
|
|
28
|
+
* ("🌱 graft saved ~12,400 tokens this turn (3 calls)"); scanning the rest of
|
|
29
|
+
* the reply instead would match any unrelated "3 calls" further down and report
|
|
30
|
+
* near-perfect compliance for a field the agent mostly omits. */
|
|
31
|
+
const TALLY_WINDOW = 60;
|
|
32
|
+
/** Above this, a per-turn "saved" figure is an estimator artifact rather than a
|
|
33
|
+
* saving — a `--depth all` closure or a vendored tree summing whole-file
|
|
34
|
+
* baselines nobody would have read. Reported separately, never averaged in. */
|
|
35
|
+
const IMPLAUSIBLE_TOKENS = 1_000_000;
|
|
36
|
+
|
|
37
|
+
const args = process.argv.slice(2).filter((a) => a !== "--json");
|
|
38
|
+
const asJson = process.argv.includes("--json");
|
|
39
|
+
const dir = args[0] ?? defaultTranscriptDir();
|
|
40
|
+
|
|
41
|
+
function defaultTranscriptDir() {
|
|
42
|
+
const slug = process.cwd().replace(/[/.]/g, "-");
|
|
43
|
+
return join(homedir(), ".claude", "projects", slug);
|
|
44
|
+
}
|
|
45
|
+
function textOf(content) {
|
|
46
|
+
if (typeof content === "string") return content;
|
|
47
|
+
if (!Array.isArray(content)) return "";
|
|
48
|
+
return content.map((p) => (p?.type === "text" ? p.text ?? "" : "")).join("\n");
|
|
49
|
+
}
|
|
50
|
+
function isUserPrompt(o) {
|
|
51
|
+
if (o.type !== "user" || o.isSidechain || o.isMeta) return false;
|
|
52
|
+
const c = o.message?.content;
|
|
53
|
+
if (typeof c === "string") return true;
|
|
54
|
+
return Array.isArray(c) && !c.some((p) => p?.type === "tool_result");
|
|
55
|
+
}
|
|
56
|
+
function median(ns) {
|
|
57
|
+
if (!ns.length) return 0;
|
|
58
|
+
const s = [...ns].sort((a, b) => a - b);
|
|
59
|
+
const mid = s.length >> 1;
|
|
60
|
+
return s.length % 2 ? s[mid] : Math.round((s[mid - 1] + s[mid]) / 2);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (!existsSync(dir)) {
|
|
64
|
+
console.error(`no transcripts at ${dir}`);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const turns = [];
|
|
69
|
+
for (const file of readdirSync(dir).filter((f) => f.endsWith(".jsonl"))) {
|
|
70
|
+
let turn = null;
|
|
71
|
+
const flush = () => { if (turn?.calls > 0) turns.push(turn); };
|
|
72
|
+
for (const line of readFileSync(join(dir, file), "utf8").split("\n")) {
|
|
73
|
+
if (!line.trim()) continue;
|
|
74
|
+
let o;
|
|
75
|
+
try { o = JSON.parse(line); } catch { continue; }
|
|
76
|
+
if (o.isSidechain) continue; // a subagent's prose is not what the user read
|
|
77
|
+
if (isUserPrompt(o)) { flush(); turn = { file, calls: 0, saved: 0, said: null, statedCalls: null }; continue; }
|
|
78
|
+
if (!turn) continue;
|
|
79
|
+
if (o.type === "user") { // a tool_result wearing the user role
|
|
80
|
+
for (const m of JSON.stringify(o.message?.content ?? "").matchAll(SAVED_FOOTER)) {
|
|
81
|
+
turn.calls++;
|
|
82
|
+
turn.saved += Number(m[1].replace(/,/g, "")) || 0;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (o.type === "assistant") {
|
|
86
|
+
const m = TALLY.exec(textOf(o.message?.content));
|
|
87
|
+
if (m) {
|
|
88
|
+
let n = Number(m[1].replace(/,/g, ""));
|
|
89
|
+
if (m[2]?.toLowerCase() === "k") n *= 1e3;
|
|
90
|
+
if (m[2]?.toLowerCase() === "m") n *= 1e6;
|
|
91
|
+
turn.said = n;
|
|
92
|
+
const c = CALLS.exec(textOf(o.message?.content).slice(m.index, m.index + TALLY_WINDOW));
|
|
93
|
+
turn.statedCalls = c ? Number(c[1]) : null;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
flush();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const said = turns.filter((t) => t.said !== null);
|
|
101
|
+
const plausible = turns.filter((t) => t.saved < IMPLAUSIBLE_TOKENS);
|
|
102
|
+
const outliers = turns.filter((t) => t.saved >= IMPLAUSIBLE_TOKENS);
|
|
103
|
+
const fidelity = { exact: 0, over: 0, under: 0 };
|
|
104
|
+
for (const t of said.filter((t) => t.saved > 0)) {
|
|
105
|
+
const r = t.said / t.saved;
|
|
106
|
+
if (r >= 0.9 && r <= 1.1) fidelity.exact++;
|
|
107
|
+
else if (r > 1.1) fidelity.over++;
|
|
108
|
+
else fidelity.under++;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const report = {
|
|
112
|
+
transcripts: readdirSync(dir).filter((f) => f.endsWith(".jsonl")).length,
|
|
113
|
+
graft_turns: turns.length,
|
|
114
|
+
reported: said.length,
|
|
115
|
+
silent: turns.length - said.length,
|
|
116
|
+
reported_pct: turns.length ? Number(((said.length / turns.length) * 100).toFixed(1)) : 0,
|
|
117
|
+
stated_call_count: said.filter((t) => t.statedCalls !== null).length,
|
|
118
|
+
median_saved_per_turn: median(plausible.map((t) => t.saved)),
|
|
119
|
+
fidelity,
|
|
120
|
+
implausible_turns: outliers.length,
|
|
121
|
+
implausible_max: outliers.length ? Math.max(...outliers.map((t) => t.saved)) : 0,
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
if (asJson) {
|
|
125
|
+
console.log(JSON.stringify(report, null, 2));
|
|
126
|
+
} else {
|
|
127
|
+
const { graft_turns: n } = report;
|
|
128
|
+
console.log(`transcripts scanned: ${report.transcripts} (${dir})`);
|
|
129
|
+
console.log(`turns that used graft: ${n}`);
|
|
130
|
+
console.log(` ...reported a tally: ${report.reported} (${report.reported_pct}%)`);
|
|
131
|
+
console.log(` ...silent: ${report.silent}`);
|
|
132
|
+
console.log(` ...named the call count ${report.stated_call_count}/${report.reported}`);
|
|
133
|
+
console.log(`median saved per turn: ${report.median_saved_per_turn.toLocaleString()} tok`);
|
|
134
|
+
console.log(`reported number vs footer sum (±10%): exact ${fidelity.exact} · over ${fidelity.over} · under ${fidelity.under}`);
|
|
135
|
+
if (outliers.length) {
|
|
136
|
+
console.log(`\n⚠ ${outliers.length} turn(s) claim ≥${IMPLAUSIBLE_TOKENS.toLocaleString()} tokens saved ` +
|
|
137
|
+
`(max ${report.implausible_max.toLocaleString()}) — an estimator artifact, excluded from the median. ` +
|
|
138
|
+
`See savingsFor() in src/context/savings.ts.`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copies the depth tier's WASM grammars into dist/vendor/grammars/. Runs as part
|
|
3
|
+
* of `npm run build`; src/graph/depth-parser.ts loads them from there.
|
|
4
|
+
*
|
|
5
|
+
* The grammar packages are dev dependencies only. As dependencies they were native
|
|
6
|
+
* addons, and installing the package compiled C wherever one had no prebuilt
|
|
7
|
+
* binary (tree-sitter-kotlin has none at all). What the depth tier needs from each
|
|
8
|
+
* is one .wasm: the package's own where it ships one, else the one
|
|
9
|
+
* scripts/build-grammar-wasm.mjs compiled from its source into src/graph/grammars/.
|
|
10
|
+
* Each grammar's license comes along.
|
|
11
|
+
*
|
|
12
|
+
* Usage: node scripts/vendor-grammars.mjs [outDir] (default dist/vendor)
|
|
13
|
+
*/
|
|
14
|
+
import { copyFileSync, existsSync, mkdirSync, rmSync } from "node:fs";
|
|
15
|
+
import { createRequire } from "node:module";
|
|
16
|
+
import { dirname, join, resolve } from "node:path";
|
|
17
|
+
import { fileURLToPath } from "node:url";
|
|
18
|
+
|
|
19
|
+
const root = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
20
|
+
const vendorDir = resolve(process.argv[2] ?? join(root, "dist", "vendor"));
|
|
21
|
+
const outDir = join(vendorDir, "grammars");
|
|
22
|
+
const require = createRequire(join(root, "package.json"));
|
|
23
|
+
|
|
24
|
+
/** Mirrors DEPTH_WASM in src/graph/depth-parser.ts, which a test holds this to. */
|
|
25
|
+
export const GRAMMARS = [
|
|
26
|
+
{ module: "tree-sitter-typescript", files: ["tree-sitter-typescript.wasm", "tree-sitter-tsx.wasm"] },
|
|
27
|
+
{ module: "tree-sitter-python", files: ["tree-sitter-python.wasm"], built: true },
|
|
28
|
+
{ module: "tree-sitter-go", files: ["tree-sitter-go.wasm"] },
|
|
29
|
+
{ module: "tree-sitter-r", files: ["tree-sitter-r.wasm"] },
|
|
30
|
+
{ module: "tree-sitter-java", files: ["tree-sitter-java.wasm"] },
|
|
31
|
+
{ module: "tree-sitter-kotlin", files: ["tree-sitter-kotlin.wasm"], built: true },
|
|
32
|
+
{ module: "tree-sitter-swift", files: ["tree-sitter-swift.wasm"], built: true },
|
|
33
|
+
{ module: "tree-sitter-php", files: ["tree-sitter-php.wasm"] },
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
37
|
+
rmSync(outDir, { recursive: true, force: true });
|
|
38
|
+
// Where earlier builds put the native tree-sitter-swift binaries: a dist/ built
|
|
39
|
+
// before would otherwise keep them, and pack them.
|
|
40
|
+
rmSync(join(vendorDir, "tree-sitter-swift"), { recursive: true, force: true });
|
|
41
|
+
mkdirSync(outDir, { recursive: true });
|
|
42
|
+
for (const { module, files, built } of GRAMMARS) {
|
|
43
|
+
const pkg = dirname(require.resolve(`${module}/package.json`));
|
|
44
|
+
const { version } = require(`${module}/package.json`);
|
|
45
|
+
for (const file of files) {
|
|
46
|
+
const from = built ? join(root, "src", "graph", "grammars", file) : join(pkg, file);
|
|
47
|
+
if (!existsSync(from)) throw new Error(`${module}@${version}: ${from} is missing`);
|
|
48
|
+
copyFileSync(from, join(outDir, file));
|
|
49
|
+
}
|
|
50
|
+
copyFileSync(join(pkg, "LICENSE"), join(outDir, `${module}.LICENSE`));
|
|
51
|
+
}
|
|
52
|
+
console.log(`vendored grammars → ${outDir} (${GRAMMARS.flatMap((g) => g.files).length} wasm)`);
|
|
53
|
+
}
|