diff --git a/lib/provider-detection.js b/lib/provider-detection.js index 69526496..d2f1f930 100644 --- a/lib/provider-detection.js +++ b/lib/provider-detection.js @@ -1,14 +1,19 @@ -const { execSync, spawnSync } = require('child_process'); +const childProcess = require('child_process'); +const { execSync, spawnSync } = childProcess; const fs = require('fs'); const path = require('path'); +function commandLookupCommand(command) { + return process.platform === 'win32' ? `where ${command}` : `command -v ${command}`; +} + function commandExists(command) { if (!command) return false; if (command.includes(path.sep)) { return fs.existsSync(command); } try { - execSync(`command -v ${command}`, { stdio: 'pipe' }); + execSync(commandLookupCommand(command), { stdio: 'pipe' }); return true; } catch { return false; @@ -21,7 +26,7 @@ function getCommandPath(command) { return fs.existsSync(command) ? command : null; } try { - const output = execSync(`command -v ${command}`, { encoding: 'utf8', stdio: 'pipe' }); + const output = execSync(commandLookupCommand(command), { encoding: 'utf8', stdio: 'pipe' }); return output.trim() || null; } catch { return null; @@ -56,4 +61,5 @@ module.exports = { getCommandPath, getHelpOutput, getVersionOutput, + commandLookupCommand, }; diff --git a/src/agent/agent-task-executor.js b/src/agent/agent-task-executor.js index 5bc4cd77..13ab92fd 100644 --- a/src/agent/agent-task-executor.js +++ b/src/agent/agent-task-executor.js @@ -727,6 +727,7 @@ function spawnTaskProcess({ agent, ctPath, args, cwd, spawnEnv }) { cwd, stdio: ['ignore', 'pipe', 'pipe'], env: spawnEnv, + windowsHide: true, }); // NOTE: Don't emit PROCESS_SPAWNED here - proc.pid is a wrapper that exits immediately. diff --git a/src/claude-task-runner.js b/src/claude-task-runner.js index eb03b107..2cef56ec 100644 --- a/src/claude-task-runner.js +++ b/src/claude-task-runner.js @@ -200,6 +200,7 @@ class ClaudeTaskRunner extends TaskRunner { cwd, stdio: ['ignore', 'pipe', 'pipe'], env: spawnEnv, + windowsHide: true, }); let stdout = ''; diff --git a/task-lib/runner.js b/task-lib/runner.js index 807008c7..0d68bf7b 100644 --- a/task-lib/runner.js +++ b/task-lib/runner.js @@ -173,6 +173,7 @@ function spawnWatcher({ watcherScript, id, cwd, logFile, finalArgs, watcherConfi { detached: true, stdio: 'ignore', + windowsHide: true, } ); diff --git a/task-lib/watcher.js b/task-lib/watcher.js index ea36169b..051e5e16 100644 --- a/task-lib/watcher.js +++ b/task-lib/watcher.js @@ -37,6 +37,7 @@ const child = spawn(command, finalArgs, { cwd, env, stdio: ['ignore', 'pipe', 'pipe'], + windowsHide: true, }); updateTask(taskId, { pid: child.pid }); diff --git a/tests/providers/detection.test.js b/tests/providers/detection.test.js index ef02018d..d6f73ae7 100644 --- a/tests/providers/detection.test.js +++ b/tests/providers/detection.test.js @@ -1,9 +1,11 @@ const assert = require('assert'); +const sinon = require('sinon'); const { commandExists, getCommandPath, getHelpOutput, getVersionOutput, + commandLookupCommand, } = require('../../lib/provider-detection'); describe('Provider CLI detection', () => { @@ -28,3 +30,21 @@ describe('Provider CLI detection', () => { assert.ok(version.length > 0); }); }); + +describe('commandLookupCommand', () => { + let platformStub; + + afterEach(() => { + if (platformStub) platformStub.restore(); + }); + + it('uses where on Windows', () => { + platformStub = sinon.stub(process, 'platform').value('win32'); + assert.strictEqual(commandLookupCommand('claude'), 'where claude'); + }); + + it('uses command -v on non-Windows platforms', () => { + platformStub = sinon.stub(process, 'platform').value('linux'); + assert.strictEqual(commandLookupCommand('claude'), 'command -v claude'); + }); +});