diff --git a/src/runs/shared/pi-spawn.ts b/src/runs/shared/pi-spawn.ts index e4d306a46..abfbdb2fb 100644 --- a/src/runs/shared/pi-spawn.ts +++ b/src/runs/shared/pi-spawn.ts @@ -70,6 +70,11 @@ function normalizePath(filePath: string): string { return path.isAbsolute(filePath) ? filePath : path.resolve(filePath); } +function isStandalonePiExecutable(execPath: string): boolean { + const executableName = execPath.split(/[\\/]/).pop(); + return /^pi(?:\.exe)?$/i.test(executableName ?? ""); +} + export function resolvePiCliScript( deps: PiSpawnDeps = {}, ): string | undefined { @@ -141,10 +146,15 @@ export function getPiSpawnCommand( return { command: piBinary, args }; } + const execPath = deps.execPath ?? process.execPath; + if (isStandalonePiExecutable(execPath)) { + return { command: execPath, args }; + } + const piCliPath = resolvePiCliScript(deps); if (piCliPath) { return { - command: deps.execPath ?? process.execPath, + command: execPath, args: [piCliPath, ...args], }; } diff --git a/test/unit/pi-spawn.test.ts b/test/unit/pi-spawn.test.ts index b4888f457..cf946d1f2 100644 --- a/test/unit/pi-spawn.test.ts +++ b/test/unit/pi-spawn.test.ts @@ -73,6 +73,33 @@ describe("getPiSpawnCommand", () => { assert.deepEqual(result, { command: "pi", args }); }); + for (const [platform, execPath] of [ + ["darwin", "/opt/pi/pi"], + ["linux", "/opt/pi/pi"], + ["win32", "C:\\Program Files\\Pi\\pi.exe"], + ] as const) { + it(`uses the standalone Pi executable directly on ${platform}`, () => { + const packageJsonPath = "/opt/pi-package/package.json"; + const cliPath = path.resolve( + path.dirname(packageJsonPath), + "dist/cli.js", + ); + const deps = makeDeps({ + platform, + execPath, + argv1: "/missing/host.js", + packageJsonPath, + packageJsonContent: JSON.stringify({ bin: { pi: "dist/cli.js" } }), + existing: [packageJsonPath, cliPath], + }); + const args = ["--mode", "json", "-p", "Task: review diff"]; + assert.deepEqual(getPiSpawnCommand(args, deps), { + command: execPath, + args, + }); + }); + } + for (const platform of ["darwin", "linux", "win32"] as const) { it(`uses node + argv1 on ${platform} when argv1 belongs to the Pi package`, () => { const tempDir = fs.mkdtempSync(