fix(scripts): resolve token-benchmark.ts --perf imports to real nested module paths#2041
Conversation
…d module paths runPerfBenchmarks and its callers (buildCodegraph, buildSessionOptions) dynamically imported/spawned codegraph's own modules via flat paths (src/builder.js, src/queries.js, src/native.js, src/parser.js, src/cli.js) that never existed — src/ has no compiled .js siblings, and the real modules live nested (domain/graph/builder.ts, domain/queries.ts, infrastructure/native.ts, domain/parser.ts), mirroring dist/'s layout. Fix the four --perf imports by reusing srcImport() from scripts/lib/bench-config.ts — the same .ts-preferring resolution the other benchmark scripts (benchmark.ts, query-benchmark.ts, incremental-benchmark.ts, resolution-benchmark.ts) already rely on for this exact problem. The CLI-spawning cliPath had the same defect plus a second one: even with a correct path, a spawned child `node` process doesn't inherit the parent's --experimental-strip-types/--import <loader> flags needed to run TypeScript source directly. Extract the fix into a new scripts/lib/cli-invocation.ts (mirroring tests/integration/cli.test.ts's NODE_TS_FLAGS pattern) so both call sites share one correct implementation and it can be unit-tested directly. Impact: 4 functions changed, 5 affected
Greptile SummaryThis PR fixes
Confidence Score: 5/5This PR fixes previously non-functional code paths; the changes are narrow, well-tested, and mirror patterns already proven in the integration test suite. All five broken references (four dynamic imports and one CLI exec path) are replaced with correct equivalents that reuse well-established helpers already present in the codebase. The loader URL derivation in cli-invocation.ts is computed from import.meta.url of the file itself, making it path-stable regardless of how the script is invoked. The two new unit tests exercise both the file-existence invariant and an end-to-end CLI spawn, covering exactly the class of bug being fixed. No pre-existing passing tests were modified. No files require special attention; all four changed files are straightforward. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
TB["token-benchmark.ts"]
TB -->|"buildCodegraph / buildSessionOptions"| CLI_ARGS["resolveCliNodeArgs(root)\nscripts/lib/cli-invocation.ts"]
CLI_ARGS --> SPAWN["execFileSync('node',\n[--experimental-strip-types,\n--import loaderUrl,\nsrc/cli.ts, ...])\n✅ was: src/cli.js (never existed)"]
TB -->|"runPerfBenchmarks"| PERF["srcImport(SRC_DIR, subpath)\nscripts/lib/bench-config.ts"]
PERF --> CHECK{".ts exists?"}
CHECK -->|Yes| TS_URL["file://…/src/domain/graph/builder.ts\nfile://…/src/domain/queries.ts\nfile://…/src/infrastructure/native.ts\nfile://…/src/domain/parser.ts\n✅ was: src/builder.js etc."]
CHECK -->|No| JS_URL["file://…/file.js (dist mode)"]
CLI_ARGS -.->|"loader URL relative to\ncli-invocation.ts"| LOADER["scripts/ts-resolve-loader.ts\n(registers .ts ESM hook)"]
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
TB["token-benchmark.ts"]
TB -->|"buildCodegraph / buildSessionOptions"| CLI_ARGS["resolveCliNodeArgs(root)\nscripts/lib/cli-invocation.ts"]
CLI_ARGS --> SPAWN["execFileSync('node',\n[--experimental-strip-types,\n--import loaderUrl,\nsrc/cli.ts, ...])\n✅ was: src/cli.js (never existed)"]
TB -->|"runPerfBenchmarks"| PERF["srcImport(SRC_DIR, subpath)\nscripts/lib/bench-config.ts"]
PERF --> CHECK{".ts exists?"}
CHECK -->|Yes| TS_URL["file://…/src/domain/graph/builder.ts\nfile://…/src/domain/queries.ts\nfile://…/src/infrastructure/native.ts\nfile://…/src/domain/parser.ts\n✅ was: src/builder.js etc."]
CHECK -->|No| JS_URL["file://…/file.js (dist mode)"]
CLI_ARGS -.->|"loader URL relative to\ncli-invocation.ts"| LOADER["scripts/ts-resolve-loader.ts\n(registers .ts ESM hook)"]
Reviews (1): Last reviewed commit: "fix(scripts): resolve token-benchmark.ts..." | Re-trigger Greptile |
Codegraph Impact Analysis4 functions changed → 5 callers affected across 1 files
|
Summary
runPerfBenchmarks(and its callersbuildCodegraph/buildSessionOptions) inscripts/token-benchmark.tsdynamically imported/spawned codegraph's own modules via flat paths that never existed:src/has no compiled.jssiblings — only.tssources — and none of these live flatly atsrc/root exceptcli.ts. Confirmed via direct execution that all five paths throwCannot find module/ERR_MODULE_NOT_FOUNDtoday, so--perf(and, sincebuildCodegraph/buildSessionOptionsare also used by the main non---perfflow, the base benchmark run too) has never actually worked against this repo's own source.Fix
--perfimports now go throughsrcImport()fromscripts/lib/bench-config.tswith the correct nested subpaths — the same.ts-preferring resolutionbenchmark.ts,query-benchmark.ts,incremental-benchmark.ts, andresolution-benchmark.tsalready use for this exact problem.cliPathhad the same defect plus a second one: even with a correct path, a spawned childnodeprocess doesn't inherit the parent's--experimental-strip-types/--import <loader>flags needed to run TypeScript source directly (only the parent script itself gets those flags from its own invocation). Extracted the fix into a newscripts/lib/cli-invocation.ts::resolveCliNodeArgs(), mirroring the exact patterntests/integration/cli.test.tsalready uses (NODE_TS_FLAGS), so both call sites (buildCodegraph,buildSessionOptions) share one correct, testable implementation instead of two duplicated broken ones.Test plan
tests/unit/cli-invocation.test.ts— verifiesresolveCliNodeArgs()resolves to a real, existingcli.ts+ loader, and that spawning the CLI with the resolved argv actually runs (--versionsucceeds). Verified this test fails against the pre-fix code (Cannot find module .../src/cli.js).tests/unit/bench-config-src-import.test.ts— verifiessrcImport()resolves the exact nested subpathsrunPerfBenchmarksneeds (domain/graph/builder.js,domain/queries.js,infrastructure/native.js,domain/parser.js) to modules exporting the expected symbols.buildCodegraphcode path end-to-end against a throwaway fixture directory — confirmed it spawns the CLI, builds a real.codegraph/graph.db, and exits cleanly.npx vitest run tests/unit/cli-invocation.test.ts tests/unit/bench-config-src-import.test.ts— both new files pass.npm run lint— clean (scripts/is outside Biome's scope perbiome.json; newtests/files pass lint).codegraph diff-impact --staged -T— 4 functions changed, 5 transitive callers affected, all withinscripts/token-benchmark.tsand the newscripts/lib/cli-invocation.tsas expected.npm test(full suite) — no new failures introduced by this change. The suite in this fresh worktree does show ~102 pre-existing failures unrelated to this fix (stale prebuilt native addon vs. unreleased Rust changes already on this branch — e.g.native.leidenCommunities, busy-timeout threading, cross-language call rejection), matching already-open issues Same -f/--file array-vs-String native crash affects triage, interfaces, implementations, and other NativeRepository methods #1815 and Thread config.db.busyTimeoutMs into the Rust native DB layer (NativeDatabase::open_readonly/open_read_write) #1882; confirmed by git history that none of the affected test files were touched by this diff.Fixes #1907