From b92fb9392ebed5e011895d846ce735afa4e542ea Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Tue, 5 May 2026 12:33:09 +0800 Subject: [PATCH] fix(cli-tests): prepend root node_modules/.bin to PATH in test runner (#737) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When npm runs a workspace script, it only adds the workspace-local node_modules/.bin to PATH. packages/cli/node_modules/.bin doesn't exist because all packages are hoisted to the root. This caused `npx paseo` inside test files to miss the local binary and fall back to the npm registry, where a stale npx cache entry for @getpaseo/cli was missing bin/paseo — failing the chmod with ENOENT and exiting 254. 07-agent-stop was the first test in shard 2/3 to call `npx paseo` without spinning up a daemon first, so it reliably hit the broken cache path. Fix: prepend root/node_modules/.bin to PATH in the spawn env for each test subprocess. --- packages/cli/tests/run-all.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/cli/tests/run-all.ts b/packages/cli/tests/run-all.ts index 98904dff2..2617c4ba7 100644 --- a/packages/cli/tests/run-all.ts +++ b/packages/cli/tests/run-all.ts @@ -11,10 +11,14 @@ import { spawn } from "child_process"; import { $ } from "zx"; import { readdir, writeFile } from "fs/promises"; -import { join, dirname } from "path"; +import { join, dirname, delimiter } from "path"; import { fileURLToPath } from "url"; const __dirname = dirname(fileURLToPath(import.meta.url)); + +// npm workspace scripts only add the local node_modules/.bin to PATH; hoisted +// packages live in the root. Prepend it so `npx paseo` resolves locally. +const rootNodeModulesBin = join(__dirname, "..", "..", "..", "node_modules", ".bin"); const args = process.argv.slice(2); const testEnvDefaults = { PASEO_LOCAL_SPEECH_AUTO_DOWNLOAD: process.env.PASEO_LOCAL_SPEECH_AUTO_DOWNLOAD ?? "0", @@ -193,6 +197,7 @@ async function runSingleTest(testFile: string): Promise { const proc = spawn("npx", ["tsx", testPath], { env: { ...process.env, + PATH: [rootNodeModulesBin, process.env.PATH].filter(Boolean).join(delimiter), PASEO_LOCAL_SPEECH_AUTO_DOWNLOAD: testEnvDefaults.PASEO_LOCAL_SPEECH_AUTO_DOWNLOAD, PASEO_DICTATION_ENABLED: testEnvDefaults.PASEO_DICTATION_ENABLED, PASEO_VOICE_MODE_ENABLED: testEnvDefaults.PASEO_VOICE_MODE_ENABLED,