Skip to content

Commit 726c18e

Browse files
jahoomaclaude
andcommitted
Move sibling-wasm lookup from pre-init to init-node's locateFile callback
Round 8 (argv[0] in pre-init) failed on Windows for the same reason round 7 (execPath in pre-init) did: [pre-init diag] argv[0]=bun # not a path! [pre-init diag] execPath=B:\~BUN\root\<binary>.exe # bunfs Pre-init runs at module evaluation time. Inside a bun --compile binary on Windows during that phase, both `process.argv[0]` and `process.execPath` lie: - argv[0] is `"bun"` (the runtime name), not a real path - execPath is the *bunfs internal* path (`B:\~BUN\root\...`), not the disk path of the .exe Both stabilize to real paths by the time main() runs (round 7's main() diag confirmed that), but the SDK's eager Parser.init has already fired by then with bad path data. The fix: do the sibling-file lookup *inside the locateFile callback* in code-map's init-node.ts. emscripten calls that callback during Parser.init's async work, after process.execPath has stabilized to the disk path. By then, `dirname(process.execPath) + 'tree-sitter.wasm'` resolves correctly. - packages/code-map/src/init-node.ts: add a sibling-of-execPath check between the existing scriptDir fallback and the require.resolve fallback. Improves the thrown-error message to include the attempted execPath dir so future failures are easier to diagnose. - cli/src/pre-init/tree-sitter-wasm.ts: keep the eager lookup as a best-effort fast path (it works on macOS/Linux where execPath is the disk path from module-load); on Windows it silently no-ops and the locateFile callback handles things lazily. Diagnostic dump remains gated on --smoke-tree-sitter so we can see what each phase thinks the paths are. The SDK dist also needs rebuilding so the bundled init-node.ts copy picks up this change — included in the diff. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 1ceaa13 commit 726c18e

2 files changed

Lines changed: 32 additions & 1 deletion

File tree

cli/src/pre-init/tree-sitter-wasm.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,20 @@ const candidates = (
4242

4343
const siblingPath = candidates.find((p) => existsSync(p))
4444

45+
// Pre-init diagnostic — only fires when --smoke-tree-sitter is set so we
46+
// don't spam every run. We need to see what argv[0] / execPath looked
47+
// like at this exact phase on Windows: the round-7 main() diag showed
48+
// disk paths, but pre-init silently bailed, meaning module-init time
49+
// gives different values. argv[0] alone wasn't enough to fix it.
50+
if (process.argv.includes('--smoke-tree-sitter')) {
51+
console.error(
52+
`[pre-init diag] argv[0]=${process.argv[0]}\n` +
53+
`[pre-init diag] execPath=${process.execPath}\n` +
54+
`[pre-init diag] candidates=${JSON.stringify(candidates)}\n` +
55+
`[pre-init diag] resolved siblingPath=${siblingPath ?? '<none>'}\n`,
56+
)
57+
}
58+
4559
if (siblingPath) {
4660
// Tell init-node.ts (in code-map / the SDK bundle) where the wasm
4761
// is. The locateFile callback there will hand this path to

packages/code-map/src/init-node.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,23 @@ function resolveTreeSitterWasm(scriptDir: string): string {
4747
return fallback
4848
}
4949

50+
// Sibling file next to the running binary. The CLI ships
51+
// tree-sitter.wasm alongside `freebuff.exe` / `codebuff.exe` because
52+
// bun --compile asset embedding was unreliable on Windows. We do this
53+
// lookup *here* (not in pre-init) on purpose: inside a bun --compile
54+
// binary on Windows, `process.execPath` returns the bunfs internal
55+
// path during early module evaluation and only switches to the disk
56+
// path later. emscripten calls this locateFile callback during
57+
// Parser.init's async work, by which time execPath has stabilized.
58+
try {
59+
const sibling = path.join(path.dirname(process.execPath), 'tree-sitter.wasm')
60+
if (fs.existsSync(sibling)) {
61+
return sibling
62+
}
63+
} catch {
64+
// process.execPath may be unavailable in exotic runtimes; fall through.
65+
}
66+
5067
try {
5168
const pkgDir = path.dirname(require.resolve('web-tree-sitter'))
5269
const wasm = path.join(pkgDir, 'tree-sitter.wasm')
@@ -61,7 +78,7 @@ function resolveTreeSitterWasm(scriptDir: string): string {
6178
? ` (env ${TREE_SITTER_WASM_ENV_VAR}=${override} did not exist)`
6279
: ''
6380
throw new Error(
64-
`Internal error: tree-sitter.wasm not found (looked at scriptDir=${scriptDir} and via web-tree-sitter package${overrideDiagnostic}). Set ${TREE_SITTER_WASM_ENV_VAR} or ensure the file is included in your deployment bundle.`,
81+
`Internal error: tree-sitter.wasm not found (looked at scriptDir=${scriptDir}, dirname(process.execPath)=${path.dirname(process.execPath)}, and via web-tree-sitter package${overrideDiagnostic}). Set ${TREE_SITTER_WASM_ENV_VAR} or ensure the file is included in your deployment bundle.`,
6582
)
6683
}
6784

0 commit comments

Comments
 (0)