summaryrefslogtreecommitdiff
path: root/packages/cli/src
diff options
context:
space:
mode:
authorConrad Irwin <[email protected]>2025-08-18 16:29:45 -0600
committerGitHub <[email protected]>2025-08-18 22:29:45 +0000
commitfb3ceb0da4e2cd636013c2c36a9c0016c01aa47f (patch)
tree7aa43846dd88bd5acdb8898b0ccd2e685f2d5ece /packages/cli/src
parent4394b6ab4fc86637b07fcd26b9a790c627d1e065 (diff)
Read and write files through Zed (#6169)
Co-authored-by: Agus Zubiaga <[email protected]>
Diffstat (limited to 'packages/cli/src')
-rw-r--r--packages/cli/src/ui/hooks/atCommandProcessor.test.ts2
-rw-r--r--packages/cli/src/zed-integration/fileSystemService.ts47
-rw-r--r--packages/cli/src/zed-integration/zedIntegration.ts15
3 files changed, 63 insertions, 1 deletions
diff --git a/packages/cli/src/ui/hooks/atCommandProcessor.test.ts b/packages/cli/src/ui/hooks/atCommandProcessor.test.ts
index 583c0b2e..5509d9ff 100644
--- a/packages/cli/src/ui/hooks/atCommandProcessor.test.ts
+++ b/packages/cli/src/ui/hooks/atCommandProcessor.test.ts
@@ -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,
diff --git a/packages/cli/src/zed-integration/fileSystemService.ts b/packages/cli/src/zed-integration/fileSystemService.ts
new file mode 100644
index 00000000..deb9857f
--- /dev/null
+++ b/packages/cli/src/zed-integration/fileSystemService.ts
@@ -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,
+ });
+ }
+}
diff --git a/packages/cli/src/zed-integration/zedIntegration.ts b/packages/cli/src/zed-integration/zedIntegration.ts
index 1b5baa8a..6adaeb70 100644
--- a/packages/cli/src/zed-integration/zedIntegration.ts
+++ b/packages/cli/src/zed-integration/zedIntegration.ts
@@ -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);