mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-23 02:07:52 +00:00
feat(vscode-ide-companion): improve CLI path detection and error handling
- Move determineNodePathForCli function to dedicated cliPathDetector.ts file - Enhance error handling with specific guidance for permission issues - Add detailed error messages for different failure scenarios - Improve logging for debugging CLI path detection issues This change improves the reliability of CLI path detection by providing better error messages and handling edge cases more gracefully.
This commit is contained in:
@@ -20,7 +20,7 @@ import type {
|
||||
} from './connectionTypes.js';
|
||||
import { AcpMessageHandler } from './acpMessageHandler.js';
|
||||
import { AcpSessionManager } from './acpSessionManager.js';
|
||||
import { statSync } from 'fs';
|
||||
import { determineNodePathForCli } from '../cli/cliPathDetector.js';
|
||||
|
||||
/**
|
||||
* ACP Connection Handler for VSCode Extension
|
||||
@@ -66,74 +66,6 @@ export class AcpConnection {
|
||||
this.sessionManager = new AcpSessionManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the correct Node.js executable path for a given CLI installation
|
||||
* Handles various Node.js version managers (nvm, n, manual installations)
|
||||
*
|
||||
* @param cliPath - Path to the CLI executable
|
||||
* @returns Path to the Node.js executable, or null if not found
|
||||
*/
|
||||
private determineNodePathForCli(cliPath: string): string | null {
|
||||
// Common patterns for Node.js installations
|
||||
const nodePathPatterns = [
|
||||
// NVM pattern: /Users/user/.nvm/versions/node/vXX.XX.X/bin/qwen -> /Users/user/.nvm/versions/node/vXX.XX.X/bin/node
|
||||
cliPath.replace(/\/bin\/qwen$/, '/bin/node'),
|
||||
|
||||
// N pattern: /Users/user/n/bin/qwen -> /Users/user/n/bin/node
|
||||
cliPath.replace(/\/bin\/qwen$/, '/bin/node'),
|
||||
|
||||
// Manual installation pattern: /usr/local/bin/qwen -> /usr/local/bin/node
|
||||
cliPath.replace(/\/qwen$/, '/node'),
|
||||
|
||||
// Alternative pattern: /opt/nodejs/bin/qwen -> /opt/nodejs/bin/node
|
||||
cliPath.replace(/\/bin\/qwen$/, '/bin/node'),
|
||||
];
|
||||
|
||||
// Check each pattern
|
||||
for (const nodePath of nodePathPatterns) {
|
||||
try {
|
||||
if (statSync(nodePath).isFile()) {
|
||||
// Verify it's executable
|
||||
const stats = statSync(nodePath);
|
||||
if (stats.mode & 0o111) {
|
||||
// Check if executable
|
||||
console.log(
|
||||
`[ACP] Found Node.js executable for CLI at: ${nodePath}`,
|
||||
);
|
||||
return nodePath;
|
||||
}
|
||||
}
|
||||
} catch (_error) {
|
||||
// File doesn't exist or other error, continue to next pattern
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to find node in the same directory as the CLI
|
||||
const cliDir = cliPath.substring(0, cliPath.lastIndexOf('/'));
|
||||
const potentialNodePaths = [`${cliDir}/node`, `${cliDir}/bin/node`];
|
||||
|
||||
for (const nodePath of potentialNodePaths) {
|
||||
try {
|
||||
if (statSync(nodePath).isFile()) {
|
||||
const stats = statSync(nodePath);
|
||||
if (stats.mode & 0o111) {
|
||||
console.log(
|
||||
`[ACP] Found Node.js executable in CLI directory at: ${nodePath}`,
|
||||
);
|
||||
return nodePath;
|
||||
}
|
||||
}
|
||||
} catch (_error) {
|
||||
// File doesn't exist, continue
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`[ACP] Could not determine Node.js path for CLI: ${cliPath}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to ACP backend
|
||||
*
|
||||
@@ -185,14 +117,21 @@ export class AcpConnection {
|
||||
// Handle various Node.js version managers (nvm, n, manual installations)
|
||||
if (cliPath.includes('/qwen') && !isWindows) {
|
||||
// Try to determine the correct node executable for this qwen installation
|
||||
const nodePath = this.determineNodePathForCli(cliPath);
|
||||
if (nodePath) {
|
||||
spawnCommand = nodePath;
|
||||
const nodePathResult = determineNodePathForCli(cliPath);
|
||||
if (nodePathResult.path) {
|
||||
spawnCommand = nodePathResult.path;
|
||||
spawnArgs = [cliPath, '--experimental-acp', ...extraArgs];
|
||||
} else {
|
||||
// Fallback to direct execution
|
||||
spawnCommand = cliPath;
|
||||
spawnArgs = ['--experimental-acp', ...extraArgs];
|
||||
|
||||
// Log any error for debugging
|
||||
if (nodePathResult.error) {
|
||||
console.warn(
|
||||
`[ACP] Node.js path detection warning: ${nodePathResult.error}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
spawnCommand = cliPath;
|
||||
|
||||
@@ -18,7 +18,7 @@ import type {
|
||||
AcpSessionUpdate,
|
||||
AcpPermissionRequest,
|
||||
} from '../constants/acpTypes.js';
|
||||
import { CLIENT_METHODS } from './schema.js';
|
||||
import { CLIENT_METHODS } from '../constants/acpSchema.js';
|
||||
import type {
|
||||
PendingRequest,
|
||||
AcpConnectionCallbacks,
|
||||
|
||||
@@ -16,7 +16,7 @@ import type {
|
||||
AcpNotification,
|
||||
AcpResponse,
|
||||
} from '../constants/acpTypes.js';
|
||||
import { AGENT_METHODS, CUSTOM_METHODS } from './schema.js';
|
||||
import { AGENT_METHODS, CUSTOM_METHODS } from '../constants/acpSchema.js';
|
||||
import type { PendingRequest } from './connectionTypes.js';
|
||||
import type { ChildProcess } from 'child_process';
|
||||
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Qwen Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* ACP (Agent Communication Protocol) Method Definitions
|
||||
*
|
||||
* This file defines the protocol methods for communication between
|
||||
* the VSCode extension (Client) and the qwen CLI (Agent/Server).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Methods that the Agent (CLI) implements and receives from Client (VSCode)
|
||||
*
|
||||
* Status in qwen CLI:
|
||||
* ✅ initialize - Protocol initialization
|
||||
* ✅ authenticate - User authentication
|
||||
* ✅ session/new - Create new session
|
||||
* ✅ session/load - Load existing session (v0.2.4+)
|
||||
* ✅ session/list - List available sessions (v0.2.4+)
|
||||
* ✅ session/prompt - Send user message to agent
|
||||
* ✅ session/cancel - Cancel current generation
|
||||
* ✅ session/save - Save current session
|
||||
*/
|
||||
export const AGENT_METHODS = {
|
||||
authenticate: 'authenticate',
|
||||
initialize: 'initialize',
|
||||
session_cancel: 'session/cancel',
|
||||
session_list: 'session/list',
|
||||
session_load: 'session/load',
|
||||
session_new: 'session/new',
|
||||
session_prompt: 'session/prompt',
|
||||
session_save: 'session/save',
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Methods that the Client (VSCode) implements and receives from Agent (CLI)
|
||||
*
|
||||
* Status in VSCode extension:
|
||||
* ✅ fs/read_text_file - Read file content
|
||||
* ✅ fs/write_text_file - Write file content
|
||||
* ✅ session/request_permission - Request user permission for tool execution
|
||||
* ✅ session/update - Stream session updates (notification)
|
||||
*/
|
||||
export const CLIENT_METHODS = {
|
||||
fs_read_text_file: 'fs/read_text_file',
|
||||
fs_write_text_file: 'fs/write_text_file',
|
||||
session_request_permission: 'session/request_permission',
|
||||
session_update: 'session/update',
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Custom methods (not in standard ACP protocol)
|
||||
* These are VSCode extension specific extensions
|
||||
*/
|
||||
export const CUSTOM_METHODS = {
|
||||
session_list: 'session/list',
|
||||
} as const;
|
||||
Reference in New Issue
Block a user