Skip to content

Commit 8775b96

Browse files
committed
Drop Claude auth token helper support
- Require `claude auth login` for Claude setup - Remove helper-command settings, contracts, and picker logic - Update related error and setup copy
1 parent 3fb6de2 commit 8775b96

12 files changed

Lines changed: 21 additions & 190 deletions

File tree

apps/server/src/doctor.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,7 @@ const doctorProgram = Effect.gen(function* () {
8787
console.log("No providers are ready. Set up at least one provider to start coding:");
8888
console.log("");
8989
console.log(" Codex: npm install -g @openai/codex && codex login");
90-
console.log(
91-
" Claude Code: npm install -g @anthropic-ai/claude-code && claude auth login (or set ANTHROPIC_API_KEY / ANTHROPIC_AUTH_TOKEN)",
92-
);
90+
console.log(" Claude Code: npm install -g @anthropic-ai/claude-code && claude auth login");
9391
console.log(" Copilot: npm install -g @github/copilot && copilot login");
9492
} else if (readyCount === statuses.length) {
9593
console.log("All providers are ready.");

apps/web/src/appSettings.test.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ describe("AppSettingsSchema", () => {
2626
expect(settings.showNotificationDetails).toBe(false);
2727
expect(settings.includeDiagnosticsTipsInCopy).toBe(false);
2828
expect(settings.browserPreviewStartPageUrl).toBe("");
29-
expect(settings.claudeAuthTokenHelperCommand).toBe("");
3029
});
3130

3231
it("defaults sidebar appearance controls", () => {
@@ -64,11 +63,10 @@ describe("AppSettingsSchema", () => {
6463
});
6564

6665
describe("getProviderStartOptions", () => {
67-
it("includes the Claude auth token helper command when configured", () => {
66+
it("includes the Claude binary path when configured", () => {
6867
expect(
6968
getProviderStartOptions({
70-
claudeBinaryPath: "",
71-
claudeAuthTokenHelperCommand: "op read op://shared/anthropic/token --no-newline",
69+
claudeBinaryPath: "/usr/local/bin/claude",
7270
codexBinaryPath: "",
7371
codexHomePath: "",
7472
copilotBinaryPath: "",
@@ -78,7 +76,7 @@ describe("getProviderStartOptions", () => {
7876
}),
7977
).toEqual({
8078
claudeAgent: {
81-
authTokenHelperCommand: "op read op://shared/anthropic/token --no-newline",
79+
binaryPath: "/usr/local/bin/claude",
8280
},
8381
});
8482
});

apps/web/src/appSettings.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,6 @@ export const AppSettingsSchema = Schema.Struct({
9191
claudeBinaryPath: Schema.String.check(Schema.isMaxLength(4096)).pipe(withDefaults(() => "")),
9292
copilotBinaryPath: Schema.String.check(Schema.isMaxLength(4096)).pipe(withDefaults(() => "")),
9393
copilotConfigDir: Schema.String.check(Schema.isMaxLength(4096)).pipe(withDefaults(() => "")),
94-
claudeAuthTokenHelperCommand: Schema.String.check(Schema.isMaxLength(4096)).pipe(
95-
withDefaults(() => ""),
96-
),
9794
codexBinaryPath: Schema.String.check(Schema.isMaxLength(4096)).pipe(withDefaults(() => "")),
9895
codexHomePath: Schema.String.check(Schema.isMaxLength(4096)).pipe(withDefaults(() => "")),
9996
backgroundImageUrl: Schema.String.check(Schema.isMaxLength(4096)).pipe(withDefaults(() => "")),
@@ -265,7 +262,6 @@ function normalizeAppSettings(settings: AppSettings): AppSettings {
265262
...settings,
266263
backgroundImageUrl: settings.backgroundImageUrl.trim(),
267264
browserPreviewStartPageUrl: settings.browserPreviewStartPageUrl.trim(),
268-
claudeAuthTokenHelperCommand: settings.claudeAuthTokenHelperCommand.trim(),
269265
backgroundImageOpacity: clampBackgroundOpacity(settings.backgroundImageOpacity),
270266
sidebarOpacity: clampOpacity(settings.sidebarOpacity),
271267
sidebarProjectRowHeight: clampSidebarProjectRowHeight(settings.sidebarProjectRowHeight),
@@ -389,7 +385,6 @@ export function getProviderStartOptions(
389385
| "claudeBinaryPath"
390386
| "copilotBinaryPath"
391387
| "copilotConfigDir"
392-
| "claudeAuthTokenHelperCommand"
393388
| "codexBinaryPath"
394389
| "codexHomePath"
395390
| "openclawGatewayUrl"
@@ -405,13 +400,10 @@ export function getProviderStartOptions(
405400
},
406401
}
407402
: {}),
408-
...(settings.claudeBinaryPath || settings.claudeAuthTokenHelperCommand
403+
...(settings.claudeBinaryPath
409404
? {
410405
claudeAgent: {
411406
...(settings.claudeBinaryPath ? { binaryPath: settings.claudeBinaryPath } : {}),
412-
...(settings.claudeAuthTokenHelperCommand
413-
? { authTokenHelperCommand: settings.claudeAuthTokenHelperCommand }
414-
: {}),
415407
},
416408
}
417409
: {}),

apps/web/src/components/ChatView.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -867,9 +867,8 @@ export default function ChatView({ threadId, onMinimize }: ChatViewProps) {
867867
getSelectableThreadProviders({
868868
statuses: providerStatuses,
869869
openclawGatewayUrl: settings.openclawGatewayUrl,
870-
claudeAuthTokenHelperCommand: settings.claudeAuthTokenHelperCommand,
871870
}),
872-
[providerStatuses, settings.claudeAuthTokenHelperCommand, settings.openclawGatewayUrl],
871+
[providerStatuses, settings.openclawGatewayUrl],
873872
);
874873
const hasThreadStarted = Boolean(
875874
activeThread &&

apps/web/src/components/chat/ProviderSetupCard.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ const PROVIDER_CONFIG = {
2727
},
2828
claudeAgent: {
2929
installCmd: "npm install -g @anthropic-ai/claude-code",
30-
authCmd: "set ANTHROPIC_API_KEY or ANTHROPIC_AUTH_TOKEN",
30+
authCmd: "claude auth login",
3131
verifyCmd: "claude auth status",
32-
note: "You can also configure a Claude auth token helper command or one-click secret-manager preset in Settings.",
32+
note: "Claude Code must be installed and signed in through the CLI before it can be used.",
3333
},
3434
copilot: {
3535
installCmd: "npm install -g @github/copilot",

apps/web/src/components/chat/threadError.test.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ describe("humanizeThreadError", () => {
4848
).toBe(true);
4949
expect(
5050
isAuthenticationThreadError(
51-
"Claude is not configured with a supported Anthropic credential. Set ANTHROPIC_API_KEY or ANTHROPIC_AUTH_TOKEN and try again.",
51+
"Claude Code must be authenticated with `claude auth login` before starting a session. API key and auth token credentials are not supported.",
5252
),
5353
).toBe(true);
5454
});
@@ -81,11 +81,9 @@ describe("humanizeThreadError", () => {
8181
).toContain("Troubleshooting:");
8282
expect(
8383
buildThreadErrorDiagnosticsCopy(
84-
"Claude Code is signed in with OAuth, which is not supported here. Set ANTHROPIC_API_KEY or ANTHROPIC_AUTH_TOKEN and try again.",
84+
"Claude Code must be authenticated with `claude auth login` before starting a session. API key and auth token credentials are not supported.",
8585
{ includeTips: true },
8686
),
87-
).toContain(
88-
"Set `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN` in the runtime environment and retry the turn.",
89-
);
87+
).toContain("Run `claude auth login` and retry the turn.");
9088
});
9189
});

apps/web/src/components/chat/threadError.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ function extractWorktreeDetail(error: string): string | null {
3838
function getProviderLoginCommand(error: string): string | null {
3939
const lower = error.toLowerCase();
4040
if (lower.includes("claude")) {
41-
return "`ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN`";
41+
return "`claude auth login`";
4242
}
4343
if (lower.includes("codex")) {
4444
return "`codex login`";

apps/web/src/lib/providerAvailability.test.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,6 @@ describe("providerAvailability", () => {
4949
).toBe(false);
5050
});
5151

52-
it("allows Claude when a local auth token helper is configured", () => {
53-
expect(
54-
isProviderReadyForThreadSelection({
55-
provider: "claudeAgent",
56-
statuses: [makeStatus("claudeAgent", { status: "error", authStatus: "unauthenticated" })],
57-
claudeAuthTokenHelperCommand: "op read op://shared/anthropic/token --no-newline",
58-
}),
59-
).toBe(true);
60-
});
61-
6252
it("treats configured OpenClaw as selectable even when server auth state is unknown", () => {
6353
expect(
6454
isProviderReadyForThreadSelection({
@@ -77,9 +67,8 @@ describe("providerAvailability", () => {
7767
makeStatus("codex"),
7868
makeStatus("claudeAgent", { status: "error", authStatus: "unauthenticated" }),
7969
],
80-
claudeAuthTokenHelperCommand: "op read op://shared/anthropic/token --no-newline",
8170
}),
82-
).toEqual(["codex", "claudeAgent", "openclaw"]);
71+
).toEqual(["codex", "openclaw"]);
8372
});
8473

8574
it("falls back to the first selectable provider when the preferred one is unavailable", () => {

apps/web/src/lib/providerAvailability.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ export function isProviderReadyForThreadSelection(input: {
3131
provider: ProviderKind;
3232
statuses: ReadonlyArray<ServerProviderStatus>;
3333
openclawGatewayUrl?: string | null | undefined;
34-
claudeAuthTokenHelperCommand?: string | null | undefined;
3534
}): boolean {
3635
const status = getProviderStatusByKind(input.statuses, input.provider);
3736

@@ -46,30 +45,19 @@ export function isProviderReadyForThreadSelection(input: {
4645
return false;
4746
}
4847

49-
if (
50-
input.provider === "claudeAgent" &&
51-
(input.claudeAuthTokenHelperCommand ?? "").trim().length > 0 &&
52-
status.available &&
53-
(status.authStatus ?? status.auth?.status) === "unauthenticated"
54-
) {
55-
return true;
56-
}
57-
5848
const authStatus = status.authStatus ?? status.auth?.status;
5949
return Boolean(status.available && status.status === "ready" && authStatus !== "unauthenticated");
6050
}
6151

6252
export function getSelectableThreadProviders(input: {
6353
statuses: ReadonlyArray<ServerProviderStatus>;
6454
openclawGatewayUrl?: string | null | undefined;
65-
claudeAuthTokenHelperCommand?: string | null | undefined;
6655
}): ProviderKind[] {
6756
return THREAD_PROVIDER_ORDER.filter((provider) =>
6857
isProviderReadyForThreadSelection({
6958
provider,
7059
statuses: input.statuses,
7160
openclawGatewayUrl: input.openclawGatewayUrl,
72-
claudeAuthTokenHelperCommand: input.claudeAuthTokenHelperCommand,
7361
}),
7462
);
7563
}

0 commit comments

Comments
 (0)