mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
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:
@@ -184,9 +184,17 @@ export class AcpConnection {
|
|||||||
if (line.trim()) {
|
if (line.trim()) {
|
||||||
try {
|
try {
|
||||||
const message = JSON.parse(line) as AcpMessage;
|
const message = JSON.parse(line) as AcpMessage;
|
||||||
|
console.log(
|
||||||
|
'[ACP] <<< Received message:',
|
||||||
|
JSON.stringify(message).substring(0, 500),
|
||||||
|
);
|
||||||
this.handleMessage(message);
|
this.handleMessage(message);
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
// 忽略非JSON行
|
// 忽略非JSON行
|
||||||
|
console.log(
|
||||||
|
'[ACP] <<< Non-JSON line (ignored):',
|
||||||
|
line.substring(0, 200),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,6 +154,10 @@ export class AcpMessageHandler {
|
|||||||
|
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case CLIENT_METHODS.session_update:
|
case CLIENT_METHODS.session_update:
|
||||||
|
console.log(
|
||||||
|
'[ACP] >>> Processing session_update:',
|
||||||
|
JSON.stringify(params).substring(0, 300),
|
||||||
|
);
|
||||||
callbacks.onSessionUpdate(params as AcpSessionUpdate);
|
callbacks.onSessionUpdate(params as AcpSessionUpdate);
|
||||||
break;
|
break;
|
||||||
case CLIENT_METHODS.session_request_permission:
|
case CLIENT_METHODS.session_request_permission:
|
||||||
|
|||||||
@@ -40,6 +40,10 @@ export class QwenSessionUpdateHandler {
|
|||||||
*/
|
*/
|
||||||
handleSessionUpdate(data: AcpSessionUpdate): void {
|
handleSessionUpdate(data: AcpSessionUpdate): void {
|
||||||
const update = data.update;
|
const update = data.update;
|
||||||
|
console.log(
|
||||||
|
'[SessionUpdateHandler] Processing update type:',
|
||||||
|
update.sessionUpdate,
|
||||||
|
);
|
||||||
|
|
||||||
switch (update.sessionUpdate) {
|
switch (update.sessionUpdate) {
|
||||||
case 'user_message_chunk':
|
case 'user_message_chunk':
|
||||||
|
|||||||
@@ -76,15 +76,26 @@ export class DiffManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and shows a new diff view.
|
* 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) {
|
async showDiff(filePath: string, oldContent: string, newContent: string) {
|
||||||
const fileUri = vscode.Uri.file(filePath);
|
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({
|
const rightDocUri = vscode.Uri.from({
|
||||||
scheme: DIFF_SCHEME,
|
scheme: DIFF_SCHEME,
|
||||||
path: filePath,
|
path: filePath,
|
||||||
// cache busting
|
query: `new&rand=${Math.random()}`,
|
||||||
query: `rand=${Math.random()}`,
|
|
||||||
});
|
});
|
||||||
this.diffContentProvider.setContent(rightDocUri, newContent);
|
this.diffContentProvider.setContent(rightDocUri, newContent);
|
||||||
|
|
||||||
@@ -94,26 +105,13 @@ export class DiffManager {
|
|||||||
rightDocUri,
|
rightDocUri,
|
||||||
});
|
});
|
||||||
|
|
||||||
const diffTitle = `${path.basename(filePath)} ↔ Modified`;
|
const diffTitle = `${path.basename(filePath)} (Before ↔ After)`;
|
||||||
await vscode.commands.executeCommand(
|
await vscode.commands.executeCommand(
|
||||||
'setContext',
|
'setContext',
|
||||||
'qwen.diff.isVisible',
|
'qwen.diff.isVisible',
|
||||||
true,
|
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(
|
await vscode.commands.executeCommand(
|
||||||
'vscode.diff',
|
'vscode.diff',
|
||||||
leftDocUri,
|
leftDocUri,
|
||||||
|
|||||||
@@ -177,6 +177,30 @@ export async function activate(context: vscode.ExtensionContext) {
|
|||||||
diffManager.cancelDiff(docUri);
|
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', () => {
|
vscode.commands.registerCommand('qwenCode.openChat', () => {
|
||||||
// Open or reveal the most recent chat tab
|
// Open or reveal the most recent chat tab
|
||||||
if (webViewProviders.length > 0) {
|
if (webViewProviders.length > 0) {
|
||||||
|
|||||||
@@ -437,7 +437,18 @@ const createMcpServer = (diffManager: DiffManager) => {
|
|||||||
inputSchema: OpenDiffRequestSchema.shape,
|
inputSchema: OpenDiffRequestSchema.shape,
|
||||||
},
|
},
|
||||||
async ({ filePath, newContent }: z.infer<typeof OpenDiffRequestSchema>) => {
|
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: [] };
|
return { content: [] };
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user