qwen-code/packages/vscode-ide-companion/src/services/acpFileHandler.ts
mingholy.lmh c044d4dba1 refactor(acp): migrate to @agentclientprotocol/sdk and clean up handlers
- Replace deprecated ACP session manager with new SDK integration
- Add acpFileHandler test coverage
- Remove obsolete acpMessageHandler and acpSessionManager
- Update type definitions and connection handlers
- Apply code formatting fixes

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-06 21:57:41 +08:00

117 lines
3.6 KiB
TypeScript

/**
* @license
* Copyright 2025 Qwen Team
* SPDX-License-Identifier: Apache-2.0
*/
/**
* ACP File Operation Handler
*
* Responsible for handling file read and write operations in the ACP protocol
*/
import { promises as fs } from 'fs';
import * as path from 'path';
/**
* ACP File Operation Handler Class
* Provides file read and write functionality according to ACP protocol specifications
*/
export class AcpFileHandler {
/**
* Handle read text file request
*
* @param params - File read parameters
* @param params.path - File path
* @param params.sessionId - Session ID
* @param params.line - Starting line number (optional)
* @param params.limit - Read line limit (optional)
* @returns File content
* @throws Error when file reading fails
*/
async handleReadTextFile(params: {
path: string;
sessionId: string;
line: number | null;
limit: number | null;
}): Promise<{ content: string }> {
console.log(`[ACP] fs/read_text_file request received for: ${params.path}`);
console.log(`[ACP] Parameters:`, {
line: params.line,
limit: params.limit,
sessionId: params.sessionId,
});
try {
const content = await fs.readFile(params.path, 'utf-8');
console.log(
`[ACP] Successfully read file: ${params.path} (${content.length} bytes)`,
);
// Handle line offset and limit.
// ACP spec: `line` is 1-based (first line = 1).
if (params.line !== null || params.limit !== null) {
const lines = content.split('\n');
const startLine = Math.max(0, (params.line ?? 1) - 1);
const endLine = params.limit ? startLine + params.limit : lines.length;
const selectedLines = lines.slice(startLine, endLine);
const result = { content: selectedLines.join('\n') };
console.log(`[ACP] Returning ${selectedLines.length} lines`);
return result;
}
const result = { content };
console.log(`[ACP] Returning full file content`);
return result;
} catch (error) {
const errorMsg = error instanceof Error ? error.message : String(error);
console.error(`[ACP] Failed to read file ${params.path}:`, errorMsg);
const nodeError = error as NodeJS.ErrnoException;
if (nodeError?.code === 'ENOENT') {
throw error;
}
throw new Error(`Failed to read file '${params.path}': ${errorMsg}`);
}
}
/**
* Handle write text file request
*
* @param params - File write parameters
* @param params.path - File path
* @param params.content - File content
* @param params.sessionId - Session ID
* @returns null indicates success
* @throws Error when file writing fails
*/
async handleWriteTextFile(params: {
path: string;
content: string;
sessionId: string;
}): Promise<null> {
console.log(
`[ACP] fs/write_text_file request received for: ${params.path}`,
);
console.log(`[ACP] Content size: ${params.content.length} bytes`);
try {
// Ensure directory exists
const dirName = path.dirname(params.path);
console.log(`[ACP] Ensuring directory exists: ${dirName}`);
await fs.mkdir(dirName, { recursive: true });
// Write file
await fs.writeFile(params.path, params.content, 'utf-8');
console.log(`[ACP] Successfully wrote file: ${params.path}`);
return null;
} catch (error) {
const errorMsg = error instanceof Error ? error.message : String(error);
console.error(`[ACP] Failed to write file ${params.path}:`, errorMsg);
throw new Error(`Failed to write file '${params.path}': ${errorMsg}`);
}
}
}