Read and write files through Zed (#6169)

Co-authored-by: Agus Zubiaga <agus@zed.dev>
This commit is contained in:
Conrad Irwin
2025-08-18 16:29:45 -06:00
committed by GitHub
parent 4394b6ab4f
commit fb3ceb0da4
17 changed files with 268 additions and 50 deletions

View File

@@ -11,6 +11,7 @@ import {
FileDiscoveryService,
GlobTool,
ReadManyFilesTool,
StandardFileSystemService,
ToolRegistry,
} from '@google/gemini-cli-core';
import * as os from 'os';
@@ -56,6 +57,7 @@ describe('handleAtCommand', () => {
respectGitIgnore: true,
respectGeminiIgnore: true,
}),
getFileSystemService: () => new StandardFileSystemService(),
getEnableRecursiveFileSearch: vi.fn(() => true),
getWorkspaceContext: () => ({
isPathWithinWorkspace: () => true,

View File

@@ -0,0 +1,47 @@
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { FileSystemService } from '@google/gemini-cli-core';
import * as acp from './acp.js';
/**
* ACP client-based implementation of FileSystemService
*/
export class AcpFileSystemService implements FileSystemService {
constructor(
private readonly client: acp.Client,
private readonly sessionId: string,
private readonly capabilities: acp.FileSystemCapability,
private readonly fallback: FileSystemService,
) {}
async readTextFile(filePath: string): Promise<string> {
if (!this.capabilities.readTextFile) {
return this.fallback.readTextFile(filePath);
}
const response = await this.client.readTextFile({
path: filePath,
sessionId: this.sessionId,
line: null,
limit: null,
});
return response.content;
}
async writeTextFile(filePath: string, content: string): Promise<void> {
if (!this.capabilities.writeTextFile) {
return this.fallback.writeTextFile(filePath, content);
}
await this.client.writeTextFile({
path: filePath,
content,
sessionId: this.sessionId,
});
}
}

View File

@@ -24,6 +24,7 @@ import {
MCPServerConfig,
} from '@google/gemini-cli-core';
import * as acp from './acp.js';
import { AcpFileSystemService } from './fileSystemService.js';
import { Readable, Writable } from 'node:stream';
import { Content, Part, FunctionCall, PartListUnion } from '@google/genai';
import { LoadedSettings, SettingScope } from '../config/settings.js';
@@ -60,6 +61,7 @@ export async function runZedIntegration(
class GeminiAgent {
private sessions: Map<string, Session> = new Map();
private clientCapabilities: acp.ClientCapabilities | undefined;
constructor(
private config: Config,
@@ -70,8 +72,9 @@ class GeminiAgent {
) {}
async initialize(
_args: acp.InitializeRequest,
args: acp.InitializeRequest,
): Promise<acp.InitializeResponse> {
this.clientCapabilities = args.clientCapabilities;
const authMethods = [
{
id: AuthType.LOGIN_WITH_GOOGLE,
@@ -129,6 +132,16 @@ class GeminiAgent {
throw acp.RequestError.authRequired();
}
if (this.clientCapabilities?.fs) {
const acpFileSystemService = new AcpFileSystemService(
this.client,
sessionId,
this.clientCapabilities.fs,
config.getFileSystemService(),
);
config.setFileSystemService(acpFileSystemService);
}
const geminiClient = config.getGeminiClient();
const chat = await geminiClient.startChat();
const session = new Session(sessionId, chat, config, this.client);