Skip to content
2 changes: 1 addition & 1 deletion packages/shared/config/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ export const WINDOWS_TERMINALS_WITH_COMMANDS: TerminalConfigWithCommand[] = [
name: 'Windows Terminal',
command: (_: string, fullCommand: string) => ({
command: 'wt',
args: ['-p', 'Command Prompt', '--', 'cmd', '/c', `"${fullCommand}"`]
args: ['-p', `"Command Prompt"`, '--', 'cmd', '/c', fullCommand]
})
},
{
Expand Down
53 changes: 52 additions & 1 deletion src/main/services/CodeToolsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,26 @@ class CodeToolsService {
return bunPath
}

/**
* Compare two semantic versions
* @param version1 - First version string (e.g., "1.2.3")
* @param version2 - Second version string (e.g., "1.2.4")
* @returns -1 if version1 < version2, 0 if equal, 1 if version1 > version2
*/
private compareVersions(version1: string, version2: string): number {
const v1Parts = version1.split('.').map(Number)
const v2Parts = version2.split('.').map(Number)
const maxLength = Math.max(v1Parts.length, v2Parts.length)

for (let i = 0; i < maxLength; i++) {
const v1Part = v1Parts[i] || 0
const v2Part = v2Parts[i] || 0
if (v1Part < v2Part) return -1
if (v1Part > v2Part) return 1
}
return 0
}

public async getPackageName(cliTool: string) {
switch (cliTool) {
case codeTools.claudeCode:
Expand Down Expand Up @@ -836,10 +856,12 @@ class CodeToolsService {

// Check for updates and auto-update if requested
let updateMessage = ''
let installedVersion: string | null = null
if (isInstalled && options.autoUpdateToLatest) {
logger.info(`Auto update to latest enabled for ${cliTool}`)
try {
const versionInfo = await this.getVersionInfo(cliTool)
installedVersion = versionInfo.installed
if (versionInfo.needsUpdate) {
logger.info(`Update available for ${cliTool}: ${versionInfo.installed} -> ${versionInfo.latest}`)
logger.info(`Auto-updating ${cliTool} to latest version`)
Expand Down Expand Up @@ -913,6 +935,18 @@ class CodeToolsService {
baseCommand = `${uvPath} tool run ${packageName}`
}

// Special handling for qwen-code: add --auth-type openai for version >= 0.12.3
if (cliTool === codeTools.qwenCode) {
// Check if installed version is >= 0.12.3
const needsAuthType = installedVersion && this.compareVersions(installedVersion, '0.12.3') >= 0
if (needsAuthType) {
baseCommand = `${baseCommand} --auth-type openai`
logger.info(`qwen-code version ${installedVersion} >= 0.12.3, using --auth-type openai`)
} else {
logger.info(`qwen-code version ${installedVersion || 'unknown'} < 0.12.3, not using --auth-type`)
}
}

// Add configuration parameters for OpenAI Codex using command line args
if (cliTool === codeTools.openaiCodex && env.OPENAI_MODEL_PROVIDER) {
const providerId = env.OPENAI_MODEL_PROVIDER
Expand Down Expand Up @@ -977,7 +1011,24 @@ class CodeToolsService {
? `set "BUN_INSTALL=${bunInstallPath}" && set "NPM_CONFIG_REGISTRY=${registryUrl}" &&`
: `export BUN_INSTALL="${bunInstallPath}" && export NPM_CONFIG_REGISTRY="${registryUrl}" &&`

const installCommand = `${installEnvPrefix} "${bunPath}" install -g ${packageName}`
// Windows: Redirect bun output to log file to prevent cmd.exe from
// misinterpreting multiline output as separate commands
// macOS/Linux: Keep output visible in terminal (handles multiline correctly)
let installCommand: string
if (platform === 'win32') {
const logsDir = loggerService.getLogsDir()
const installLogPath = path.join(logsDir, 'cli-tools-install.log')

// Ensure logs directory exists
if (!fs.existsSync(logsDir)) {
fs.mkdirSync(logsDir, { recursive: true })
}

installCommand = `${installEnvPrefix} "${bunPath}" install -g ${packageName} >> "${installLogPath}" 2>&1`
} else {
installCommand = `${installEnvPrefix} "${bunPath}" install -g ${packageName}`
}

baseCommand = `echo "Installing ${packageName}..." && ${installCommand} && echo "Installation complete, starting ${cliTool}..." && ${baseCommand}`
}

Expand Down