Problem
scripts/build_sandbox.ts tries to clear the previous tarball before each npm pack with a wildcard path:
rmSync(join(corePackageDir, 'dist', 'vybestack-llxprt-code-core-*.tgz'), {
force: true,
});
node:fs's rmSync does not expand globs. It treats vybestack-llxprt-code-core-*.tgz as a literal filename, finds nothing, and force: true swallows the ENOENT. The cleanup is a silent no-op.
Reproduction:
const { existsSync, mkdtempSync, writeFileSync, rmSync } = require('node:fs');
const { join } = require('node:path');
const os = require('node:os');
const dir = mkdtempSync(join(os.tmpdir(), 'rm-glob-'));
const archive = join(dir, 'vybestack-llxprt-code-core-1.0.0.tgz');
writeFileSync(archive, '');
rmSync(join(dir, 'vybestack-llxprt-code-core-*.tgz'), { force: true });
console.log('still there:', existsSync(archive)); // true
Impact
npm pack writes a version-stamped filename, so within one version the pack simply overwrites and nothing is visibly wrong. Across a version bump the old tarball stays in packages/<pkg>/dist/, and the Dockerfile copies by glob:
COPY --chown=node:node packages/core/dist/vybestack-llxprt-code-core-*.tgz /tmp/
so both versions land in /tmp and both are handed to the single npm install -g transaction. Which one wins is left to npm's resolution rather than being determined by the build. A git clean or a fresh clone hides the problem, which is probably why it has not been noticed.
Scope
Twelve call sites in scripts/build_sandbox.ts, one per packed workspace. The fix is to enumerate packages/<pkg>/dist, filter for entries matching the package's tarball prefix, and rmSync each concrete path — ideally through one shared helper rather than twelve repetitions of the same block.
A regression test belongs with it: create a dist directory holding a stale <pkg>-0.0.1.tgz, run the cleanup, and assert the file is gone. That test fails against the current code.
Origin
Found by CodeRabbit on #3332, which added the twelfth call site (packages/zed-acp) by matching the existing eleven. Deferred there because fixing one site among twelve would be inconsistent and fixing all twelve was outside that issue's scope.
Problem
scripts/build_sandbox.tstries to clear the previous tarball before eachnpm packwith a wildcard path:node:fs'srmSyncdoes not expand globs. It treatsvybestack-llxprt-code-core-*.tgzas a literal filename, finds nothing, andforce: trueswallows the ENOENT. The cleanup is a silent no-op.Reproduction:
Impact
npm packwrites a version-stamped filename, so within one version the pack simply overwrites and nothing is visibly wrong. Across a version bump the old tarball stays inpackages/<pkg>/dist/, and the Dockerfile copies by glob:so both versions land in
/tmpand both are handed to the singlenpm install -gtransaction. Which one wins is left to npm's resolution rather than being determined by the build. Agit cleanor a fresh clone hides the problem, which is probably why it has not been noticed.Scope
Twelve call sites in
scripts/build_sandbox.ts, one per packed workspace. The fix is to enumeratepackages/<pkg>/dist, filter for entries matching the package's tarball prefix, andrmSynceach concrete path — ideally through one shared helper rather than twelve repetitions of the same block.A regression test belongs with it: create a dist directory holding a stale
<pkg>-0.0.1.tgz, run the cleanup, and assert the file is gone. That test fails against the current code.Origin
Found by CodeRabbit on #3332, which added the twelfth call site (
packages/zed-acp) by matching the existing eleven. Deferred there because fixing one site among twelve would be inconsistent and fixing all twelve was outside that issue's scope.