fix(cli): fall back to esbuild-wasm on native host/binary mismatch (#9629)

* fix(cli): fall back to esbuild-wasm on native host/binary mismatch

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(cli): guard tarball extraction, extend esbuild-wasm fallback to script bundling

Address CI review: prevent tar-slip in esbuild-wasm package extraction, route codebase/script and inline-rawscript bundling through getEsbuild() too, and move the loader to utils. Add a unit test for the tar-slip guard.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(cli): make esbuild-wasm fallback concurrency-safe

Address CI review (P1): memoize getEsbuild() on an in-flight promise so concurrent first callers (parallel wmill sync push) share one probe/download instead of racing, and give each extraction a unique temp dir so concurrent extractions can't clobber each other.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ruben Fiszel
2026-06-17 02:33:18 +02:00
committed by GitHub
parent 8a3f69dda8
commit 86d1d160f0
7 changed files with 289 additions and 20 deletions
+3 -2
View File
@@ -58,6 +58,7 @@ import { SyncCodebase, listSyncCodebases } from "../../utils/codebase.ts";
import { pollJobWithQueueLogging } from "../../utils/job_polling.ts";
import fs from "node:fs";
import { createTarBlob, type TarEntry } from "../../utils/tar.ts";
import { getEsbuild } from "../../utils/esbuild_loader.ts";
import { execSync } from "node:child_process";
import { NewScript, Script, ScriptModule } from "../../../gen/types.gen.ts";
@@ -328,7 +329,7 @@ export async function handleFile(
}).toString();
log.info("Custom bundler executed for " + path);
} else {
const esbuild = await import("esbuild");
const esbuild = await getEsbuild();
log.info(`Started bundling ${path} ...`);
const startTime = performance.now();
@@ -1565,7 +1566,7 @@ async function preview(
maxBuffer: 1024 * 1024 * 50,
}).toString();
} else {
const esbuild = await import("esbuild");
const esbuild = await getEsbuild();
if (!opts.silent) {
log.info(`Bundling ${filePath} for preview...`);