chore: standardize Claude Code CLI naming (#915)

Follow-up to #915.
This commit is contained in:
Peter Steinberger
2026-01-14 20:06:32 +00:00
parent e65e5f40c9
commit fe974f420d
23 changed files with 55 additions and 54 deletions

View File

@@ -4,7 +4,8 @@
### Changes ### Changes
- Usage: add MiniMax coding plan usage tracking. - Usage: add MiniMax coding plan usage tracking.
- Auth: rename “Claude CLI” to “Claude Code CLI” in auth options. (#915) — thanks @SeanZoR. - Auth: label Claude Code CLI auth options. (#915) — thanks @SeanZoR.
- Docs: standardize Claude Code CLI naming across docs and prompts. (follow-up to #915)
### Fixes ### Fixes
- Gateway/Dev: ensure `pnpm gateway:dev` always uses the dev profile config + state (`~/.clawdbot-dev`). - Gateway/Dev: ensure `pnpm gateway:dev` always uses the dev profile config + state (`~/.clawdbot-dev`).
@@ -324,7 +325,7 @@
- Dependencies: Pi 0.40.0 bump (#543) — thanks @mcinteerj. - Dependencies: Pi 0.40.0 bump (#543) — thanks @mcinteerj.
- Build: Docker build cache layer (#605) — thanks @zknicker. - Build: Docker build cache layer (#605) — thanks @zknicker.
- Auth: enable OAuth token refresh for Claude CLI credentials (`anthropic:claude-cli`) with bidirectional sync back to Claude Code storage (file on Linux/Windows, Keychain on macOS). This allows long-running agents to operate autonomously without manual re-authentication (#654 — thanks @radek-paclt). - Auth: enable OAuth token refresh for Claude Code CLI credentials (`anthropic:claude-cli`) with bidirectional sync back to Claude Code storage (file on Linux/Windows, Keychain on macOS). This allows long-running agents to operate autonomously without manual re-authentication (#654 — thanks @radek-paclt).
## 2026.1.8 ## 2026.1.8

View File

@@ -152,7 +152,7 @@ JSON includes `auth.oauth` (warn window + profiles) and `auth.providers`
(effective auth per provider). (effective auth per provider).
Use `--check` for automation (exit `1` when missing/expired, `2` when expiring). Use `--check` for automation (exit `1` when missing/expired, `2` when expiring).
Preferred Anthropic auth is the Claude CLI setup-token (run on the gateway host): Preferred Anthropic auth is the Claude Code CLI setup-token (run on the gateway host):
```bash ```bash
claude setup-token claude setup-token

View File

@@ -47,10 +47,10 @@ API keys for daemon use: `clawdbot onboard`.
See [/start/faq](/start/faq) for details on env inheritance (`env.shellEnv`, See [/start/faq](/start/faq) for details on env inheritance (`env.shellEnv`,
`~/.clawdbot/.env`, systemd/launchd). `~/.clawdbot/.env`, systemd/launchd).
## Anthropic: Claude CLI setup-token (supported) ## Anthropic: Claude Code CLI setup-token (supported)
For Anthropic, the recommended path is an **API key**. If youre already using For Anthropic, the recommended path is an **API key**. If youre already using
Claude Code, the Claude CLI setup-token is also supported. Claude Code CLI, the setup-token flow is also supported.
Run it on the **gateway host**: Run it on the **gateway host**:
```bash ```bash
@@ -138,7 +138,7 @@ Use `--agent <id>` to target a specific agent; omit it to use the configured def
`~/.clawdbot/agents/<agentId>/agent/auth-profiles.json` when the auth store is `~/.clawdbot/agents/<agentId>/agent/auth-profiles.json` when the auth store is
loaded. loaded.
3. Refreshable OAuth profiles can be refreshed automatically on use. Static 3. Refreshable OAuth profiles can be refreshed automatically on use. Static
token profiles (including Claude CLI setup-token) are not refreshable by token profiles (including Claude Code CLI setup-token) are not refreshable by
Clawdbot. Clawdbot.
## Troubleshooting ## Troubleshooting

View File

@@ -2,7 +2,7 @@
summary: "CLI backends: text-only fallback via local AI CLIs" summary: "CLI backends: text-only fallback via local AI CLIs"
read_when: read_when:
- You want a reliable fallback when API providers fail - You want a reliable fallback when API providers fail
- You are running Claude CLI or other local AI CLIs and want to reuse them - You are running Claude Code CLI or other local AI CLIs and want to reuse them
- You need a text-only, tool-free path that still supports sessions and images - You need a text-only, tool-free path that still supports sessions and images
--- ---
# CLI backends (fallback runtime) # CLI backends (fallback runtime)
@@ -20,7 +20,7 @@ want “always works” text responses without relying on external APIs.
## Beginner-friendly quick start ## Beginner-friendly quick start
You can use Claude CLI **without any config** (Clawdbot ships a built-in default): You can use Claude Code CLI **without any config** (Clawdbot ships a built-in default):
```bash ```bash
clawdbot agent --message "hi" --model claude-cli/opus-4.5 clawdbot agent --message "hi" --model claude-cli/opus-4.5
@@ -162,7 +162,7 @@ imageMode: "repeat"
Clawdbot will write base64 images to temp files. If `imageArg` is set, those Clawdbot will write base64 images to temp files. If `imageArg` is set, those
paths are passed as CLI args. If `imageArg` is missing, Clawdbot appends the paths are passed as CLI args. If `imageArg` is missing, Clawdbot appends the
file paths to the prompt (path injection), which is enough for CLIs that auto- file paths to the prompt (path injection), which is enough for CLIs that auto-
load local files from plain paths (Claude CLI behavior). load local files from plain paths (Claude Code CLI behavior).
## Inputs / outputs ## Inputs / outputs

View File

@@ -1,14 +1,14 @@
--- ---
summary: "Use Anthropic Claude via API keys or Claude CLI auth in Clawdbot" summary: "Use Anthropic Claude via API keys or Claude Code CLI auth in Clawdbot"
read_when: read_when:
- You want to use Anthropic models in Clawdbot - You want to use Anthropic models in Clawdbot
- You want setup-token or Claude CLI auth instead of API keys - You want setup-token or Claude Code CLI auth instead of API keys
--- ---
# Anthropic (Claude) # Anthropic (Claude)
Anthropic builds the **Claude** model family and provides access via an API. Anthropic builds the **Claude** model family and provides access via an API.
In Clawdbot you can authenticate with an API key or reuse **Claude Code / Claude CLI** In Clawdbot you can authenticate with an API key or reuse **Claude Code CLI** credentials
credentials (setup-token or OAuth). (setup-token or OAuth).
## Option A: Anthropic API key ## Option A: Anthropic API key
@@ -34,9 +34,9 @@ clawdbot onboard --anthropic-api-key "$ANTHROPIC_API_KEY"
} }
``` ```
## Option B: Claude CLI (setup-token or OAuth) ## Option B: Claude Code CLI (setup-token or OAuth)
**Best for:** using your Claude subscription or existing Claude CLI login. **Best for:** using your Claude subscription or existing Claude Code CLI login.
### CLI setup ### CLI setup
@@ -44,7 +44,7 @@ clawdbot onboard --anthropic-api-key "$ANTHROPIC_API_KEY"
# Run setup-token on the gateway host (wizard can run it for you) # Run setup-token on the gateway host (wizard can run it for you)
clawdbot onboard --auth-choice setup-token clawdbot onboard --auth-choice setup-token
# Reuse Claude CLI OAuth credentials if already logged in # Reuse Claude Code CLI OAuth credentials if already logged in
clawdbot onboard --auth-choice claude-cli clawdbot onboard --auth-choice claude-cli
``` ```

View File

@@ -25,7 +25,7 @@ Looking for chat channel docs (WhatsApp/Telegram/Discord/Slack/etc.)? See [Chann
## Provider docs ## Provider docs
- [OpenAI (API + Codex)](/providers/openai) - [OpenAI (API + Codex)](/providers/openai)
- [Anthropic (API + Claude CLI)](/providers/anthropic) - [Anthropic (API + Claude Code CLI)](/providers/anthropic)
- [OpenRouter](/providers/openrouter) - [OpenRouter](/providers/openrouter)
- [Moonshot AI (Kimi)](/providers/moonshot) - [Moonshot AI (Kimi)](/providers/moonshot)
- [OpenCode Zen](/providers/opencode) - [OpenCode Zen](/providers/opencode)

View File

@@ -23,7 +23,7 @@ model as `provider/model`.
## Supported providers (starter set) ## Supported providers (starter set)
- [OpenAI (API + Codex)](/providers/openai) - [OpenAI (API + Codex)](/providers/openai)
- [Anthropic (API + Claude CLI)](/providers/anthropic) - [Anthropic (API + Claude Code CLI)](/providers/anthropic)
- [OpenRouter](/providers/openrouter) - [OpenRouter](/providers/openrouter)
- [Moonshot AI (Kimi)](/providers/moonshot) - [Moonshot AI (Kimi)](/providers/moonshot)
- [Synthetic](/providers/synthetic) - [Synthetic](/providers/synthetic)

View File

@@ -1017,11 +1017,11 @@ It means the system attempted to use the auth profile ID `anthropic:default`, bu
### Fix checklist for `No credentials found for profile "anthropic:claude-cli"` ### Fix checklist for `No credentials found for profile "anthropic:claude-cli"`
This means the run is pinned to the **Claude CLI** profile, but the Gateway This means the run is pinned to the **Claude Code CLI** profile, but the Gateway
cant find that profile in its auth store. cant find that profile in its auth store.
- **Sync the Claude CLI token on the gateway host** - **Sync the Claude Code CLI token on the gateway host**
- Run `clawdbot models status` (it loads + syncs Claude CLI credentials). - Run `clawdbot models status` (it loads + syncs Claude Code CLI credentials).
- If it still says missing: run `claude setup-token` (or `clawdbot models auth setup-token --provider anthropic`) and retry. - If it still says missing: run `claude setup-token` (or `clawdbot models auth setup-token --provider anthropic`) and retry.
- **If you want to use an API key instead** - **If you want to use an API key instead**
- Put `ANTHROPIC_API_KEY` in `~/.clawdbot/.env` on the **gateway host**. - Put `ANTHROPIC_API_KEY` in `~/.clawdbot/.env` on the **gateway host**.

View File

@@ -74,7 +74,7 @@ Tip: `--json` does **not** imply non-interactive mode. Use `--non-interactive` (
2) **Model/Auth** 2) **Model/Auth**
- **Anthropic API key (recommended)**: uses `ANTHROPIC_API_KEY` if present or prompts for a key, then saves it for daemon use. - **Anthropic API key (recommended)**: uses `ANTHROPIC_API_KEY` if present or prompts for a key, then saves it for daemon use.
- **Anthropic token (setup-token)**: run `claude setup-token` on the gateway host (the wizard can run it for you and reuse the token). - **Anthropic token (setup-token)**: run `claude setup-token` on the gateway host (the wizard can run it for you and reuse the token).
- **Anthropic OAuth (Claude CLI)**: on macOS the wizard checks Keychain item "Claude Code-credentials" (choose "Always Allow" so launchd starts don't block); on Linux/Windows it reuses `~/.claude/.credentials.json` if present. - **Anthropic OAuth (Claude Code CLI)**: on macOS the wizard checks Keychain item "Claude Code-credentials" (choose "Always Allow" so launchd starts don't block); on Linux/Windows it reuses `~/.claude/.credentials.json` if present.
- **Anthropic token (paste setup-token)**: run `claude setup-token` in your terminal, then paste the token (you can name it; blank = default). - **Anthropic token (paste setup-token)**: run `claude setup-token` in your terminal, then paste the token (you can name it; blank = default).
- **OpenAI Code (Codex) subscription (Codex CLI)**: if `~/.codex/auth.json` exists, the wizard can reuse it. - **OpenAI Code (Codex) subscription (Codex CLI)**: if `~/.codex/auth.json` exists, the wizard can reuse it.
- **OpenAI Code (Codex) subscription (OAuth)**: browser flow; paste the `code#state`. - **OpenAI Code (Codex) subscription (OAuth)**: browser flow; paste the `code#state`.

View File

@@ -157,7 +157,7 @@ pnpm clawdbot models list --json
## Live: Anthropic setup-token smoke ## Live: Anthropic setup-token smoke
- Test: `src/agents/anthropic.setup-token.live.test.ts` - Test: `src/agents/anthropic.setup-token.live.test.ts`
- Goal: verify Claude CLI setup-token (or a pasted setup-token profile) can complete an Anthropic prompt. - Goal: verify Claude Code CLI setup-token (or a pasted setup-token profile) can complete an Anthropic prompt.
- Enable: - Enable:
- `pnpm test:live` (or `CLAWDBOT_LIVE_TEST=1` if invoking Vitest directly) - `pnpm test:live` (or `CLAWDBOT_LIVE_TEST=1` if invoking Vitest directly)
- `CLAWDBOT_LIVE_SETUP_TOKEN=1` - `CLAWDBOT_LIVE_SETUP_TOKEN=1`
@@ -174,7 +174,7 @@ clawdbot models auth paste-token --provider anthropic --profile-id anthropic:set
CLAWDBOT_LIVE_SETUP_TOKEN=1 CLAWDBOT_LIVE_SETUP_TOKEN_PROFILE=anthropic:setup-token-test pnpm test:live src/agents/anthropic.setup-token.live.test.ts CLAWDBOT_LIVE_SETUP_TOKEN=1 CLAWDBOT_LIVE_SETUP_TOKEN_PROFILE=anthropic:setup-token-test pnpm test:live src/agents/anthropic.setup-token.live.test.ts
``` ```
## Live: CLI backend smoke (Claude CLI or other local CLIs) ## Live: CLI backend smoke (Claude Code CLI or other local CLIs)
- Test: `src/gateway/gateway-cli-backend.live.test.ts` - Test: `src/gateway/gateway-cli-backend.live.test.ts`
- Goal: validate the Gateway + agent pipeline using a local CLI backend, without touching your default config. - Goal: validate the Gateway + agent pipeline using a local CLI backend, without touching your default config.
@@ -195,7 +195,7 @@ CLAWDBOT_LIVE_SETUP_TOKEN=1 CLAWDBOT_LIVE_SETUP_TOKEN_PROFILE=anthropic:setup-to
- `CLAWDBOT_LIVE_CLI_BACKEND_IMAGE_ARG="--image"` to pass image file paths as CLI args instead of prompt injection. - `CLAWDBOT_LIVE_CLI_BACKEND_IMAGE_ARG="--image"` to pass image file paths as CLI args instead of prompt injection.
- `CLAWDBOT_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"` (or `"list"`) to control how image args are passed when `IMAGE_ARG` is set. - `CLAWDBOT_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"` (or `"list"`) to control how image args are passed when `IMAGE_ARG` is set.
- `CLAWDBOT_LIVE_CLI_BACKEND_RESUME_PROBE=1` to send a second turn and validate resume flow. - `CLAWDBOT_LIVE_CLI_BACKEND_RESUME_PROBE=1` to send a second turn and validate resume flow.
- `CLAWDBOT_LIVE_CLI_BACKEND_DISABLE_MCP_CONFIG=0` to keep Claude CLI MCP config enabled (default disables MCP config with a temporary empty file). - `CLAWDBOT_LIVE_CLI_BACKEND_DISABLE_MCP_CONFIG=0` to keep Claude Code CLI MCP config enabled (default disables MCP config with a temporary empty file).
Example: Example:

View File

@@ -283,7 +283,7 @@ const main = async () => {
const keychain = readClaudeCliKeychain(); const keychain = readClaudeCliKeychain();
if (keychain) { if (keychain) {
console.log( console.log(
`Claude CLI keychain: accessToken=${opts.reveal ? keychain.accessToken : mask(keychain.accessToken)} scopes=${keychain.scopes?.join(",") ?? "(unknown)"}`, `Claude Code CLI keychain: accessToken=${opts.reveal ? keychain.accessToken : mask(keychain.accessToken)} scopes=${keychain.scopes?.join(",") ?? "(unknown)"}`,
); );
const oauth = await fetchAnthropicOAuthUsage(keychain.accessToken); const oauth = await fetchAnthropicOAuthUsage(keychain.accessToken);
console.log( console.log(
@@ -291,7 +291,7 @@ const main = async () => {
); );
console.log(oauth.text.slice(0, 200).replace(/\s+/g, " ").trim()); console.log(oauth.text.slice(0, 200).replace(/\s+/g, " ").trim());
} else { } else {
console.log("Claude CLI keychain: missing/unreadable"); console.log("Claude Code CLI keychain: missing/unreadable");
} }
const anthropic = pickAnthropicTokens(store); const anthropic = pickAnthropicTokens(store);

View File

@@ -11,7 +11,7 @@ describe("external CLI credential sync", () => {
try { try {
await withTempHome( await withTempHome(
async (tempHome) => { async (tempHome) => {
// Create Claude CLI credentials // Create Claude Code CLI credentials
const claudeDir = path.join(tempHome, ".claude"); const claudeDir = path.join(tempHome, ".claude");
fs.mkdirSync(claudeDir, { recursive: true }); fs.mkdirSync(claudeDir, { recursive: true });
const claudeCreds = { const claudeCreds = {

View File

@@ -6,13 +6,13 @@ import { withTempHome } from "../../test/helpers/temp-home.js";
import { CLAUDE_CLI_PROFILE_ID, ensureAuthProfileStore } from "./auth-profiles.js"; import { CLAUDE_CLI_PROFILE_ID, ensureAuthProfileStore } from "./auth-profiles.js";
describe("external CLI credential sync", () => { describe("external CLI credential sync", () => {
it("syncs Claude CLI OAuth credentials into anthropic:claude-cli", async () => { it("syncs Claude Code CLI OAuth credentials into anthropic:claude-cli", async () => {
const agentDir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdbot-cli-sync-")); const agentDir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdbot-cli-sync-"));
try { try {
// Create a temp home with Claude CLI credentials // Create a temp home with Claude Code CLI credentials
await withTempHome( await withTempHome(
async (tempHome) => { async (tempHome) => {
// Create Claude CLI credentials with refreshToken (OAuth) // Create Claude Code CLI credentials with refreshToken (OAuth)
const claudeDir = path.join(tempHome, ".claude"); const claudeDir = path.join(tempHome, ".claude");
fs.mkdirSync(claudeDir, { recursive: true }); fs.mkdirSync(claudeDir, { recursive: true });
const claudeCreds = { const claudeCreds = {
@@ -59,12 +59,12 @@ describe("external CLI credential sync", () => {
fs.rmSync(agentDir, { recursive: true, force: true }); fs.rmSync(agentDir, { recursive: true, force: true });
} }
}); });
it("syncs Claude CLI credentials without refreshToken as token type", async () => { it("syncs Claude Code CLI credentials without refreshToken as token type", async () => {
const agentDir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdbot-cli-token-sync-")); const agentDir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdbot-cli-token-sync-"));
try { try {
await withTempHome( await withTempHome(
async (tempHome) => { async (tempHome) => {
// Create Claude CLI credentials WITHOUT refreshToken (fallback to token type) // Create Claude Code CLI credentials WITHOUT refreshToken (fallback to token type)
const claudeDir = path.join(tempHome, ".claude"); const claudeDir = path.join(tempHome, ".claude");
fs.mkdirSync(claudeDir, { recursive: true }); fs.mkdirSync(claudeDir, { recursive: true });
const claudeCreds = { const claudeCreds = {

View File

@@ -10,12 +10,12 @@ import {
} from "./auth-profiles.js"; } from "./auth-profiles.js";
describe("external CLI credential sync", () => { describe("external CLI credential sync", () => {
it("upgrades token to oauth when Claude CLI gets refreshToken", async () => { it("upgrades token to oauth when Claude Code CLI gets refreshToken", async () => {
const agentDir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdbot-cli-upgrade-")); const agentDir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdbot-cli-upgrade-"));
try { try {
await withTempHome( await withTempHome(
async (tempHome) => { async (tempHome) => {
// Create Claude CLI credentials with refreshToken // Create Claude Code CLI credentials with refreshToken
const claudeDir = path.join(tempHome, ".claude"); const claudeDir = path.join(tempHome, ".claude");
fs.mkdirSync(claudeDir, { recursive: true }); fs.mkdirSync(claudeDir, { recursive: true });
fs.writeFileSync( fs.writeFileSync(

View File

@@ -53,7 +53,7 @@ function isExternalProfileFresh(cred: AuthProfileCredential | undefined, now: nu
} }
/** /**
* Sync OAuth credentials from external CLI tools (Claude CLI, Codex CLI) into the store. * Sync OAuth credentials from external CLI tools (Claude Code CLI, Codex CLI) into the store.
* This allows clawdbot to use the same credentials as these tools without requiring * This allows clawdbot to use the same credentials as these tools without requiring
* separate authentication, and keeps credentials in sync when CLI tools refresh tokens. * separate authentication, and keeps credentials in sync when CLI tools refresh tokens.
* *
@@ -66,7 +66,7 @@ export function syncExternalCliCredentials(
let mutated = false; let mutated = false;
const now = Date.now(); const now = Date.now();
// Sync from Claude CLI (supports both OAuth and Token credentials) // Sync from Claude Code CLI (supports both OAuth and Token credentials)
const existingClaude = store.profiles[CLAUDE_CLI_PROFILE_ID]; const existingClaude = store.profiles[CLAUDE_CLI_PROFILE_ID];
const shouldSyncClaude = const shouldSyncClaude =
!existingClaude || !existingClaude ||

View File

@@ -66,7 +66,7 @@ async function refreshOAuthTokenWithLock(params: {
}; };
saveAuthProfileStore(store, params.agentDir); saveAuthProfileStore(store, params.agentDir);
// Sync refreshed credentials back to Claude CLI if this is the claude-cli profile // Sync refreshed credentials back to Claude Code CLI if this is the claude-cli profile
// This ensures Claude Code continues to work after ClawdBot refreshes the token // This ensures Claude Code continues to work after ClawdBot refreshes the token
if (params.profileId === CLAUDE_CLI_PROFILE_ID && cred.provider === "anthropic") { if (params.profileId === CLAUDE_CLI_PROFILE_ID && cred.provider === "anthropic") {
writeClaudeCliCredentials(result.newCredentials); writeClaudeCliCredentials(result.newCredentials);

View File

@@ -111,7 +111,7 @@ describe("cli credentials", () => {
expect(updated.claudeAiOauth?.expiresAt).toBeTypeOf("number"); expect(updated.claudeAiOauth?.expiresAt).toBeTypeOf("number");
}); });
it("caches Claude CLI credentials within the TTL window", async () => { it("caches Claude Code CLI credentials within the TTL window", async () => {
execSyncMock.mockImplementation(() => execSyncMock.mockImplementation(() =>
JSON.stringify({ JSON.stringify({
claudeAiOauth: { claudeAiOauth: {
@@ -142,7 +142,7 @@ describe("cli credentials", () => {
expect(execSyncMock).toHaveBeenCalledTimes(1); expect(execSyncMock).toHaveBeenCalledTimes(1);
}); });
it("refreshes Claude CLI credentials after the TTL window", async () => { it("refreshes Claude Code CLI credentials after the TTL window", async () => {
execSyncMock.mockImplementation(() => execSyncMock.mockImplementation(() =>
JSON.stringify({ JSON.stringify({
claudeAiOauth: { claudeAiOauth: {

View File

@@ -15,7 +15,7 @@ describe("buildAuthChoiceOptions", () => {
expect(options.find((opt) => opt.value === "github-copilot")).toBeDefined(); expect(options.find((opt) => opt.value === "github-copilot")).toBeDefined();
}); });
it("includes Claude CLI option on macOS even when missing", () => { it("includes Claude Code CLI option on macOS even when missing", () => {
const store: AuthProfileStore = { version: 1, profiles: {} }; const store: AuthProfileStore = { version: 1, profiles: {} };
const options = buildAuthChoiceOptions({ const options = buildAuthChoiceOptions({
store, store,
@@ -29,7 +29,7 @@ describe("buildAuthChoiceOptions", () => {
expect(claudeCli?.hint).toBe("requires Keychain access"); expect(claudeCli?.hint).toBe("requires Keychain access");
}); });
it("skips missing Claude CLI option off macOS", () => { it("skips missing Claude Code CLI option off macOS", () => {
const store: AuthProfileStore = { version: 1, profiles: {} }; const store: AuthProfileStore = { version: 1, profiles: {} };
const options = buildAuthChoiceOptions({ const options = buildAuthChoiceOptions({
store, store,
@@ -41,7 +41,7 @@ describe("buildAuthChoiceOptions", () => {
expect(options.find((opt) => opt.value === "claude-cli")).toBeUndefined(); expect(options.find((opt) => opt.value === "claude-cli")).toBeUndefined();
}); });
it("uses token hint when Claude CLI credentials exist", () => { it("uses token hint when Claude Code CLI credentials exist", () => {
const store: AuthProfileStore = { const store: AuthProfileStore = {
version: 1, version: 1,
profiles: { profiles: {

View File

@@ -28,10 +28,10 @@ export async function applyAuthChoiceAnthropic(
'Choose "Always Allow" so the launchd gateway can start without prompts.', 'Choose "Always Allow" so the launchd gateway can start without prompts.',
'If you choose "Allow" or "Deny", each restart will block on a Keychain alert.', 'If you choose "Allow" or "Deny", each restart will block on a Keychain alert.',
].join("\n"), ].join("\n"),
"Claude CLI Keychain", "Claude Code CLI Keychain",
); );
const proceed = await params.prompter.confirm({ const proceed = await params.prompter.confirm({
message: "Check Keychain for Claude CLI credentials now?", message: "Check Keychain for Claude Code CLI credentials now?",
initialValue: true, initialValue: true,
}); });
if (!proceed) return { config: nextConfig }; if (!proceed) return { config: nextConfig };
@@ -74,9 +74,9 @@ export async function applyAuthChoiceAnthropic(
if (!refreshed.profiles[CLAUDE_CLI_PROFILE_ID]) { if (!refreshed.profiles[CLAUDE_CLI_PROFILE_ID]) {
await params.prompter.note( await params.prompter.note(
process.platform === "darwin" process.platform === "darwin"
? 'No Claude CLI credentials found in Keychain ("Claude Code-credentials") or ~/.claude/.credentials.json.' ? 'No Claude Code CLI credentials found in Keychain ("Claude Code-credentials") or ~/.claude/.credentials.json.'
: "No Claude CLI credentials found at ~/.claude/.credentials.json.", : "No Claude Code CLI credentials found at ~/.claude/.credentials.json.",
"Claude CLI OAuth", "Claude Code CLI OAuth",
); );
return { config: nextConfig }; return { config: nextConfig };
} }
@@ -137,7 +137,7 @@ export async function applyAuthChoiceAnthropic(
}); });
if (!store.profiles[CLAUDE_CLI_PROFILE_ID]) { if (!store.profiles[CLAUDE_CLI_PROFILE_ID]) {
await params.prompter.note( await params.prompter.note(
`No Claude CLI credentials found after setup-token. Expected ${CLAUDE_CLI_PROFILE_ID}.`, `No Claude Code CLI credentials found after setup-token. Expected ${CLAUDE_CLI_PROFILE_ID}.`,
"Anthropic setup-token", "Anthropic setup-token",
); );
return { config: nextConfig }; return { config: nextConfig };

View File

@@ -83,7 +83,7 @@ export async function modelsAuthSetupTokenCommand(
const synced = store.profiles[CLAUDE_CLI_PROFILE_ID]; const synced = store.profiles[CLAUDE_CLI_PROFILE_ID];
if (!synced) { if (!synced) {
throw new Error( throw new Error(
`No Claude CLI credentials found after setup-token. Expected auth profile ${CLAUDE_CLI_PROFILE_ID}.`, `No Claude Code CLI credentials found after setup-token. Expected auth profile ${CLAUDE_CLI_PROFILE_ID}.`,
); );
} }

View File

@@ -261,8 +261,8 @@ export async function applyNonInteractiveAuthChoice(params: {
if (!store.profiles[CLAUDE_CLI_PROFILE_ID]) { if (!store.profiles[CLAUDE_CLI_PROFILE_ID]) {
runtime.error( runtime.error(
process.platform === "darwin" process.platform === "darwin"
? 'No Claude CLI credentials found. Run interactive onboarding to approve Keychain access for "Claude Code-credentials".' ? 'No Claude Code CLI credentials found. Run interactive onboarding to approve Keychain access for "Claude Code-credentials".'
: "No Claude CLI credentials found at ~/.claude/.credentials.json", : "No Claude Code CLI credentials found at ~/.claude/.credentials.json",
); );
runtime.exit(1); runtime.exit(1);
return null; return null;

View File

@@ -111,7 +111,7 @@ async function resolveOAuthToken(params: {
provider: params.provider, provider: params.provider,
}); });
// Claude CLI creds are the only Anthropic tokens that reliably include the // Claude Code CLI creds are the only Anthropic tokens that reliably include the
// `user:profile` scope required for the OAuth usage endpoint. // `user:profile` scope required for the OAuth usage endpoint.
const candidates = params.provider === "anthropic" ? [CLAUDE_CLI_PROFILE_ID, ...order] : order; const candidates = params.provider === "anthropic" ? [CLAUDE_CLI_PROFILE_ID, ...order] : order;
const deduped: string[] = []; const deduped: string[] = [];

View File

@@ -126,7 +126,7 @@ export async function fetchClaudeUsage(
// ignore parse errors // ignore parse errors
} }
// Claude CLI setup-token yields tokens that can be used for inference, but may not // Claude Code CLI setup-token yields tokens that can be used for inference, but may not
// include user:profile scope required by the OAuth usage endpoint. When a claude.ai // include user:profile scope required by the OAuth usage endpoint. When a claude.ai
// browser sessionKey is available, fall back to the web API. // browser sessionKey is available, fall back to the web API.
if (res.status === 403 && message?.includes("scope requirement user:profile")) { if (res.status === 403 && message?.includes("scope requirement user:profile")) {