Files
openclaw/extensions/anthropic/cli-auth-seam.test.ts
Peter Steinberger fee4e77d91 fix(anthropic): native Claude models show incorrect availability (#129346)
* fix(anthropic): verify native Claude login before publishing runtime auth

* fix(status): preserve native Claude CLI authentication labels

* refactor(gateway): remove retired native Claude auth projection

* fix(plugin-sdk): retain Claude compatibility types

Keep the released Claude CLI credential reader source-compatible through its documented v2026.10 retirement window and explicitly account for both retained type exports in the public SDK budget.

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>

* fix(plugin-sdk): preserve only shipped Claude compatibility exports

* fix(ci): align Claude native-auth contracts

Retire Doctor fixtures for credentials now owned by Claude CLI and remove the two never-shipped compatibility type exports while retaining the shipped reader through its documented v2026.10 window.

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>

* test(onboard): remove retired Claude credential file fixture

* fix(auth): skip incompatible profiles before plugin discovery

* fix(auth): avoid cold plugin activation for retired profiles

* test: repair upstream doctor and learning regressions

* fix(onboard): validate authored aliases without plugin discovery

* fix(agents): resolve compaction aliases without plugin discovery

* test(ui): register pairing sidebar before lifecycle teardown

* fix(anthropic): keep provider policy imports runtime-free

* test(vitest): cover codex startup retry test family

* fix(agents): avoid plugin discovery for internal sessions

---------

Co-authored-by: roboclaw-bot <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-08-25 14:42:08 -07:00

55 lines
1.6 KiB
TypeScript

import { beforeEach, expect, it, vi } from "vitest";
const { spawnSync } = vi.hoisted(() => ({
spawnSync: vi.fn(),
}));
vi.mock("node:child_process", () => ({ spawnSync }));
const { probeClaudeCliAuthStatus } = await import("./cli-auth-seam.js");
beforeEach(() => {
spawnSync.mockReset();
});
it("asks Claude CLI to verify its own login", () => {
spawnSync.mockReturnValue({
status: 0,
stdout: JSON.stringify({ loggedIn: true, authMethod: "claude.ai" }),
});
expect(probeClaudeCliAuthStatus()).toEqual({ status: "available" });
expect(spawnSync).toHaveBeenCalledWith(
"claude",
["auth", "status", "--json"],
expect.objectContaining({ timeout: 3_000 }),
);
});
it("does not inspect Claude token storage when the CLI reports logout", () => {
spawnSync.mockReturnValue({ status: 1, stdout: "" });
expect(probeClaudeCliAuthStatus()).toEqual({ status: "missing" });
});
it("keeps the selected native-login root while removing inherited provider credentials", () => {
spawnSync.mockReturnValue({ status: 0, stdout: JSON.stringify({ loggedIn: true }) });
expect(
probeClaudeCliAuthStatus({
command: "/custom/claude",
env: {
ANTHROPIC_API_KEY: "synthetic-ignored-api-key",
CLAUDE_CODE_OAUTH_TOKEN: "synthetic-ignored-token",
CLAUDE_CONFIG_DIR: "/tmp/selected-claude-account",
},
}),
).toEqual({ status: "available" });
expect(spawnSync).toHaveBeenCalledWith(
"/custom/claude",
["auth", "status", "--json"],
expect.objectContaining({ env: { CLAUDE_CONFIG_DIR: "/tmp/selected-claude-account" } }),
);
});