fix(setup): keep a contributor checkout's dev packages on bun.lock's versions (GSTA-97)

/ship Step 11: a production install over a full install reports "no
changes" and leaves devDependencies at old versions after bun.lock moves,
so the session updater's ./setup left contributors on stale TypeScript,
Prettier and Agent SDK. A checkout with node_modules/typescript gets the
full frozen install. The import-closure scan now follows shipped code into
test/helpers (gstack-model-benchmark loads the providers).

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-10-26 01:22:34 +00:00
1 parent b5b8820df8
commit 9773f6844f
4 files changed
+33 -8

No files matched your search

+22 -4
View File
@@ -54,12 +54,12 @@ describe.skipIf(process.platform === 'win32')('setup installs production depende
test('install_runtime_deps passes --production with the frozen lockfile, and refreshes a stale lockfile before installing production-only again', () => {
const base = tempBase();
const { bun, calls } = stubBun(base);
expect(runBashScript(script(bun, 'install_runtime_deps'), { env: { ...process.env, FROZEN_RC: '0' } }).status).toBe(0);
expect(runBashScript(script(bun, 'install_runtime_deps'), { cwd: base, env: { ...process.env, FROZEN_RC: '0' } }).status).toBe(0);
expect(calls()).toEqual(['install --production --frozen-lockfile']);
const base2 = tempBase();
const stub2 = stubBun(base2);
expect(runBashScript(script(stub2.bun, 'install_runtime_deps'), { env: { ...process.env, FROZEN_RC: '1' } }).status).toBe(0);
expect(runBashScript(script(stub2.bun, 'install_runtime_deps'), { cwd: base2, env: { ...process.env, FROZEN_RC: '1' } }).status).toBe(0);
expect(stub2.calls()).toEqual(['install --production --frozen-lockfile', 'install --lockfile-only', 'install --production --frozen-lockfile']);
// Generated by /ship Step 7 coverage audit (GSTA-97).
@@ -68,12 +68,29 @@ describe.skipIf(process.platform === 'win32')('setup installs production depende
// why_new=both rows above end in a successful install; seam=none; no_claim=setup's own subshell wiring around the call
const base3 = tempBase();
const stub3 = stubBun(base3);
const failed = runBashScript(script(stub3.bun, 'install_runtime_deps\necho AFTER'), { env: { ...process.env, FROZEN_RC: '1', FALLBACK_RC: '3' } });
const failed = runBashScript(script(stub3.bun, 'install_runtime_deps\necho AFTER'), { cwd: base3, env: { ...process.env, FROZEN_RC: '1', FALLBACK_RC: '3' } });
expect(failed.status).toBe(3);
expect(failed.stdout).not.toContain('AFTER');
expect(stub3.calls()).toEqual(['install --production --frozen-lockfile', 'install --lockfile-only']);
});
// Value: protects=a contributor checkout (dev toolchain present) keeps its dev packages at bun.lock's versions after ./setup;
// fails_when=setup runs the production install there, which Bun reports as "no changes" and leaves old dev versions;
// why_new=every other row starts without node_modules; seam=none; no_claim=Bun's own update behavior (stub bun)
test('a checkout with the dev toolchain gets the full frozen install, falling back to a plain install', () => {
const base = tempBase();
fs.mkdirSync(path.join(base, 'node_modules', 'typescript'), { recursive: true });
const { bun, calls } = stubBun(base);
expect(runBashScript(script(bun, 'install_runtime_deps'), { cwd: base, env: { ...process.env, FROZEN_RC: '0' } }).status).toBe(0);
expect(calls()).toEqual(['install --frozen-lockfile']);
const base2 = tempBase();
fs.mkdirSync(path.join(base2, 'node_modules', 'typescript'), { recursive: true });
const stub2 = stubBun(base2);
expect(runBashScript(script(stub2.bun, 'install_runtime_deps'), { cwd: base2, env: { ...process.env, FROZEN_RC: '1' } }).status).toBe(0);
expect(stub2.calls()).toEqual(['install --frozen-lockfile', 'install']);
});
test('every bun install in setup goes through install_runtime_deps', () => {
const body = setup.replace(sliceFunction(setup, 'install_runtime_deps'), '');
const directInstall = /(?:^|[\s;&|(])(?:bun_cmd|"?\$\{?BUN_CMD\}?"?|bun)\s+install\b/;
@@ -266,12 +283,13 @@ describe('setup and runtime need only production dependencies', () => {
for (const m of text.matchAll(relSpec)) {
const spec = path.posix.normalize(path.posix.join(path.posix.dirname(rel), m[1] ?? m[2]));
const target = [spec, `${spec}.ts`, `${spec}.js`, `${spec}/index.ts`].find((c) => fs.existsSync(path.join(ROOT, c)) && fs.statSync(path.join(ROOT, c)).isFile());
if (!target || target.startsWith('..') || target in files || target in reached || /(^|\/)(test|node_modules)\//.test(target) || !/\.(ts|js|mjs)$/.test(target)) continue;
if (!target || target.startsWith('..') || target in files || target in reached || /(^|\/)node_modules\//.test(target) || (/(^|\/)test\//.test(target) && !target.startsWith('test/helpers/')) || !/\.(ts|js|mjs)$/.test(target)) continue;
reached[target] = fs.readFileSync(path.join(ROOT, target), 'utf-8');
queue.push(target);
}
}
expect(Object.keys(reached)).toContain('scripts/discover-skills.ts');
expect(Object.keys(reached)).toContain('test/helpers/providers/claude.ts');
expect(nonProductionImports(PKG, reached)).toEqual([]);
});