6 Commits
Author SHA1 Message Date
Jason 50a9d103d3 chore(presets): refresh preset models to the latest vendor lineups
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.
2026-10-24 22:56:15 +08:00
Jason 31038e686e fix(presets): pre-check 1M for presets whose models have a 1M window
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.
2026-10-15 23:29:24 +08:00
Jason 146f3196fa feat(claude): add auto mode server-check toggle and default it off for gateways
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.
2026-10-06 21:13:04 +08:00
Jason 0e6430abdb feat(codex): switch Codex by replacing only key fields
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.
2026-09-27 22:38:42 +08:00
Jason 63ed5002e5 feat(claude): switch Claude Code by replacing only key fields
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.
2026-09-27 22:38:25 +08:00
Jason bcb83d7ccd test: add golden tests that lock live-config behavior before the switching refactor
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.
2026-09-26 23:05:45 +08:00