diff --git a/packages/vscode-ide-companion/src/acp/acpConnection.ts b/packages/vscode-ide-companion/src/acp/acpConnection.ts index 2f75f60a..204ccf7a 100644 --- a/packages/vscode-ide-companion/src/acp/acpConnection.ts +++ b/packages/vscode-ide-companion/src/acp/acpConnection.ts @@ -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), + ); } } } diff --git a/packages/vscode-ide-companion/src/acp/acpMessageHandler.ts b/packages/vscode-ide-companion/src/acp/acpMessageHandler.ts index 08b59346..967c6e8f 100644 --- a/packages/vscode-ide-companion/src/acp/acpMessageHandler.ts +++ b/packages/vscode-ide-companion/src/acp/acpMessageHandler.ts @@ -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: diff --git a/packages/vscode-ide-companion/src/agents/qwenSessionUpdateHandler.ts b/packages/vscode-ide-companion/src/agents/qwenSessionUpdateHandler.ts index 3ed27d2d..61fde052 100644 --- a/packages/vscode-ide-companion/src/agents/qwenSessionUpdateHandler.ts +++ b/packages/vscode-ide-companion/src/agents/qwenSessionUpdateHandler.ts @@ -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': diff --git a/packages/vscode-ide-companion/src/diff-manager.ts b/packages/vscode-ide-companion/src/diff-manager.ts index fea9edc4..83636c56 100644 --- a/packages/vscode-ide-companion/src/diff-manager.ts +++ b/packages/vscode-ide-companion/src/diff-manager.ts @@ -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, diff --git a/packages/vscode-ide-companion/src/extension.ts b/packages/vscode-ide-companion/src/extension.ts index 1c03ca60..084b3f2a 100644 --- a/packages/vscode-ide-companion/src/extension.ts +++ b/packages/vscode-ide-companion/src/extension.ts @@ -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) { diff --git a/packages/vscode-ide-companion/src/ide-server.ts b/packages/vscode-ide-companion/src/ide-server.ts index e67dfa81..98fafc98 100644 --- a/packages/vscode-ide-companion/src/ide-server.ts +++ b/packages/vscode-ide-companion/src/ide-server.ts @@ -437,7 +437,18 @@ const createMcpServer = (diffManager: DiffManager) => { inputSchema: OpenDiffRequestSchema.shape, }, async ({ filePath, newContent }: z.infer) => { - 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: [] }; }, );