diff --git a/src/acp-agent.ts b/src/acp-agent.ts index 893a546c..ed3157b9 100644 --- a/src/acp-agent.ts +++ b/src/acp-agent.ts @@ -3430,7 +3430,9 @@ export class ClaudeAcpAgent { try { const cliPath = await claudeCliPath(); const args = ["auth", "status", "--json"]; - if (context?.override) args.push("--settings", JSON.stringify(context.override)); + // `--settings` is a global CLI option: after the `auth status` subcommand the CLI rejects + // it with "unknown option '--settings'", so it has to come first. + if (context?.override) args.unshift("--settings", JSON.stringify(context.override)); ({ stdout } = await execFileAsync(cliPath, args, { timeout: AUTH_STATUS_PROBE_TIMEOUT_MS, cwd: context?.manager.getCwd() ?? process.cwd(), diff --git a/src/tests/auth-status.test.ts b/src/tests/auth-status.test.ts index 2265a217..b59398bc 100644 --- a/src/tests/auth-status.test.ts +++ b/src/tests/auth-status.test.ts @@ -22,6 +22,11 @@ vi.mock("@anthropic-ai/claude-agent-sdk", async () => ({ /** Shared spy for both `claude auth status --json` and `claude auth logout`. * Tests set `execFileResults` per invoked subcommand. */ const execFileSpy = vi.hoisted(() => vi.fn()); +/** `auth status` probes, wherever global options such as `--settings` put the subcommand. */ +function isStatusProbe(args: string[]): boolean { + const auth = args.indexOf("auth"); + return auth >= 0 && args[auth + 1] === "status"; +} vi.mock("node:child_process", async () => { const actual = await vi.importActual("node:child_process"); @@ -409,7 +414,7 @@ describe("auth status over ACP", () => { execFileSpy.mockImplementation((...invocation: unknown[]) => { const args = invocation[1] as string[]; const cb = invocation[invocation.length - 1] as (...a: unknown[]) => void; - if (args[1] === "status") { + if (isStatusProbe(args)) { const stdout = statusStdout; const fails = statusFails; const answer = () => { @@ -451,7 +456,7 @@ describe("auth status over ACP", () => { }); function statusCalls() { - return execFileSpy.mock.calls.filter((call) => (call[1] as string[])[1] === "status"); + return execFileSpy.mock.calls.filter((call) => isStatusProbe(call[1] as string[])); } function updates() { @@ -542,11 +547,11 @@ describe("auth status over ACP", () => { env: { ANTHROPIC_BASE_URL: "https://example.invalid/override" }, }); expect(statusCalls().at(-1)?.[1]).toEqual([ + "--settings", + JSON.stringify({ apiKeyHelper: "central proxy start" }), "auth", "status", "--json", - "--settings", - JSON.stringify({ apiKeyHelper: "central proxy start" }), ]); await promptOnce(sessionId); await flushStatus();