Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
367 changes: 336 additions & 31 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ ratatui = "0.29"
crossterm = "0.28"
jiff = { version = "0.2", default-features = false, features = ["std", "tz-system", "tzdb-zoneinfo"] }
tiktoken-rs = { version = "0.12", default-features = false }
jsonschema = { version = "=0.59.0", default-features = false, features = ["idna"] }

[dev-dependencies]
tokio = { version = "1", features = ["test-util"] }
Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,19 @@ The opt-in Images API returns base64 image data and consumes the signed-in accou
Run `claude-code-proxy models` for the current catalog or
`claude-code-proxy models --full` for every dynamic Cursor alias.

An additional **experimental, default-off native Antigravity Argon adapter** supports
only `antigravity/gemini-4-argon-low`, `antigravity/gemini-4-argon-medium`, and
`antigravity/gemini-4-argon-high`. It does not run or import credentials from `agy`.
Its default HTTP User-Agent is `claude-code-proxy/<package version>`. An explicit
provider-specific override affects only native generation/project discovery,
not OAuth; it is compatibility metadata, not verified official-client identity.
Use a fresh session for every model/tier/profile change. Real Google OAuth,
entitlement, native tool round trips and all three tiers remain live-validation
gates; offline tests are not evidence of account access. See the
[Antigravity limitations](docs/src/content/docs/reference/compatibility-and-limitations.md#experimental-native-antigravity-argon)
and [configuration](docs/src/content/docs/reference/configuration.md#experimental-antigravity)
before explicitly enabling it. Existing provider defaults and aliases are unchanged.

> [!WARNING]
> The proxy accepts local requests without client authentication. It binds to
> `127.0.0.1` by default. Protect any non-loopback listener with a firewall or
Expand Down
21 changes: 20 additions & 1 deletion docs/src/content/docs/reference/command-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ claude-code-proxy <provider> auth <action>
| `kimi` | Device code | Unsupported | User, expiry, scope, storage | Delete proxy credential |
| `grok` | Browser PKCE | Device code | Expiry and storage | Delete proxy credential |
| `cursor` | Browser polling flow | Unsupported | Source, claims, expiry | Delete proxy credential |
| `antigravity` (experimental) | Explicit browser PKCE | Unsupported | Safe local readiness, optional `--json` | Delete only Antigravity credential |

Examples:

Expand All @@ -80,7 +81,25 @@ claude-code-proxy kimi auth status
claude-code-proxy cursor auth logout
```

A missing credential makes `auth status` exit with status 1. Other provider command failures exit with status 2. Successful commands exit with status 0.
For existing providers, a missing credential makes `auth status` exit with status 1. Other provider command failures exit with status 2. Successful commands exit with status 0.

Antigravity auth commands work even while inference is disabled:

```sh
claude-code-proxy antigravity auth status --json
claude-code-proxy antigravity auth login
claude-code-proxy antigravity auth logout
```

Configure your installed-app client ID before explicit login; see
[Antigravity configuration](/reference/configuration/#experimental-antigravity).
`status --json` is Antigravity-only and emits schema version 1, `provider:
antigravity`, plus the safe provider descriptor documented under
[model discovery](/reference/http-api/#get-v1models). A successfully emitted
report exits 0 even for missing/invalid/unready credentials. Inspection performs
no network, refresh, directory creation or writes. CLI readiness describes this
CLI's configuration, not a different running proxy, and never proves live access.
Auth invocation failures exit nonzero. No existing provider gains a `--json` flag.

Logout removes the local proxy-owned credential. It does not call the provider to revoke a refresh token.

Expand Down
242 changes: 242 additions & 0 deletions docs/src/content/docs/reference/compatibility-and-limitations.md

Large diffs are not rendered by default.

105 changes: 103 additions & 2 deletions docs/src/content/docs/reference/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ These settings configure the proxy process. Claude Code client settings such as
}
```

All keys are optional. An unreadable file, malformed JSON, or incompatible field type causes the file configuration to be ignored and built-in or environment values to apply.
All keys are optional. For existing providers, an unreadable file, malformed JSON, or incompatible field type causes the file configuration to be ignored and built-in or environment values to apply. The experimental Antigravity adapter instead fails closed on invalid configuration; discovery reports bounded status enums without raw parse errors.

## Core and diagnostics

Expand All @@ -74,7 +74,7 @@ All keys are optional. An unreadable file, malformed JSON, or incompatible field

`CCP_CONFIG_DIR` affects `config.json` and file-backed provider auth. It does not relocate the state directory.

Codex auto-review classifier requests use `gpt-6-luna` by default. Requests routed through other providers retain their requested model. `CCP_AUTO_REVIEW_MODEL` or `autoReviewModel` selects an explicit registered model for all detected classifier requests without changing the session's provider affinity. Normal messages, streaming requests, tool-using requests, and token counting retain their requested model.
Codex auto-review classifier requests use `gpt-6-luna` by default. Requests routed through other providers retain their requested model. `CCP_AUTO_REVIEW_MODEL` or `autoReviewModel` selects an explicit registered model for detected classifier requests without changing the session's provider affinity. **Exception:** explicit Antigravity requests ignore cross-provider auto-review overrides. Same-provider overrides still undergo exact replay/model validation; changing tiers with signed history is rejected. Normal messages, streaming requests, tool-using requests, and token counting retain their requested model.

## Outbound proxies

Expand Down Expand Up @@ -155,6 +155,107 @@ Proxy URLs may use `http`, `https`, `socks4`, `socks4a`, `socks5`, or `socks5h`.
| `CCP_CURSOR_AGENT_BUNDLE` | `cursor.agentBundle` | Auto-detected | Points to Cursor Agent's bundled `index.js` protobuf schemas. |
| `CCP_CURSOR_AUTH_TOKEN` | none | unset | Uses a bearer token instead of proxy-owned Cursor auth storage. |

## Experimental Antigravity

Disabled by default. This native Argon adapter is unofficial, not generic Gemini API
support and not a promise of Google account entitlement. Authentication commands
remain available while disabled. Do not enable it in a production session before
separate real-account OAuth/native smoke validation.

| Environment | Config key | Default | Purpose |
| --- | --- | --- | --- |
| `CCP_ANTIGRAVITY_ENABLED` | `antigravity.enabled` | `false` | Explicit opt-in. Environment accepts only `1`/`true` or `0`/`false`; file value is boolean. |
| `CCP_ANTIGRAVITY_CLIENT_ID` | `antigravity.clientId` | unset | Your public installed-app OAuth client ID; required for login and refresh. |
| `CCP_ANTIGRAVITY_CLIENT_SECRET` | `antigravity.clientSecret` | unset | Optional public-client application secret, when required by that registered application. Not a user bearer token. |
| `CCP_ANTIGRAVITY_PROJECT_ID` | `antigravity.projectId` | stored discovery result | Your authorized project; no borrowed project or automatic onboarding. |
| `CCP_ANTIGRAVITY_BASE_URL` | `antigravity.baseUrl` | `https://cloudcode-pa.googleapis.com` | Explicit trusted HTTPS origin override. No userinfo, query, fragment, or path. Never automatically falls back to another endpoint. |
| `CCP_ANTIGRAVITY_USER_AGENT` | `antigravity.userAgent` | `claude-code-proxy/<package version>` | Full HTTP User-Agent override for native generation and `loadCodeAssist` only. OAuth token exchange/refresh always retain the default proxy identity. |

Remote endpoints require HTTPS, redirects are never followed, and OAuth endpoints
are fixed to `https://accounts.google.com/o/oauth2/v2/auth` and
`https://oauth2.googleapis.com/token`. Plain loopback HTTP endpoints exist only as
injected test fixtures, not environment/config options. By default every HTTP
request sent by this adapter uses exactly `claude-code-proxy/<package version>`, with no
platform suffix. A provider-specific User-Agent override replaces that header only
on native generation (both streaming and nonstreaming frontend requests) and
`loadCodeAssist` project discovery, never OAuth code exchange or refresh. Incoming
client User-Agent, authorization and cookies are not forwarded. JSON product
selectors `userAgent: antigravity` and `requestType: agent` are unchanged.

Override precedence is `CCP_ANTIGRAVITY_USER_AGENT`, then `antigravity.userAgent`,
then the proxy default. Neither `CCP_USER_AGENT` nor Codex settings are inherited.
Presence selects the environment override even when empty; invalid values fail
configuration rather than falling back, including while the provider is disabled.
Invalid native configuration removes Antigravity readiness/advertisement; it does
not disable other providers or prevent the proxy listener from starting. Auth
status still exits successfully with a report of `configuration: invalid` and
`configuration_ready: false`; report success does not establish readiness.
The file field must be a string. The selected value must contain 1–4096 printable
ASCII bytes (`0x20`–`0x7e`), with no leading/trailing space, tabs, control bytes or
non-ASCII characters. Non-UTF8 environment values are rejected by the native
validator even though this dedicated setting is excluded from legacy UTF-8
snapshots. Unix key matching is exact; Windows covers ASCII case variants.
Unrelated non-Unicode environment entries remain unsupported and fail with a
fixed error, rather than being silently discarded. Valid bytes,
including interior spacing, are preserved exactly: no trimming, suffix appending,
version/changelist rewriting or platform substitution. Raw values are omitted from
status/errors and marked sensitive in HTTP diagnostics. Do not put credentials in
a User-Agent; it is sent to the configured trusted native API origin.

An explicit compatibility override may use this pinned historical value:

```text
antigravity/cli/1.3.5 (aidev_client; os_type=darwin; arch=arm64; cl=998863838; auth_method=consumer)
```

Set it as the full provider-specific environment or file value only when desired;
it is **not the default** and does not enable the provider. These literal platform
and consumer-profile tokens are caller-selected compatibility metadata, not a
claim about the host or a verified account classification. They are not normalized
to the host. The pinned public reference records CLI 1.3.5 generation on
Darwin/arm64 and uses the same formatter for project discovery. Exact CLI 1.4.2
identification, current official-client equivalence, live acceptance and provider
policy/terms compatibility remain unverified. No runtime `agy` probing, credential
import, device identity or attestation fabrication is performed. User-Agent is not
authentication or evidence of entitlement; see the
[reference evidence](/reference/compatibility-and-limitations/#evidence-and-remaining-gates).

Login requests explicit browser consent, offline access, PKCE S256, independent
one-time state, and an ephemeral `127.0.0.1` callback. The reference-protocol scopes
are `https://www.googleapis.com/auth/` followed by `cloud-platform`, `userinfo.email`,
`userinfo.profile`, `cclog`, and `experimentsandconfigs`. These are reference
compatibility scopes, not independently proven minimal scopes. No `agy`, Gemini,
Codex, keychain or other application's credentials are discovered or imported.

Only `CCP_CONFIG_DIR/antigravity/auth.json` is used. Atomic private writes use mode
0600 on Unix, under a mode-0700 provider directory. A stable sibling `auth.lock`
coordinates login/logout/refresh across processes; logout never removes that
lock. Missing, invalid and unreadable storage remain distinct. Local logout resolves
this exact store path independently of transport settings, so malformed JSON or
an invalid API URL or User-Agent does not prevent deleting this provider's credential. It does
not remove another provider's state.

Refresh preserves the profile ID and retains the old refresh token when rotation
is omitted. A bounded manager-owned, single-flight transaction acquires the stable
lock **before** contacting OAuth. Cancelling an inference waiter cannot discard a
completed rotation: credential maintenance may finish after disconnection, but
never starts or continues model generation. The 30-second network phase ends
before validated replacement persistence. Filesystem writes are synchronous and
are not claimed cancellable by that timer.

If persistence fails, the manager retains the replacement in memory, scoped to
the profile, lock epoch and superseded refresh token, and reports a typed pending-
persistence error. Subsequent requests retry the local write, not the obsolete
token. Logout/new login or a different committed refresh token invalidates that
pending scope. An ambiguous network timeout/error requires explicit login rather
than automatically reusing a potentially consumed token. Graceful server shutdown
joins owned maintenance and attempts only pending local persistence; it performs
no new refresh or inference. Forced process termination/crashes between remote
rotation and durable storage are not covered by this in-memory recovery. Google's
immediate refresh-token invalidation behavior remains unverified.

A new login changes the profile and invalidates prior session replay.

## Shared compatibility fallbacks

`CCP_USER_AGENT` is the fallback when a Codex or Kimi provider-specific user-agent is absent. Prefer `CCP_CODEX_USER_AGENT` or `CCP_KIMI_USER_AGENT` in durable configuration.
Expand Down
51 changes: 51 additions & 0 deletions docs/src/content/docs/reference/http-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,57 @@ Returns Anthropic-shaped model discovery:

An optional `limit` query truncates `data` and sets `has_more`. The route does not expose a pagination cursor.

Optional `include_capabilities=true` adds the following safe descriptor while
retaining the normal fields. Without this query, the default-off catalog JSON
and all existing provider entries are unchanged.

```json
{
"capabilities": {
"schema_version": 1,
"providers": {
"antigravity": {
"supported": true,
"enabled": false,
"mode": "native",
"experimental": true,
"supported_apis": ["messages", "count_tokens"],
"session_policy": "fixed-model",
"context_window": 200000,
"backend_window_verified": false,
"status": {
"configuration": "valid",
"auth": "missing",
"project": "missing",
"configuration_ready": false,
"live_verified": false
}
}
}
}
}
```

`configuration` is `valid|invalid`; `auth` is
`missing|invalid|unreadable|ready|refresh_required|login_required`; `project` is
`missing|configured`. `configuration_ready` requires valid local configuration,
a usable access token or refresh-capable credentials, and a local project. It
is independent of `enabled`, and **never an entitlement or live-access check**.
`live_verified` remains false. No actual project/account IDs, private paths,
expiry details, tokens or replay state are exposed. The query performs no network,
refresh, writes or directory creation. An absent or malformed descriptor must not
be interpreted as confirmed disabled/ready state.

Antigravity uses native Messages/count-tokens only; optional OpenAI generation is
explicitly HTTP 501. Its streaming is buffered-turn SSE, not incremental native
text delivery. The selected tier wins over advisory `output_config.effort`, and
`x-antigravity-reasoning-tier` plus monitor metadata expose the effective tier.
Counts use a local semantic-byte estimate (roughly bytes/3) of validated native
history, including hidden retained thoughts and recorded argument/name codecs.
The estimate is invariant to full/omitted display, supported assistant fragments
and opaque signature size; it is not a native tokenizer/billing value. See the
[full experimental contract](/reference/compatibility-and-limitations/#experimental-native-antigravity-argon).

Claude Code gateway discovery filters IDs according to its own model rules. See [Models and routing](/using/models-and-routing/).

## `POST /v1/chat/completions`
Expand Down
21 changes: 21 additions & 0 deletions meta/antigravity-reference-LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2025 Jens

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Loading