feat(vscode-ide-companion): 更新核心服务和扩展功能

- 增强 extension.ts,集成新增功能
- 优化 ide-server.ts,改进服务端逻辑
- 更新 diff-manager.ts,提升差异管理能力
- 改进 ACP 连接和消息处理
- 更新会话处理器,支持新的交互模式

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
yiliang114
2025-11-21 01:54:24 +08:00
parent ecc6e22002
commit e2beecb9c4
6 changed files with 68 additions and 19 deletions

View File

@@ -184,9 +184,17 @@ export class AcpConnection {
if (line.trim()) {
try {
const message = JSON.parse(line) as AcpMessage;
console.log(
'[ACP] <<< Received message:',
JSON.stringify(message).substring(0, 500),
);
this.handleMessage(message);
} catch (_error) {
// 忽略非JSON行
console.log(
'[ACP] <<< Non-JSON line (ignored):',
line.substring(0, 200),
);
}
}
}

View File

@@ -154,6 +154,10 @@ export class AcpMessageHandler {
switch (method) {
case CLIENT_METHODS.session_update:
console.log(
'[ACP] >>> Processing session_update:',
JSON.stringify(params).substring(0, 300),
);
callbacks.onSessionUpdate(params as AcpSessionUpdate);
break;
case CLIENT_METHODS.session_request_permission:

View File

@@ -40,6 +40,10 @@ export class QwenSessionUpdateHandler {
*/
handleSessionUpdate(data: AcpSessionUpdate): void {
const update = data.update;
console.log(
'[SessionUpdateHandler] Processing update type:',
update.sessionUpdate,
);
switch (update.sessionUpdate) {
case 'user_message_chunk':

View File

@@ -76,15 +76,26 @@ export class DiffManager {
/**
* Creates and shows a new diff view.
* @param filePath Path to the file being diffed
* @param oldContent The original content (left side)
* @param newContent The modified content (right side)
*/
async showDiff(filePath: string, newContent: string) {
const fileUri = vscode.Uri.file(filePath);
async showDiff(filePath: string, oldContent: string, newContent: string) {
const _fileUri = vscode.Uri.file(filePath);
// Left side: old content using qwen-diff scheme
const leftDocUri = vscode.Uri.from({
scheme: DIFF_SCHEME,
path: filePath,
query: `old&rand=${Math.random()}`,
});
this.diffContentProvider.setContent(leftDocUri, oldContent);
// Right side: new content using qwen-diff scheme
const rightDocUri = vscode.Uri.from({
scheme: DIFF_SCHEME,
path: filePath,
// cache busting
query: `rand=${Math.random()}`,
query: `new&rand=${Math.random()}`,
});
this.diffContentProvider.setContent(rightDocUri, newContent);
@@ -94,26 +105,13 @@ export class DiffManager {
rightDocUri,
});
const diffTitle = `${path.basename(filePath)} ↔ Modified`;
const diffTitle = `${path.basename(filePath)} (Before ↔ After)`;
await vscode.commands.executeCommand(
'setContext',
'qwen.diff.isVisible',
true,
);
let leftDocUri;
try {
await vscode.workspace.fs.stat(fileUri);
leftDocUri = fileUri;
} catch {
// We need to provide an empty document to diff against.
// Using the 'untitled' scheme is one way to do this.
leftDocUri = vscode.Uri.from({
scheme: 'untitled',
path: filePath,
});
}
await vscode.commands.executeCommand(
'vscode.diff',
leftDocUri,

View File

@@ -177,6 +177,30 @@ export async function activate(context: vscode.ExtensionContext) {
diffManager.cancelDiff(docUri);
}
}),
vscode.commands.registerCommand(
'qwenCode.showDiff',
async (args: { path: string; oldText: string; newText: string }) => {
log(`[Command] showDiff called for: ${args.path}`);
try {
// Convert relative path to absolute if needed
let absolutePath = args.path;
if (!args.path.startsWith('/') && !args.path.match(/^[a-zA-Z]:/)) {
const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
if (workspaceFolder) {
absolutePath = vscode.Uri.joinPath(
workspaceFolder.uri,
args.path,
).fsPath;
}
}
await diffManager.showDiff(absolutePath, args.oldText, args.newText);
} catch (error) {
log(`[Command] Error showing diff: ${error}`);
vscode.window.showErrorMessage(`Failed to show diff: ${error}`);
}
},
),
vscode.commands.registerCommand('qwenCode.openChat', () => {
// Open or reveal the most recent chat tab
if (webViewProviders.length > 0) {

View File

@@ -437,7 +437,18 @@ const createMcpServer = (diffManager: DiffManager) => {
inputSchema: OpenDiffRequestSchema.shape,
},
async ({ filePath, newContent }: z.infer<typeof OpenDiffRequestSchema>) => {
await diffManager.showDiff(filePath, newContent);
// Read old content if file exists, otherwise use empty string
let oldContent = '';
try {
const fileUri = vscode.Uri.file(filePath);
const document = await vscode.workspace.openTextDocument(fileUri);
oldContent = document.getText();
} catch (_error) {
// File doesn't exist, use empty string (creating new file)
oldContent = '';
}
await diffManager.showDiff(filePath, oldContent, newContent);
return { content: [] };
},
);