From d18bfe90475e851347f91ff2003288354ce9dd52 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Wed, 13 May 2026 16:34:49 +0800 Subject: [PATCH] Add local settings to Claude configuration (#977) --- .../agent/providers/claude/agent.test.ts | 35 +++++++++++++++++++ .../server/agent/providers/claude/agent.ts | 6 +++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/packages/server/src/server/agent/providers/claude/agent.test.ts b/packages/server/src/server/agent/providers/claude/agent.test.ts index 1bafc7015..79d116ef8 100644 --- a/packages/server/src/server/agent/providers/claude/agent.test.ts +++ b/packages/server/src/server/agent/providers/claude/agent.test.ts @@ -380,6 +380,41 @@ describe("ClaudeAgentClient.listModels", () => { describe("ClaudeAgentClient binary resolution", () => { const logger = createTestLogger(); + test("loads user, project, and local Claude settings", async () => { + const queryReturn = vi.fn(); + queryReturn.mockResolvedValue(undefined); + const queryFactory = vi.fn(() => ({ + close: vi.fn(), + return: queryReturn, + })); + + const client = new ClaudeAgentClient({ + logger, + queryFactory, + resolveBinary: async () => "/test/claude/bin", + }); + const session = await client.createSession({ + provider: "claude", + cwd: process.cwd(), + }); + + await expect( + ( + session as unknown as { + ensureQuery(): Promise; + } + ).ensureQuery(), + ).resolves.toBeDefined(); + + expect(queryFactory.mock.calls[0]?.[0].options.settingSources).toEqual([ + "user", + "project", + "local", + ]); + + await session.close(); + }); + test("uses the replace-command override binary when claude is not on PATH", async () => { const customClaudePath = "/path/to/custom-claude"; vi.spyOn(executableUtils, "findExecutable").mockImplementation(async (name: string) => { diff --git a/packages/server/src/server/agent/providers/claude/agent.ts b/packages/server/src/server/agent/providers/claude/agent.ts index ededd5b60..170094bd1 100644 --- a/packages/server/src/server/agent/providers/claude/agent.ts +++ b/packages/server/src/server/agent/providers/claude/agent.ts @@ -83,7 +83,11 @@ import { execCommand } from "../../../../utils/spawn.js"; import { getOrchestratorModeInstructions } from "../../orchestrator-instructions.js"; const fsPromises = promises; -const CLAUDE_SETTING_SOURCES: NonNullable = ["user", "project"]; +const CLAUDE_SETTING_SOURCES: NonNullable = [ + "user", + "project", + "local", +]; function readNonEmptyString(value: unknown): string | null { return typeof value === "string" && value.trim().length > 0 ? value : null;