mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-22 09:47:47 +00:00
chore(vscode-ide-companion): update dependencies in package-lock.json
Added new dependencies including: - @cfworker/json-schema - @parcel/watcher and related platform-specific packages - autoprefixer - browserslist - chokidar - Various other utility packages These updates likely support enhanced functionality and improved compatibility.
This commit is contained in:
163
packages/vscode-ide-companion/src/utils/CliInstaller.ts
Normal file
163
packages/vscode-ide-companion/src/utils/CliInstaller.ts
Normal file
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Qwen Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { CliDetector } from './cliDetector.js';
|
||||
|
||||
/**
|
||||
* CLI 检测和安装处理器
|
||||
* 负责 Qwen CLI 的检测、安装和提示功能
|
||||
*/
|
||||
export class CliInstaller {
|
||||
/**
|
||||
* 检查 CLI 安装状态并发送结果到 WebView
|
||||
* @param sendToWebView 发送消息到 WebView 的回调函数
|
||||
*/
|
||||
static async checkInstallation(
|
||||
sendToWebView: (message: unknown) => void,
|
||||
): Promise<void> {
|
||||
try {
|
||||
const result = await CliDetector.detectQwenCli();
|
||||
|
||||
sendToWebView({
|
||||
type: 'cliDetectionResult',
|
||||
data: {
|
||||
isInstalled: result.isInstalled,
|
||||
cliPath: result.cliPath,
|
||||
version: result.version,
|
||||
error: result.error,
|
||||
installInstructions: result.isInstalled
|
||||
? undefined
|
||||
: CliDetector.getInstallationInstructions(),
|
||||
},
|
||||
});
|
||||
|
||||
if (!result.isInstalled) {
|
||||
console.log('[CliInstaller] Qwen CLI not detected:', result.error);
|
||||
} else {
|
||||
console.log(
|
||||
'[CliInstaller] Qwen CLI detected:',
|
||||
result.cliPath,
|
||||
result.version,
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[CliInstaller] CLI detection error:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 提示用户安装 CLI
|
||||
* 显示警告消息,提供安装选项
|
||||
*/
|
||||
static async promptInstallation(): Promise<void> {
|
||||
const selection = await vscode.window.showWarningMessage(
|
||||
'Qwen Code CLI is not installed. You can browse conversation history, but cannot send new messages.',
|
||||
'Install Now',
|
||||
'View Documentation',
|
||||
'Remind Me Later',
|
||||
);
|
||||
|
||||
if (selection === 'Install Now') {
|
||||
await this.install();
|
||||
} else if (selection === 'View Documentation') {
|
||||
vscode.env.openExternal(
|
||||
vscode.Uri.parse('https://github.com/QwenLM/qwen-code#installation'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安装 Qwen CLI
|
||||
* 通过 npm 安装全局 CLI 包
|
||||
*/
|
||||
static async install(): Promise<void> {
|
||||
try {
|
||||
// Show progress notification
|
||||
await vscode.window.withProgress(
|
||||
{
|
||||
location: vscode.ProgressLocation.Notification,
|
||||
title: 'Installing Qwen Code CLI',
|
||||
cancellable: false,
|
||||
},
|
||||
async (progress) => {
|
||||
progress.report({
|
||||
message: 'Running: npm install -g @qwen-code/qwen-code@latest',
|
||||
});
|
||||
|
||||
const { exec } = await import('child_process');
|
||||
const { promisify } = await import('util');
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
try {
|
||||
const { stdout, stderr } = await execAsync(
|
||||
'npm install -g @qwen-code/qwen-code@latest',
|
||||
{ timeout: 120000 }, // 2 minutes timeout
|
||||
);
|
||||
|
||||
console.log('[CliInstaller] Installation output:', stdout);
|
||||
if (stderr) {
|
||||
console.warn('[CliInstaller] Installation stderr:', stderr);
|
||||
}
|
||||
|
||||
// Clear cache and recheck
|
||||
CliDetector.clearCache();
|
||||
const detection = await CliDetector.detectQwenCli();
|
||||
|
||||
if (detection.isInstalled) {
|
||||
vscode.window
|
||||
.showInformationMessage(
|
||||
`✅ Qwen Code CLI installed successfully! Version: ${detection.version}`,
|
||||
'Reload Window',
|
||||
)
|
||||
.then((selection) => {
|
||||
if (selection === 'Reload Window') {
|
||||
vscode.commands.executeCommand(
|
||||
'workbench.action.reloadWindow',
|
||||
);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
throw new Error(
|
||||
'Installation completed but CLI still not detected',
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : String(error);
|
||||
console.error('[CliInstaller] Installation failed:', errorMessage);
|
||||
|
||||
vscode.window
|
||||
.showErrorMessage(
|
||||
`Failed to install Qwen Code CLI: ${errorMessage}`,
|
||||
'Try Manual Installation',
|
||||
'View Documentation',
|
||||
)
|
||||
.then((selection) => {
|
||||
if (selection === 'Try Manual Installation') {
|
||||
const terminal = vscode.window.createTerminal(
|
||||
'Qwen Code Installation',
|
||||
);
|
||||
terminal.show();
|
||||
terminal.sendText(
|
||||
'npm install -g @qwen-code/qwen-code@latest',
|
||||
);
|
||||
} else if (selection === 'View Documentation') {
|
||||
vscode.env.openExternal(
|
||||
vscode.Uri.parse(
|
||||
'https://github.com/QwenLM/qwen-code#installation',
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('[CliInstaller] Install CLI error:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,21 +5,21 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* 从完整路径中提取文件名
|
||||
* @param fsPath 文件的完整路径
|
||||
* @returns 文件名(不含路径)
|
||||
* Extract filename from full path
|
||||
* @param fsPath Full path of the file
|
||||
* @returns Filename (without path)
|
||||
*/
|
||||
export function getFileName(fsPath: string): string {
|
||||
// 使用 path.basename 的逻辑:找到最后一个路径分隔符后的部分
|
||||
// Use path.basename logic: find the part after the last path separator
|
||||
const lastSlash = Math.max(fsPath.lastIndexOf('/'), fsPath.lastIndexOf('\\'));
|
||||
return lastSlash >= 0 ? fsPath.substring(lastSlash + 1) : fsPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML 转义函数,防止 XSS 攻击
|
||||
* 将特殊字符转换为 HTML 实体
|
||||
* @param text 需要转义的文本
|
||||
* @returns 转义后的文本
|
||||
* HTML escape function to prevent XSS attacks
|
||||
* Convert special characters to HTML entities
|
||||
* @param text Text to escape
|
||||
* @returns Escaped text
|
||||
*/
|
||||
export function escapeHtml(text: string): string {
|
||||
return text
|
||||
|
||||
Reference in New Issue
Block a user