From 5c13040f585ec6b6e4636f8c73bc012f42aa074e Mon Sep 17 00:00:00 2001 From: Aaron Erickson Date: Tue, 14 Apr 2026 22:29:53 -0700 Subject: [PATCH] fix(test): extract shellQuote to standalone module to fix vitest CJS resolution config-io.ts importing shellQuote from runner.ts caused vitest to load runner.ts from source, where the CJS require("./platform") fails because Node cannot resolve .ts extensions. Extract shellQuote into shell-quote.ts so config-io.ts no longer pulls in runner.ts and its platform dependency. Fixes the MODULE_NOT_FOUND error in sandbox-version.test.ts and secret-redaction.test.ts introduced by #1370. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/lib/config-io.ts | 2 +- src/lib/shell-quote.ts | 10 ++++++++++ test/runner.test.ts | 7 +++++-- 3 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 src/lib/shell-quote.ts diff --git a/src/lib/config-io.ts b/src/lib/config-io.ts index 00cbbe7ac9..afd516ab79 100644 --- a/src/lib/config-io.ts +++ b/src/lib/config-io.ts @@ -7,7 +7,7 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; -import { shellQuote } from "./runner"; +import { shellQuote } from "./shell-quote"; function buildRemediation(): string { const home = process.env.HOME || os.homedir(); diff --git a/src/lib/shell-quote.ts b/src/lib/shell-quote.ts new file mode 100644 index 0000000000..55b88d5162 --- /dev/null +++ b/src/lib/shell-quote.ts @@ -0,0 +1,10 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * Shell-quote a value for safe interpolation into bash -c strings. + * Wraps in single quotes and escapes embedded single quotes. + */ +export function shellQuote(value: string): string { + return `'${String(value).replace(/'/g, `'\\''`)}'`; +} diff --git a/test/runner.test.ts b/test/runner.test.ts index 5f824203af..f1fc6c261e 100644 --- a/test/runner.test.ts +++ b/test/runner.test.ts @@ -429,8 +429,11 @@ describe("regression guards", () => { defs.push(path.relative(repoRoot, file)); } } - expect(defs).toHaveLength(1); - expect(defs[0]).toBe(path.join("src", "lib", "runner.ts")); + // runner.ts (CJS consumers) and shell-quote.ts (ESM consumers like config-io.ts) + expect(defs.sort()).toEqual([ + path.join("src", "lib", "runner.ts"), + path.join("src", "lib", "shell-quote.ts"), + ]); }); it("CLI rejects malicious sandbox names before shell commands (e2e)", () => {