Move first-party, sponsor and relay presets to current model IDs so a
pasted Key works without editing the model list.
- Claude: opus/sonnet 5 -> 5.5, haiku 4.5 -> 5.5, fable 5 -> 5.1
- GPT: gpt-5.6-sol / gpt-6-sol -> gpt-6.1-sol; add gpt-6-astra/luna
- Gemini 3.6 Flash -> 3.8 Flash, 3.1 Pro preview -> 4 Argon;
Grok 4.5 -> 4.7; GLM 5.1/5.2 -> 5.3 (+5.3 Flash);
DeepSeek V4 Flash -> V4.1 Flash; Doubao 2.1 Pro 260628 -> 260915;
StepFun Step Plan -> step-5-preview; add Kimi K3.1 Pro, Qwen3.8 Max,
MiniMax M3.1 Flash where the site serves them
- Drop retired models: NVIDIA moonshotai/kimi-k3 (EOL 2026-10-15,
now kimi-k2.6 without unverified Codex reasoning levels),
MiMo V2.5 / V2.5 Pro, Claude Sonnet 4.5, MiniMax M2.7 on Tencent
Token Plan Enterprise Pro
- Relay presets follow each site's own ID spelling and catalog;
DIT.ai, BuyToken and hao.ai are left as configured from their docs;
Soshow, SiliconFlow CN, OpenCode Zen and the Ark rolling alias stay
- MoArk Codex keeps the tested Kimi-K2.7-Code; K3.1 Pro and Qwen3.8
Max stay out of its Codex catalog until their levels are verified
Tests updated to the new IDs; cross-app invariants unchanged.
Claude Code treats any model id it does not recognize (anything not
claude- prefixed) as a 200K window unless the id ends in [1M] or
CLAUDE_CODE_MAX_CONTEXT_TOKENS is set. 23 Claude Code presets pointed at
1M models (GLM-5.3, Kimi K3, DeepSeek V4, Qwen3.8, MiniMax-M3, MiMo,
LongCat, ...) with neither, so in direct mode they auto-compacted around
200K. Windows come from the same vendors' presets in the other apps.
- Claude Code: every tier whose model is 1M now carries [1M], which is
what the form's 1M checkbox reads and writes. That covers those 23 plus
the 5 that pinned MAX_CONTEXT_TOKENS (Qwen x3, Meta, Hugging Face); MAX
stays there as the fallback for tiers the user later unchecks.
DeepInfra's Haiku (Ling-3.0-flash, 131072) stays unmarked.
- Claude Desktop: 12 presets on the same 1M models now declare 1M on
their branded routes.
- SambaNova's note about not adding [1M] is replaced: the context-1m beta
rides alongside the ten or so betas Claude Code already sends, so it
does not change upstream compatibility.
Left as is: Kimi For Coding deliberately pins a 256K compaction window.
Add a "Disable auto mode server check" quick toggle to the Claude
provider editor that writes CLAUDE_CODE_AUTO_MODE_SERVER=0, with a hint
explaining that third-party gateways cannot serve the check and that
official endpoints should leave it unchecked.
New Claude providers now get the key by default unless the preset is
official or a cloud provider, or the preset already sets it. The default
form (no live base yet) also goes through the overlay so the custom
provider starts with the same value.
Switching, adding, editing, sync, universal providers and entering or
leaving local routing now write Codex through the write engine. Only
routing, credential, model, reasoning, context-window and compatibility
fields are replaced; MCP servers, [projects], comments and the user's own
provider tables stay byte-for-byte. auth.json, config.toml, the model
catalog, the managed-account marker and a device-local login stash commit
as one operation, so a crash at any point rolls forward on startup.
- Third-party routes are always written as [model_providers.custom] with
the key in experimental_bearer_token. Rows that use another id, a
top-level openai_base_url or a legacy reserved table are normalized on
the way out. Switching to an official card leaves a dormant custom table
(local proxy address plus placeholder credential) so older third-party
sessions can still resume.
- requires_openai_auth follows the route's auth and whether a login is on
disk; keyring and ephemeral credential stores are handled separately.
- A switch is refused before anything is written when the active profile
overrides the route, the selected table is missing or built in, a
keyless row would fall back to the official login, or the row has no
auth.
- Provider tables an older version wrote are removed only when they can
be proven to be CC Switch's. Tables a profile references are kept, and
reserved ids that cannot be proven are renamed.
- Provider-exclusive fields, including web_search and a row's own
model_catalog_json, are removed on the way out only when live still
holds the previous provider's value.
- No more backfill. A native ChatGPT login that CC Switch deletes or
overwrites is kept in ~/.cc-switch/codex-login-stash.json (0600, not
synced) and restored when switching back to an official card; logging
out on an official card discards it. Login snapshots already in
official rows seed the stash once. A leftover API key in auth.json is
deleted only when it matches a third-party row's key.
- Managed accounts fetch their token before taking the lock. If the CLI
refreshes the login during a switch, the switch stops before writing
anything. Once files are published, a later failure no longer rolls the
row back; startup finishes the switch.
- Local routing: third-party routes get a fixed local-proxy table and the
official route uses cc-switch-official plus the client's own login. The
contract covers every field written, so a route switch with the same
contract touches no files.
- The Codex editor shows what config.toml will look like after switching.
On save, key fields go to the row and other edits go to live as global
settings with a three-way check. Row fields that never reach live are
listed read-only and can be copied.
- The Codex common-config snippet is frozen like Claude's; its UI and the
TOML snippet command are removed. New Codex rows keep
commonConfigEnabled: true for older versions that sync them.
- The write engine can delete a file as part of an operation.
- Integration-test mutexes tolerate poisoning so one failure no longer
cascades into unrelated tests.
Switching, adding the first provider, editing the current provider,
sync, universal providers and restoring after the local router all
write settings.json through the write engine now. Only endpoint,
credential, model and protocol fields plus the provider's own switches
are replaced; hooks, plugins, permissions and everything else stay
byte-for-byte. The file write and the current-provider pointer commit
as one operation, so a crash in between rolls forward on startup.
- No more backfill, no common-config snippet and no context-window
injection for Claude. Window values left behind by the old injection
are cleaned up from a frozen list.
- The provider editor shows what settings.json will look like after
switching. On save, provider fields go back to the row and other
edits go to live as global settings, with a three-way check against
external changes and a dialog to resolve conflicts. Row fields that
never reach live are listed with a one-click add.
- New Claude rows keep commonConfigEnabled: true so older versions that
sync the row still merge their snippet.
- Presets drop timeout and telemetry keys; a test now requires Claude
presets to contain only key or provider-owned fields.
The upcoming refactor replaces whole-file live writes with key-field
replacement and splits direct and proxy modes. These tests pin what must
survive it, and pass on the current code.
Backend (`cargo test --test golden`, snapshots under
src-tauri/tests/golden/snapshots, refresh with CC_SWITCH_UPDATE_GOLDEN=1):
- mcp_bytes: MCP projection bytes in ~/.claude.json, Codex config.toml
and Gemini settings.json, and that switching providers leaves the MCP
section untouched.
- import_rows: raw DB rows written by deep-link import and first-run
import (including seeded official rows and the generated snippet).
- file_modes (Unix): which client files a switch writes and their
permission bits; existing 0600 files are never loosened.
- claude_key_fields: after a switch, live key fields are exactly the
target provider's, across third-party, Bedrock, Vertex, apiKeyHelper
and official providers, with or without common config.
- codex_red_lines: 25 Codex invariants (index at the top of the file),
asserted as outcomes: the config loads on Codex 0.149, the official
login never reaches a third-party URL, refused switches leave files,
current provider and rows untouched.
- downgrade_contract: the previous release detects takeover by the
PROXY_MANAGED literal, rebuilds live from current rows without backup
rows, and replays leftover backup rows.
Frontend: ProviderForm submit payloads for ten representative Claude and
Codex presets.
Three spots are sorted before comparing because their output order is
not deterministic today (MCP maps written from a HashMap, Gemini .env
parsed into a HashMap). One ignored test records a known gap: exiting
the proxy restores a login the user logged out of while on a
third-party Codex route.