diff --git a/packages/vscode/src/opencode.ts b/packages/vscode/src/opencode.ts index fe4e50fc..18482a9b 100644 --- a/packages/vscode/src/opencode.ts +++ b/packages/vscode/src/opencode.ts @@ -10,6 +10,7 @@ import { randomBytes } from 'crypto'; import { normalizeWindowsDriveLetter } from './pathUtils'; const READY_CHECK_TIMEOUT_MS = 30000; +const WINDOWS_EXECUTABLE_EXTENSIONS = ['', '.exe', '.cmd', '.bat', '.com']; export type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'error'; export type OpenCodeDebugInfo = { @@ -139,15 +140,18 @@ function findExecutableInPath(binaryName: string): string | null { return null; } + const extensions = process.platform === 'win32' ? WINDOWS_EXECUTABLE_EXTENSIONS : ['']; for (const segment of current.split(path.delimiter)) { const dir = segment.trim(); if (!dir) { continue; } - const candidate = path.join(dir, trimmed); - if (isExecutable(candidate)) { - return candidate; + for (const ext of extensions) { + const candidate = path.join(dir, process.platform === 'win32' ? `${trimmed}${ext}` : trimmed); + if (isExecutable(candidate)) { + return candidate; + } } } @@ -309,14 +313,18 @@ function resolveOpencodeCliPath(): string | null { const winFallbacks = (() => { const userProfile = process.env.USERPROFILE || home; - const appData = process.env.APPDATA || ''; + const appData = process.env.APPDATA || path.join(userProfile, 'AppData', 'Roaming'); const localAppData = process.env.LOCALAPPDATA || ''; const programData = process.env.ProgramData || 'C:\\ProgramData'; + const npmDir = path.join(appData, 'npm'); return [ path.join(userProfile, '.opencode', 'bin', 'opencode.exe'), path.join(userProfile, '.opencode', 'bin', 'opencode.cmd'), - path.join(appData, 'npm', 'opencode.cmd'), + path.join(npmDir, 'node_modules', 'opencode-ai', 'bin', 'opencode.exe'), + path.join(npmDir, 'opencode.exe'), + path.join(npmDir, 'opencode.cmd'), + path.join(npmDir, 'opencode.bat'), path.join(userProfile, 'scoop', 'shims', 'opencode.cmd'), path.join(programData, 'chocolatey', 'bin', 'opencode.exe'), path.join(programData, 'chocolatey', 'bin', 'opencode.cmd'), @@ -328,12 +336,10 @@ function resolveOpencodeCliPath(): string | null { ].filter(Boolean); })(); - if (process.platform !== 'win32') { - const fromPath = findExecutableInPath('opencode'); - if (fromPath) { - cachedDetectedOpencodeCliPath = fromPath; - return fromPath; - } + const fromPath = findExecutableInPath('opencode'); + if (fromPath) { + cachedDetectedOpencodeCliPath = fromPath; + return fromPath; } const fallbacks = process.platform === 'win32' ? winFallbacks : unixFallbacks;