feat(cli): 添加 CLI 版本检测和会话验证功能

- 新增 CLI 版本检测功能,支持检测 CLI 版本并缓存结果
- 实现会话验证方法,用于检查当前会话是否有效
- 在连接处理中集成 CLI 版本检测和会话验证逻辑
- 优化 WebViewProvider 中的初始化流程,支持背景初始化
- 更新消息处理逻辑,增加与 CLI 相关的错误处理
This commit is contained in:
yiliang114
2025-11-28 01:13:57 +08:00
parent b986692f94
commit 8bc9bea5a1
9 changed files with 644 additions and 5 deletions

View File

@@ -5,7 +5,7 @@
*/
import * as vscode from 'vscode';
import { CliDetector } from './cliDetector.js';
import { CliDetector } from '../cli/cliDetector.js';
/**
* CLI Detection and Installation Handler

View File

@@ -1,129 +0,0 @@
/**
* @license
* Copyright 2025 Qwen Team
* SPDX-License-Identifier: Apache-2.0
*/
import { exec } from 'child_process';
import { promisify } from 'util';
const execAsync = promisify(exec);
export interface CliDetectionResult {
isInstalled: boolean;
cliPath?: string;
version?: string;
error?: string;
}
/**
* Detects if Qwen Code CLI is installed and accessible
*/
export class CliDetector {
private static cachedResult: CliDetectionResult | null = null;
private static lastCheckTime: number = 0;
private static readonly CACHE_DURATION_MS = 30000; // 30 seconds
/**
* Checks if the Qwen Code CLI is installed
* @param forceRefresh - Force a new check, ignoring cache
* @returns Detection result with installation status and details
*/
static async detectQwenCli(
forceRefresh = false,
): Promise<CliDetectionResult> {
const now = Date.now();
// Return cached result if available and not expired
if (
!forceRefresh &&
this.cachedResult &&
now - this.lastCheckTime < this.CACHE_DURATION_MS
) {
return this.cachedResult;
}
try {
const isWindows = process.platform === 'win32';
const whichCommand = isWindows ? 'where' : 'which';
// Check if qwen command exists
try {
const { stdout } = await execAsync(`${whichCommand} qwen`, {
timeout: 5000,
});
const cliPath = stdout.trim().split('\n')[0];
// Try to get version
let version: string | undefined;
try {
const { stdout: versionOutput } = await execAsync('qwen --version', {
timeout: 5000,
});
version = versionOutput.trim();
} catch {
// Version check failed, but CLI is installed
}
this.cachedResult = {
isInstalled: true,
cliPath,
version,
};
this.lastCheckTime = now;
return this.cachedResult;
} catch (_error) {
// CLI not found
this.cachedResult = {
isInstalled: false,
error: `Qwen Code CLI not found in PATH. Please install it using: npm install -g @qwen-code/qwen-code@latest`,
};
this.lastCheckTime = now;
return this.cachedResult;
}
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : String(error);
this.cachedResult = {
isInstalled: false,
error: `Failed to detect Qwen Code CLI: ${errorMessage}`,
};
this.lastCheckTime = now;
return this.cachedResult;
}
}
/**
* Clears the cached detection result
*/
static clearCache(): void {
this.cachedResult = null;
this.lastCheckTime = 0;
}
/**
* Gets installation instructions based on the platform
*/
static getInstallationInstructions(): {
title: string;
steps: string[];
documentationUrl: string;
} {
return {
title: 'Qwen Code CLI is not installed',
steps: [
'Install via npm:',
' npm install -g @qwen-code/qwen-code@latest',
'',
'Or install from source:',
' git clone https://github.com/QwenLM/qwen-code.git',
' cd qwen-code',
' npm install',
' npm install -g .',
'',
'After installation, reload VS Code or restart the extension.',
],
documentationUrl: 'https://github.com/QwenLM/qwen-code#installation',
};
}
}