- Added metadata merge helpers in `sdk/cliproxy/auth` to retain existing auth-file settings while excluding token lifecycle fields.
- Applied merge before saving in management handler and `sdk/auth.Manager.Login` so re-login overwrites credentials without discarding user-configured fields.
- Updated token save paths for Claude, Codex, Kimi, XAI, and Vertex to persist merged metadata payloads when writing auth files.
Closes: #4945
Classify malformed caller metadata and Fast failures as request-scoped, reuse the strict Anthropic origin gate, bound diagnostics and proxy caches, and remove the unrelated translator test change.
Align the remaining measured OAuth wire profiles, including the ordered
connection writer in internal/httpwire that reproduces the observed header
sequence, and the refresh/profile response shapes in internal/auth/claude.
Replay the measured Fast path and keep diagnostic continuity across cloaked and
native requests.
Preserve the native direct token-counting shape so a caller that reaches
count_tokens itself is not reshaped into the cloaked form.
Scope cloak dates to the credential's timezone rather than the host's, so
currentDate matches what the real client would have sent for that account.
A single *Auth is shared by every concurrent request that selects the same
credential, so any path reaching into Auth.Metadata directly races the others.
The credential identity helpers initialized and wrote the map outside
claudeDevicePoolMu; only EnsureDeviceIDPool took the lock, so a lazy
`auth.Metadata = make(...)` racing a pool write could abort the whole process
with "concurrent map writes" instead of failing a request.
Locking only the device-pool helpers was not enough: the account-profile and
refresh paths kept mutating the same map unguarded, which a concurrency probe
surfaced as data races. Widen the lock to the whole metadata map and route the
remaining call sites through new accessors in internal/auth/claude, including
the lazy map initialization, which needs a pointer to the field to stay inside
the critical section. claudeAccountProfileLookupDue now takes the already-read
timestamp so it cannot be handed an unsynchronized map.
Detect confirmed CLI, sdk-cli and VSCode callers before mutation so native
software, system, tool, cache and beta shapes pass through, while unconfirmed
OAuth clients receive a coherent minimum CLI identity.
Persist each Claude OAuth credential's upstream account metadata and one stable
device ID, derive one stable session per agent conversation, and keep body and
header identity synchronized across Messages, streaming and count_tokens.
Alias every cloaked third-party custom tool through caller-stable opaque MCP
names and restore declarations, choices, history, references, non-stream
responses and SSE events without changing tool ownership.
Implement the Claude Code 2.1.220 CCH algorithm over the final serialized
request bytes, align currentDate and first-user cache layout, update the
official beta/header baseline, and use upstream count_tokens for OAuth and
first-party Anthropic credentials.
Match the 2.1.220 TLS ClientHello so the transport fingerprint agrees with the
identity the request now claims, and document the CLI defaults and automatic
OAuth signing / tool alias behaviour in config.example.yaml.
- Introduce explicit per-refresh request timeouts in Codex and Claude OAuth token refresh logic.
- Ensure refresh flows use `context.WithTimeout` with `context.WithoutCancel` to avoid inheriting caller cancellation and avoid hanging refresh calls.
- Add a dedicated Claude TLS handshake timeout for utls transport creation via request context and enforce it by setting connection deadlines during handshake.
Closes: #4712
- Modified `CredentialFileName` to incorporate `hashAccountID` for better disambiguation when available.
- Updated fallback behavior to maintain compatibility with legacy email-based filenames.
- Refined test suite to validate scenarios with and without account hash and plan type.
Closes: #4425
- Updated `X-Msh-Version` and `User-Agent` headers in both `kimi.go` and `kimi_executor.go` to dynamically include the current version from `buildinfo`.
- Replaced hardcoded values with `buildinfo.Version` to ensure consistency with the build version.
- Introduced `using_api` attribute in xAI auth for toggling between official API and CLI chat-proxy paths.
- Updated `xaiChatBaseURL` and `applyXAIChatHeaders` to conditionally apply the appropriate logic based on the `using_api` value.
- Added robust handling of attribute and metadata parsing for `using_api`.
- Extended test suite to cover `using_api` scenarios, including defaults, overrides, and header behaviors.
- Replaced PKCE-based OAuth for xAI with device authorization flow for enhanced compatibility.
- Introduced cancelable OAuth sessions with server-side invalidation to prevent token persistence on flow interruption.
- Updated OAuth polling and session tracking to handle device flow specifics, such as `user_code` and extended timeouts.
- Refactored TUI OAuth model to track polling generations, distinguish device flow, and handle session cancellation gracefully.
- Extended test cases for device flow scenarios, stale session handling, and cancelation logic.
- Streamlined xAI device flow management in handler logic and improved error handling.
- Introduced `xaiChatBaseURL` helper to normalize base URLs for non-media chat requests.
- Added `applyXAIChatHeaders` to handle CLI chat-proxy-specific headers.
- Updated logic to differentiate between default, chat-proxy, and custom gateway base URLs.
- Extended test coverage to validate behavior of headers and base URL handling across scenarios.
Closes: #4182
- Updated `CredentialFileName` to include trimmed `hashAccountID` for team-scoped plans.
- Added `isTeamScopedPlan` helper to handle plan-specific logic.
- Ensured filenames are unique across emails for multiple teams.
Closes: #4075
Use the aidev_client parenthetical suffix for default Antigravity UA and
route loadCodeAssist through the short UA. Keep onboardUser on the long UA
with google-api-nodejs-client.
- Deleted `geminicli` provider and related `Apply` logic.
- Removed all translator packages specific to Gemini CLI (Claude, Codex integrations).
- Purged associated test files for Gemini CLI translation.
- Removed `GeminiAuthenticator` and all associated authentication logic (OAuth flows, token handling, refresh logic).
- Deleted internal/executor Gemini OAuth support, including bearer token handling and runtime API logic.
- Purged all tests, configs, and command-line flags specific to Gemini OAuth flows.
- Updated documentation and aliases to reflect Gemini removal.
- Renamed `parseRetryDelay` to `ParseRetryDelay` and `deleteJSONField` to `DeleteJSONField`.
- Updated references in `antigravity_executor` and tests to use the new `helps` package.
- Adjusted import paths and test cases to ensure compatibility with the new location.
- Updated README files to reflect changes in the retry logic references.
- Updated `.github/ISSUE_TEMPLATE/bug_report.md` to remove deprecated Gemini CLI mention.
- Implemented xAI OAuth2 integration with PKCE (Proof Key for Code Exchange) support.
- Added logic for token exchange, refresh, and persistent storage in JSON format.
- Created `xai` package with helpers for OAuth discovery, API token handling, and URL building.
- Introduced `XAIExecutor` for integrating xAI credentials into runtime HTTP requests.
- Added unit tests to validate OAuth flow, token persistence, and endpoint validation.
- Updated all references from v6 to v7 for `github.com/router-for-me/CLIProxyAPI`.
- Ensured consistency in imports within core libraries, tests, and integration tests.
- Added missing tests for new features in Redis Protocol integration.
- Deleted `iflow` provider implementation, including thinking configuration (`apply.go`) and authentication modules.
- Removed iFlow-specific tests, executors, and helpers across SDK and internal components.
- Updated all references to exclude iFlow functionality.
- Introduced `WithProxyURL` variants for `CodexAuth`, `ClaudeAuth`, `IFlowAuth`, and `DeviceFlowClient`.
- Updated executors to use proxy-aware constructors for improved configurability.
- Added unit tests to validate proxy override precedence and functionality.
Closes: #2823
- Deleted `QwenAuthenticator`, internal `qwen_auth`, and `qwen_executor` implementations.
- Removed all Qwen-related OAuth flows, token handling, and execution logic.
- Cleaned up dependencies and references to Qwen across the codebase.
Address two blocking issues from PR review:
- Auth file now named vertex-{prefix}-{project}.json so importing the
same project with different prefixes no longer overwrites credentials
- Prefix containing "/" is rejected at import time instead of being
silently ignored at runtime
- Add prefix to in-memory metadata map for consistency
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
feat(proxy): centralize proxy handling with `proxyutil` package and enhance test coverage
- Added `proxyutil` package to simplify proxy handling across the codebase.
- Refactored various components (`executor`, `cliproxy`, `auth`, etc.) to use `proxyutil` for consistent and reusable proxy logic.
- Introduced support for "direct" proxy mode to explicitly bypass all proxies.
- Updated tests to validate proxy behavior (e.g., `direct`, HTTP/HTTPS, and SOCKS5).
- Enhanced YAML configuration documentation for proxy options.
Captured and compared outgoing requests from CLIProxyAPI against real
Claude Code 2.1.63 and fixed all detectable differences:
Headers:
- Update anthropic-beta to match 2.1.63: replace fine-grained-tool-streaming
and prompt-caching-2024-07-31 with context-management-2025-06-27 and
prompt-caching-scope-2026-01-05
- Remove X-Stainless-Helper-Method header (real Claude Code does not send it)
- Update default User-Agent from "claude-cli/2.1.44 (external, sdk-cli)" to
"claude-cli/2.1.63 (external, cli)"
- Force Claude Code User-Agent for non-Claude clients to avoid leaking
real client identity (e.g. curl, OpenAI SDKs) during cloaking
Body:
- Inject x-anthropic-billing-header as system[0] (matches real format)
- Change system prompt identifier from "You are Claude Code..." to
"You are a Claude agent, built on Anthropic's Claude Agent SDK."
- Add cache_control with ttl:"1h" to match real request format
- Fix user_id format: user_[64hex]_account_[uuid]_session_[uuid]
(was missing account UUID)
- Disable tool name prefix (set claudeToolPrefix to empty string)
TLS:
- Switch utls fingerprint from HelloFirefox_Auto to HelloChrome_Auto
(closer to Node.js/OpenSSL used by real Claude Code)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
console.anthropic.com is now protected by a Cloudflare managed challenge
that blocks all non-browser POST requests to /v1/oauth/token, causing
`-claude-login` to fail with a 403 error.
Switch to api.anthropic.com which hosts the same OAuth token endpoint
without the Cloudflare managed challenge.
Fixes#1659
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>