Compare commits

..

154 Commits

Author SHA1 Message Date
Jason 47232cb05d chore(release): bump version to 3.16.0 and add release notes
- Bump version to 3.16.0 in package.json, Cargo.toml, tauri.conf.json, and Cargo.lock
- Add v3.16.0 release notes (zh/en/ja) with contributor credits
2026-05-30 00:00:15 +08:00
Jason fe3eb7e6a6 docs(changelog): add 3.16.0 release notes 2026-05-29 23:17:44 +08:00
Jason d905ed1609 Add UTM params to Atlas Cloud partner link across all locales 2026-05-29 22:52:25 +08:00
Jason 94cc3d103a Align Claude Desktop model mapping with Claude Code three-role tiers
Claude Desktop's 3P validation only accepts claude-{sonnet,opus,haiku}-*
role IDs, so providers must map every tier. Bring the Desktop mapping flow
in line with Claude Code and fix the fallout that broke sub-agent Haiku calls.

- Proxy form: replace the dynamic route list with fixed Sonnet/Opus/Haiku
  tiers; blank tiers backfill from the first filled tier (Sonnet first) on
  submit and inherit its supports1m flag
- Backend: add a role-keyword fallback in map_proxy_request_model so dated
  official names (e.g. claude-haiku-4-5-20251001) resolve to the right tier,
  guarded by is_claude_safe_model_id so [1m]-suffixed IDs stay rejected
- Tighten is_claude_safe_model_id / isClaudeSafeRoute to reject degenerate
  role IDs like "claude-sonnet-"
- Fix the seed-effect race where normalizing empty routes to three blank
  tiers blocked the default-route backfill
- Sync switch hints, placeholders, and the zh/en/ja/zh-TW locales to the
  three-role-ID rule
- Update zh/en/ja user manual (2.1, 2.6), calling out legacy Claude IDs
  (claude-3-5-sonnet-...) as a rejected example

Tests: 282 frontend + 34 backend claude_desktop; typecheck, clippy, fmt clean.
2026-05-29 22:52:25 +08:00
Jason 058c9fb8e5 Rename OpenCode Go preset to drop model suffix
Simplify the display name from "OpenCode Go (DeepSeek V4 Flash)" to
"OpenCode Go" in both the Claude Code and Claude Desktop preset lists.
2026-05-29 22:52:25 +08:00
Jason 85552cf40a Add referral param to ShengSuanYun website links
The websiteUrl for ShengSuanYun presets pointed at the bare domain while
only apiKeyUrl carried the from=CH_4HHXMRYF referral code. Append the same
referral param to websiteUrl across all provider presets so the in-app
'open website' jump is also attributed to the channel.
2026-05-29 22:52:25 +08:00
Jason 3a15420770 Update default models and pricing across presets
Bump default model names project-wide: gpt-5.4 -> gpt-5.5,
gemini-3.x -> gemini-3.5-flash, glm-5 -> glm-5.1, and
grok-code-fast-1 -> grok-build-0.1 across all provider presets
(claude, codex, gemini, hermes, openclaw, opencode, universal),
Gemini config, and stream check defaults.

Pricing:
- Seed gemini-3.5-flash, gemini-3.1-flash-lite, step-3.5-flash-2603,
  doubao-seed-2.0-code, mimo-v2.5(/pro), qwen3-coder-480b, grok-build-0.1.
- Correct deepseek-v4-flash/pro, glm-5/5.1, grok pricing.
- Add repair_current_model_pricing: idempotent pass that fixes only
  rows still equal to the outdated built-in values, preserving any
  user-customized prices (seed uses INSERT OR IGNORE and cannot update
  existing rows).

Fixes from review:
- opencode: drop duplicate gemini-3.5-flash variant (unreachable via
  .find), keep the entry with the full minimal/low/medium/high set.
- Align stale display names/costs to gemini-3.5-flash (hermes, openclaw,
  opencode); openclaw cost -> {1.5, 9, 0.15} to match seed.
- i18n (zh/en/ja/zh-TW): refresh OMO category tooltips for new model
  names; fix writing tooltip to Kimi K2.5 to match its recommended.

Update tests accordingly and add a regression test asserting unique
model ids in the Google opencode preset variants.
2026-05-29 22:52:25 +08:00
Jason 2b6ede1431 Update Codex provider migration test expectations 2026-05-29 22:52:25 +08:00
Jason 0877b9e35d Upgrade default Claude Opus model to 4.8
Bump the default Opus route/model from claude-opus-4-7 to claude-opus-4-8
across provider presets (claude, claudeDesktop, hermes, openclaw, opencode,
universal), i18n locales (zh/en/ja/zh-TW), pricing seed data, and the
user-manual docs.

- Add claude-opus-4-8 pricing row ($5/$25/$0.50/$6.25); keep the 4-7 row
  for historical usage stats (seeded via INSERT OR IGNORE).
- Claude Desktop proxy: accept bidirectional opus 4-7 <-> 4-8 route alias
  during rollout so previously saved routes keep resolving.
- thinking_optimizer: route opus-4-8 through adaptive thinking and normalize
  dotted model ids (also fixes dotted 4-6/4-7 falling back to legacy).
- usage_stats: normalize Bedrock/Vertex/aggregator opus-4-8 ids to base
  pricing.

Also merge role:"system" messages into the Gemini systemInstruction in the
Anthropic->Gemini transform.
2026-05-29 22:52:25 +08:00
Q3yp 554e3b4875 fix(proxy): normalize DeepSeek Anthropic tool thinking history (#3203)
Fixes #3200
2026-05-29 22:51:12 +08:00
lipeng e605eba292 fix(deeplink): preserve custom env fields when importing Claude providers (#2928)
When importing a Claude provider via deep link, the preview dialog
correctly shows every env field carried in the `config` payload — but
on confirmation `build_claude_settings` only persisted the standard
fields mapped from URL params (`apiKey`, `endpoint`, `model`,
`haiku/sonnet/opusModel`). Any non-standard env keys such as
`ANTHROPIC_CUSTOM_HEADERS`, `API_TIMEOUT_MS`, or
`CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS` were silently dropped,
making the preview and the actual write diverge.

Start the env map from the inline `config` payload (best-effort
decode via the new `extract_claude_config_env` helper) and then
overlay the URL-param-derived standard fields on top, so:

- URL params remain authoritative for standard fields (unchanged)
- Custom env keys present in `config` survive the import
- Deep links without a `config` payload behave exactly as before

Adds two regression tests:
- `test_build_claude_provider_preserves_custom_env_fields` proves
  custom fields are kept and URL params override same-named config
  fields.
- `test_build_claude_provider_without_config_unchanged` guards the
  backward-compatible path (no `config` → only standard env keys).

Closes #2927

Co-authored-by: lipeng31 <lipeng31@tanyang.co>
2026-05-29 22:49:02 +08:00
in30mn1a bc1467db8d feat(usage): real-time stats refresh + fix codex sync panic on non-ASCII model names (#3027)
The usage dashboard previously only refreshed on app restart for users
who don't route through the cc-switch proxy. Two issues were involved:

1. The session-sync background task panicked when a Codex model name
   contained non-ASCII characters (e.g. `【官】glm-5.1`), because
   `normalize_codex_model` sliced `&name[name.len() - 11..]` without
   verifying char boundaries. Once the task panicked, no session logs
   were imported until the app was restarted (where startup-time
   `rollup_and_prune` happened to flush pending data).

2. Even with sync working, the dashboard only polled every 30s and
   skipped polling when the window was unfocused, so freshly-imported
   data was invisible until the next poll or window refocus.

Fixes
-----

* `normalize_codex_model`: guard the 11-byte ISO-date suffix slice with
  `is_char_boundary` + `is_ascii` checks. ASCII-only suffix means the
  date-stripping logic is correct, and non-ASCII names (which can never
  be valid date suffixes anyway) now bypass the slice safely.

* New `usage_events` module that emits `usage-log-recorded` to the
  frontend whenever `proxy_request_logs` actually gains a new row.
  Sources covered: proxy `log_request`, Claude/Codex/Gemini session
  sync, and startup `rollup_and_prune`. Notifications use a global
  `OnceLock<AppHandle>` so call sites that don't already hold an
  `AppHandle` (e.g. `UsageLogger`) can notify without signature churn.

* 200ms debounce in `notify_log_recorded` collapses bursts (a single
  Codex sync importing 3000+ entries triggers ~2 emits, not 3000) so
  the frontend's `invalidateQueries` is never spammed.

* Frontend `useUsageEventBridge` listens for the event and invalidates
  `usageKeys.all`. Hook is mounted only on `UsageDashboard`, so the
  listener is unsubscribed automatically when the user navigates away.

Verification
------------

* `cargo check` passes (existing 25 dead-code warnings in
  `commands/misc.rs` are pre-existing and unrelated).
* `tsc --noEmit` passes.
* Manually verified end-to-end: a Codex sync run that imported 3145
  entries produced 2 debounced emits, both logged as `emit
  usage-log-recorded 成功`, and the dashboard updated within ~200ms.

Behaviour notes
---------------

* `INSERT OR IGNORE` paths (Claude/Codex session sync) only notify when
  the row is actually inserted, so dedup-skipped writes don't trigger
  empty refreshes.
* Gemini's `INSERT … ON CONFLICT … DO UPDATE` path reuses the existing
  `conn.changes() > 0` check and only notifies when token counts truly
  changed.
* `rollup_and_prune` notifies once per pruning cycle (at most once per
  app start) so the dashboard reflects the new aggregate state.

Co-authored-by: in30mn1a <in30mn1a@users.noreply.github.com>
2026-05-29 22:47:51 +08:00
Jason e71b90916b Add SudoCode partner provider presets 2026-05-29 11:11:46 +08:00
Jason 32b30e43c0 Add AtlasCloud partner provider presets 2026-05-29 09:46:00 +08:00
Jason 9ef141902e Add APINebula partner provider presets 2026-05-29 09:18:59 +08:00
Jason d7a34f4247 fix(about): handle prerelease tools in version check
Use semver comparison instead of string inequality so locally-ahead prerelease builds aren't misreported as outdated; backend now fetches the full npm dist-tags and, when the local version leads latest, surfaces the tool's prerelease channel (claude=next) as latest.
2026-05-29 08:47:54 +08:00
Jason 8302f1e36c Add APIKEY.FUN partner provider presets 2026-05-28 23:43:48 +08:00
Jason 4bb4e994af Fix Shengsuanyun prefixed model IDs for Claude Code and upgrade GPT to 5.5 2026-05-28 21:48:22 +08:00
Jason fc0433f2f4 refactor(codex): unify custom model_provider routing key to "custom"
- Always emit `model_provider = "custom"` from deep link, UniversalProvider, and the universal form modal so future writes share one stable routing key.
- Add `codex_provider_template_v1` local migration that rewrites legacy keys (aihubmix/ccswitch/...) under `[model_providers.custom]`, updates profile refs, and backs up the original settings_config under `~/.cc-switch/backups/<timestamp>/providers/`.
- Tighten history migration source detection to a whitelist plus `[model_providers.<id>]` existence check so user-authored keys are never rewritten in jsonl/state DB.
- Encode deep link name/model/endpoint through `toml_edit::Value` so display names containing quotes or backslashes no longer break the generated config.toml.
- Stabilize provider settings backup filename hash with Sha256 (was process-random SipHash).
2026-05-28 17:30:44 +08:00
Jason 3d6fb894b5 Fix Shengsuanyun prefixed model IDs 2026-05-28 13:16:44 +08:00
Jason af60c7ed2c feat(codex): add remote compaction toggle for third-party providers
Write model_providers name as "OpenAI" to let Codex attempt remote
compaction through compatible endpoints. Hidden for official providers.
2026-05-28 11:57:54 +08:00
Jason a2ac21d0a6 refactor(codex): stop force-rewriting user's model_provider field in live config
The one-time history migration already consolidates legacy provider IDs
into a single bucket; there is no need to normalize on every write.
This preserves user-chosen provider identities through the full
write/backup/restore cycle.
2026-05-28 11:39:54 +08:00
Jason 6b0dd3c4e9 fix(omo): sync recommended models with upstream and improve Fill Recommended feedback
The Fill Recommended button was misleading — it showed toast.success even
when most slots couldn't be filled due to model ID mismatches with the
user's configured providers.

Changes:
- Sync OMO_BUILTIN_AGENTS/CATEGORIES recommended fields with upstream
  oh-my-openagent model-requirements (gpt-5.4→5.5, kimi-k2.5→claude-sonnet-4-6, etc.)
- Add toast.warning tier when unmatched >= filled, showing slot:model pairs
  (e.g. "Sisyphus: claude-opus-4-7") so users know exactly what to configure
- Upgrade fillRecommendedNoMatch to also show examples
- Add fillRecommendedMostlyUnmatched i18n key (zh/en/ja/zh-TW)
2026-05-27 23:08:11 +08:00
Kairos Duan 3c3d417457 Enable Codex goals in provider templates (#3089)
* Enable Codex goals in provider templates

* feat: add Codex goal mode toggle

- Remove forced goals=true from Codex provider presets and custom templates.
- Add a Codex provider editor switch that updates [features].goals on demand.
- Update docs, i18n, and regression coverage for the optional Goal mode flow.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-05-27 11:31:31 +08:00
nanmen2 e9d84af500 fix(session): include Codex archived sessions (#2861)
Scan Codex archived_sessions alongside active sessions so archived conversations appear in the session manager.

Allow deletion from any validated Codex session root while keeping path safety checks in place.
2026-05-27 11:16:50 +08:00
Zihao Han 8e21b061cf Fix custom usage script summaries (#3129)
Co-authored-by: Zihao Han <hanhan3344@users.noreply.github.com>
2026-05-27 10:50:29 +08:00
zhizhuowq 9c2add9a09 fix(proxy): 修复 Claude 兼容模式下流式响应因空 tool_calls 数组导致 block 状态重置 (#2915)
问题:OpenAI 兼容 Provider(如 MiniMax)在发送 reasoning_content 流时,
      每个 chunk 包含 "tool_calls": [] 空数组,导致每个字符被当作独立 block 处理

根因:streaming.rs:343 的 if let Some(tool_calls) 匹配空数组进入处理分支,
      发送 content_block_stop 并重置 current_non_tool_block_type 为 None

修改:在 tool_calls 处理前添加 if !tool_calls.is_empty() 判断

示例输入:
```jsonl
{"delta": {"content": null, "reasoning_content": "用户", "role": "assistant", "tool_calls": []}}
{"delta": {"content": null, "reasoning_content": "用", "role": "assistant", "tool_calls": []}}
{"delta": {"content": null, "reasoning_content": "中文", "role": "assistant", "tool_calls": []}}
...
```
示例错误输出:
```text
event: content_block_start → index 0, type thinking
event: content_block_delta → thinking "用户"
event: content_block_stop → index 0
event: content_block_start → index 1, type thinking
event: content_block_delta → thinking "用"
event: content_block_stop → index 1
event: content_block_start → index 2, type thinking
event: content_block_delta → thinking "中文"
event: content_block_stop → index 2
...
```

Co-authored-by: WangQiang <wangqiang75@huawei.com>
2026-05-27 10:49:41 +08:00
Sphaela 864593bb09 Fix Claude Desktop Cowork egress profile (#3172) 2026-05-27 10:49:08 +08:00
滅ü 5fd3ec0d6a feat(i18n): add Traditional Chinese localization (#3093)
* Add Traditional Chinese localization

* fix: address zh-TW formatting and token units

- Format `zh-TW.json` with Prettier.
- Use Traditional Chinese `萬` and `億` units for zh-TW token summaries.
- Add usage formatting coverage for Traditional Chinese locale aliases.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-05-27 00:05:03 +08:00
zcb 8cdaf90d8d refactor: replace JSON deep copy with deepClone helper and extract useTauriEvent hook (#3140)
* refactor: replace JSON.parse(JSON.stringify()) with structuredClone and extract useTauriEvent hook

Replace all `JSON.parse(JSON.stringify())` deep copy patterns with native
`structuredClone()` across production source (9 occurrences), tests (11
occurrences), and a hand-rolled `deepClone` utility in providerConfigUtils.ts.
Add "ES2022" to tsconfig lib for type support.

Extract a `useTauriEvent` hook to eliminate the repeated Tauri event listener
boilerplate (`useEffect` + `active/disposed` flag + async `listen`) that was
duplicated across App.tsx (3 listeners) and useUsageCacheBridge.ts. The hook
handles async registration, race-condition guards, and cleanup automatically.

* fix: add compatible deepClone helper

- Add a shared deepClone helper with a structuredClone runtime guard and fallback.
- Route clone call sites through the helper.
- Preserve universal-provider-synced listener ordering and drop the dead-directory diff.

* fix: harden Tauri event handling

- Guard WebDAV sync status events against missing payloads.
- Preserve settings query invalidation ordering before showing auto-sync errors.
- Simplify useTauriEvent subscriptions to avoid dependency-driven re-listens.

---------

Co-authored-by: zcb <zhangchongbiao@qiyuanlab.com>
Co-authored-by: Jason <farion1231@gmail.com>
2026-05-26 23:39:16 +08:00
MelorTang 05ba28016c fix: sync Claude Desktop profile during proxy takeover (#3157)
* fix: sync Claude Desktop profile during proxy takeover

* fix(provider): skip Claude Desktop backup refresh during takeover

- Route Claude Desktop takeover updates directly through the 3P profile writer.
- Keep takeover startup backup state unchanged when provider metadata changes.
- Narrow platform-specific test helpers and environment setup with cfg gates.

* fix(provider): restore PathBuf import for CI tests

- Restore an unconditional PathBuf import for provider tests.

- Keep Linux cargo test builds compiling while preserving Claude Desktop cfg-gated helpers.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-05-26 23:01:33 +08:00
zhangyapu1 707a5593e5 feat: add MiMo reasoning_content support for Claude Code proxy (#2990)
* feat: add MiMo reasoning_content support for Claude Code proxy

MiMo requires reasoning_content to be passed back in multi-turn
conversations with tool calls. Add "mimo" and "xiaomimimo" to the
preserve_reasoning_content whitelist so thinking blocks are converted
to reasoning_content when proxying Claude Code → MiMo.

Also handle redacted_thinking blocks (encrypted by Claude Code across
turns) by injecting a placeholder to prevent MiMo 400 errors.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: support MiMo reasoning histories

- Fix the PR CI clippy failure for redacted thinking handling.
- Preserve MiMo reasoning content on the OpenAI Chat proxy path.
- Normalize Claude Desktop Anthropic thinking history for MiMo local routes.
- Reject unsupported Claude Desktop direct model remaps.

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Jason <farion1231@gmail.com>
2026-05-26 22:55:36 +08:00
Martin Klein 48473a5ca3 docs: add German README translation (README_DE.md) (#2994)
* docs: add German README translation (README_DE.md)

Adds README_DE.md, a full German translation modelled on README_JA.md,
and extends the language switcher in README.md, README_ZH.md and
README_JA.md with a Deutsch link.

* docs: remove outdated German sponsor entry

- Remove the AICoding.sh sponsor block from README_DE.md.
- Keep the German README aligned with the current sponsor list.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-05-26 22:09:25 +08:00
Loocor 62928c62bc fix(ui): remove fixed width constraint on AppSwitcher text to prevent clipping (#3161)
* fix(ui): remove fixed width constraint on AppSwitcher text to prevent clipping

App names like "Claude Desktop" were being clipped by the max-w-[90px]
constraint on the text label. Changed to max-w-none so text adapts to
content width. Also removed overflow-x-hidden from the parent toolbar
container to prevent clipping of the wider content.

Fixes text truncation in the top-right app switcher segmented control.

* - fix(ui): preserve AppSwitcher compact overflow behavior

- Restore toolbar overflow clipping required by useAutoCompact.

- Cap expanded AppSwitcher labels at 120px so Claude Desktop fits while compact animation remains smooth.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-05-26 17:35:13 +08:00
Jason 910ca3b40e chore(sponsors): drop AICoding partner from README, presets and i18n
Remove AICoding (aicoding.sh) sponsor entry from the three README files
and the provider preset across all seven app_types (claude, codex,
gemini, hermes, opencode, openclaw, claudeDesktop). Also drop the
matching partner_promotion.aicoding string in zh/en/ja locales.

The icon (src/icons/extracted/index.ts) and the legacy provider id in
codex_history_migration.rs are kept intentionally: the former for
possible later re-use, the latter so existing users' Codex history
still gets bucketed into "custom" on upgrade.
2026-05-25 22:20:34 +08:00
Jason d8a4292091 chore: satisfy clippy::nonminimal_bool and prettier to unblock CI
- codex_config: rewrite `!(A && !B)` as `!A || B` (De Morgan-
  equivalent) — also reads more directly as "no OAuth, or
  already has provider API key".
- UsageScriptModal: reflow conditional onto one line per prettier.
2026-05-25 22:20:34 +08:00
Jason b15d9dfa11 feat(codex): migrate third-party history provider bucket to unified "custom" ID
Codex CLI filters conversations by model_provider — after normalizing
all third-party providers to "custom", old sessions with their original
provider IDs become invisible. This migration rewrites JSONL session
files and state_5.sqlite threads to use the unified ID.

Uses a three-tier trust model for source ID collection:
- Known legacy preset whitelist (46 IDs, case-insensitive)
- cc-switch-created custom providers (identified by created_at)
- User-maintained custom providers are explicitly skipped

Adds scanned_history_files flag to prevent stale v1 markers from
blocking re-runs with the improved source ID collection logic.
2026-05-25 22:20:34 +08:00
Jason 177eef6682 fix(quota): sort ZhiPu tiers so missing nextResetTime maps to five_hour bucket
When the 5-hour bucket is at 0% utilization, ZhiPu's API omits
nextResetTime. The old i64::MAX sentinel sorted these entries last,
causing the weekly bucket to incorrectly claim the five_hour slot.
2026-05-25 22:20:34 +08:00
Jason 95f2dd4126 feat(codex): preserve OAuth login state during third-party provider switching
Codex provider switches now only write config.toml for third-party providers,
injecting the API key as experimental_bearer_token. The user's auth.json
(ChatGPT OAuth tokens) is preserved. Official providers with login material
still write auth.json normally. Backfill restores bearer tokens into stored
provider auth.OPENAI_API_KEY to maintain canonical shape.
2026-05-25 22:20:34 +08:00
Jason 88ba908bc4 feat(settings): unify unix installers on mktemp+bash, fix WSL install missing native installer
Extend the mktemp+bash installer pattern from hermes (commit 20d943be) to
claude and opencode, and remove the cfg gate that locked install_command_for
to non-Windows targets — Windows host + WSL tools now correctly route
through the POSIX install priority instead of falling back to bare npm.
Frontend "one-click install commands" displayed in the About section now
diverge per platform to match what the backend actually runs.

Backend (src-tauri/src/commands/misc.rs):
- New CLAUDE_INSTALL_UNIX and OPENCODE_INSTALL_UNIX constants use the same
  `bash -c 'tmp=$(mktemp) && curl -fsSL .../install.sh -o $tmp && bash
  $tmp; status=$?; rm -f $tmp; exit $status'` shape as HERMES_INSTALL_UNIX.
  The shared comment about why we avoid `curl | bash` is now hoisted to the
  top of all three constants — the constraint (WSL `sh -c` sub-shells
  don't inherit outer pipefail; default shell may be dash/ash) applies to
  every shell installer, not just Hermes.
- New installer_with_npm_fallback helper deduplicates the
  "official installer || npm fallback" chain construction; reuses
  chain_update_commands(LifecycleCommandShell::Posix) so the wiring matches
  the update-chain logic.
- install_command_for split into cross-platform posix_install_command_for
  + thin #[cfg(not(target_os = "windows"))] wrapper. The cfg gate had
  been hiding a real bug: on Windows hosts, the WSL branch called
  wsl_tool_action_shell_command which forwarded install actions to the
  Windows-target tool_action_shell_command, yielding bare `npm i -g` for
  claude/opencode even though they have working native POSIX installers.
- wsl_tool_action_shell_command now branches on action: Install dispatches
  to posix_install_command_for (native installer || npm chain); Update
  keeps the existing behavior. Empty install commands collapse to None so
  callers error on unsupported tools instead of running an empty command.
- build_tool_lifecycle_command pipefail comment updated: the original
  justification (covering install's `curl | bash` path) no longer applies
  to any current command, but the directive stays as defense-in-depth for
  future pipe additions.
- build_tool_action_line WSL branch comment updated to reflect the
  install/update split.

Frontend (src/components/settings/AboutSection.tsx):
- New posixScriptInstallCommand(url) helper builds the same mktemp+bash
  string template the backend uses.
- New powershellEncodedCommand(script) mirrors the backend's UTF-16 LE +
  base64 encoder (charCodeAt + String.fromCharCode(lo, hi) + btoa) so the
  PowerShell EncodedCommand shown to users matches what the backend
  executes.
- ONE_CLICK_INSTALL_COMMANDS split into POSIX_ONE_CLICK_INSTALL_COMMANDS
  and WINDOWS_ONE_CLICK_INSTALL_COMMANDS, selected by isWindows():
  POSIX shows claude/opencode/hermes with the mktemp+bash installer;
  Windows shows claude/codex/gemini/opencode/openclaw with npm (matching
  backend static_fallback_command on Windows) and hermes with the
  PowerShell EncodedCommand. Display now mirrors backend execution
  per platform, removing the show-vs-run mismatch.
- Stale comment in the probe-concurrency note mentioning "curl | bash"
  updated to "官方 installer".

Tests (src-tauri/src/commands/misc.rs):
- New wsl_install_uses_posix_install_priority covers three
  representatives: claude (positive: native installer with npm fallback),
  opencode (positive), codex (negative: no native installer so falls back
  to bare `npm i -g`). Reverse-asserts !contains("| bash") to lock out
  the old pipe form.
- claude_install_chains_native_then_npm and
  opencode_install_chains_native_then_npm strengthened with
  !parts[0].contains('|') so the native installer portion stays
  pipe-free even if future edits to the template sneak a pipe back in.

Validated:
- cargo check --tests: clean
- cargo test --lib commands::misc:: : 59 passed, 0 failed
- pnpm typecheck: 0 errors
- cargo fmt: clean
- pnpm format: clean (no files changed)
2026-05-25 22:20:34 +08:00
Jason 5de0a0dc8d feat(settings): self-update first chain, switch hermes to native installer
Promote anchored upgrades to "<bin> update || <package fallback>" for the
tools whose CLI knows how to self-update safely, and replace pip-based
hermes install/update with the official NousResearch installer scripts.
Frontend learns to detect "update reported success but version did not
change" so silent upstream no-ops surface as a soft warning.

Backend (src-tauri/src/commands/misc.rs):
- New prefers_official_update(tool, shell) per-platform allow-list:
  POSIX {claude, codex, opencode, openclaw}. Windows drops opencode
  pending anomalyco/opencode#17295 (its silent `upgrade` may prompt for
  install-source detection and deadlock our lifecycle). gemini is absent
  from both because `gemini update` is not implemented upstream
  (google-gemini/gemini-cli#18618 / #16122 OPEN).
- New chain_update_commands joins primary/fallback per shell: POSIX
  `||`, Windows `|| call` — batch transfers control to the `||` RHS
  without `call`, skipping subsequent tools in multi-tool actions.
- New LifecycleCommandShell {Posix, WindowsBatch} threads the target
  shell through tool_action_shell_command_for_shell, replacing the old
  hermes-only WSL substitution hack with a uniform mechanism.
- anchored_command_from_paths refactored: hermes anchors to
  `<bin> update`; tools in prefers_official_update chain self-update
  with the package-manager command as fallback; brew formulae remain
  brew-managed (never self-update what Homebrew owns); others use the
  prior npm/volta/bun/pnpm anchoring unchanged. Mirror on Windows.
- Hermes commands switch from pip to the official scripts. POSIX/WSL
  runs `bash -c 'tmp=\$(mktemp) && curl -fsSL .../install.sh -o \$tmp
  && bash \$tmp; status=\$?; rm -f \$tmp; exit \$status'`. The mktemp +
  two-step download avoids `curl | bash` because WSL sub-shells inherit
  neither outer `set -o pipefail` nor a guaranteed bash (default may be
  dash/ash). Windows uses `powershell -NoProfile -ExecutionPolicy Bypass
  -EncodedCommand <b64>` with a hand-rolled UTF-16 LE base64 encoder
  for `irm .../install.ps1 | iex`, hiding the PowerShell pipe from
  cmd.exe. Pip is abandoned because macOS system python3 is often 3.9
  while hermes-agent requires >=3.11, and the pyenv `python` shim may
  not exist — pip errors then misclassify as "command not found".

Frontend (src/components/settings/AboutSection.tsx):
- New versionUnchangedAfterUpdate four-AND short-circuit detects when
  the upgrade command succeeded, the tool still reports a version, but
  that version equals the pre-upgrade version while a different
  latest_version is known. Guards against upstream no-op updaters that
  return exit 0 without applying anything (openai/codex#21897).
- Soft-failure shape gains kind?: "notRunnable" | "versionUnchanged"
  so the warning toast title can disambiguate the two cases.
- Hermes install command snippet swapped from `python3 -m pip ...` to
  the official curl-bash one-liner shown to users.

i18n (zh / en / ja):
- New settings.toolActionVersionUnchangedTitle and
  settings.toolActionVersionUnchanged, synchronized across all locales.

Tests (src-tauri/src/commands/misc.rs):
- Anchored upgrade assertions updated to `<bin> update || <pkg>` shape
  across nvm / volta / bun / homebrew-npm-global / spaces / fnm
  branches; brew formula explicitly does NOT chain self-update.
- New hermes anchor tests replace hermes_has_no_npm_anchor on both
  POSIX and Windows. WSL hermes tests rewritten for the mktemp+bash
  flow with `hermes update` fallback.
- Reverse-lock tests: gemini static fallback must NOT contain
  `gemini update`; opencode Windows static fallback must NOT contain
  `opencode upgrade`; hermes commands must NOT contain
  `python`/`pip`/`powershell`/forbidden pipes.

Validated:
- cargo check --tests: clean
- pnpm typecheck: 0 errors
- cargo fmt: clean
2026-05-25 22:20:34 +08:00
Jason 7cad61be27 refactor(settings): drop CLI uninstall command hints, keep conflict diagnostics
The uninstall hint feature added in f6bdd4bb / 89e2339b printed a
copy-pasteable shell command (e.g. `brew uninstall <formula>`,
`<sibling-npm> rm -g <pkg>; [ -e bin ] && rm -f bin && rm -rf pkg_dir`)
under each detected install in the multi-install conflict panel. Even
with copy-only-never-execute UX, putting destructive commands one
button away from the user is risk we don't want to ship — `rm -rf`
under a misclassified path would be unrecoverable.

Conflict diagnostics themselves are kept: users still see the warning
banner + per-install row (source / path / version / Default badge), so
the "you have multiple installs and the upgrade only touches one"
signal survives. They just don't get a one-click destructive command.

Backend (src-tauri/src/commands/misc.rs):
- Remove `uninstall_command_from_paths` (POSIX + Windows pair).
- Remove `posix_quote_for_user_shell` and `win_quote_path_for_user_shell`
  — both were uninstall-only quoters (whitelist + cmd-only forms).
  `win_quote_path_for_batch` and `shell_single_quote` stay because the
  anchored upgrade path and `build_shell_cd_command` still use them.
- Remove `quoted_sibling_or_bare` and `quoted_sibling_or_bare_with_ext`
  thin wrappers (only callers were uninstall branches).
- Drop `uninstall_command` and `uninstall_command_needs_cmd_hint` from
  `ToolInstallation`. Drop the eager `infer_install_source` ->
  `uninstall_command_from_paths` call in `enumerate_tool_installations`
  (saves ~16μs per probe but the real point is fewer surprises).
- Remove 14 `#[test]` cases for uninstall command shape (brew /
  homebrew-npm-global / nvm / npm-fallback quoting / pnpm / volta / bun /
  hermes / system / Windows percent-path) plus 4 `win_quote_path_for_user_shell`
  helper tests and the `expect_user_shell_quoted_path` test mirror.
- Drop the `src()` test helper that was only used to feed the deleted
  uninstall tests (`infer_install_source` is still called directly by
  surviving tests).
- Cross-references in `anchored_command_from_paths` doc to its now-gone
  uninstall "dual" are stripped.

Frontend (src/components/settings/AboutSection.tsx):
- Conflicts `<ul>` keeps the diagnostic header + per-install `ToolInstallRow`
  but loses the inline command box, the trash + copy icons, the per-row
  PowerShell-call-operator hint, and the `handleCopyCommand` callback.
- Remove the `Trash2` lucide import; `Copy` stays (the install-commands
  copy button at line 1100 still uses it).

API (src/lib/api/settings.ts):
- Drop `uninstall_command` and `uninstall_command_needs_cmd_hint` from
  the `ToolInstallation` TS interface (matches the Rust struct change).

i18n (zh / en / ja):
- Drop `settings.toolUninstallCopyHint`, `settings.toolUninstallCopied`,
  `settings.toolUninstallPwshHint`. Other `tool*` and `skills.uninstall*`
  keys are untouched (Skill uninstall is a separate, non-destructive
  feature for managing the Skills repo and is unaffected).

Stats: 858 deletions, 5 insertions across 6 files.

Validated:
- cargo test --lib: 1322 passed, 0 failed
- cargo fmt --check: clean
- cargo build: clean
- cargo check --tests: clean
- pnpm typecheck: 0 errors
- JSON.parse on all three locale files: clean
2026-05-25 22:20:34 +08:00
Jason 3a77861dd9 feat(settings): backend-generated source-aware uninstall command hints
Move uninstall hint command generation from frontend (which used a lossy
`source` string and couldn't tell brew formula from homebrew-npm-global apart)
into the Rust backend, where `brew_formula_from_path` + `infer_install_source`
together produce correct commands for each install. Conflict UI now reads
`inst.uninstall_command` directly.

Backend (src-tauri/src/commands/misc.rs):
- New `uninstall_command_from_paths` (POSIX + Windows) mirrors the
  `anchored_command_from_paths` family. POSIX branches on brew formula /
  volta / bun / pnpm / nvm|fnm|mise|homebrew / system. Windows branches on
  volta / pnpm / npm.
- New `quoted_sibling_or_bare` (POSIX) + `quoted_sibling_or_bare_with_ext`
  (Windows) deduplicate the `sibling_bin().map(quote).unwrap_or_else(bare)`
  pattern across all uninstall branches.
- New `posix_quote_for_user_shell` whitelists `[A-Za-z0-9._/+=:@-]`; any
  other character routes through `shell_single_quote`. Replaces
  `quote_path_if_spaced` on the uninstall side because the fallback chain
  is destructive (`rm -rf <pkg_dir>`), so a `;` / `$` / backtick in the
  home dir would have let the chain inject extra commands.
- New `win_quote_path_for_user_shell` (no `%` 4x escape) splits from
  `win_quote_path_for_batch`. Uninstall hints are copy-paste targets, not
  `.bat + call` payloads, so the two-round percent expansion that
  motivates the 4x escape doesn't apply.
- POSIX `nvm|fnm|mise|homebrew` branch appends physical-delete fallback
  `; [ -e <bin> ] && rm -f <bin> && rm -rf <pkg_dir>` because nvm v18.20.8
  was observed to silently no-op `npm rm -g` (exit 0 with `up to date`
  message, no filesystem change). Anchored `<node_root>/{bin,lib}` layout
  assumption documented as branch-specific.
- `ToolInstallation` gains `uninstall_command: String` and
  `uninstall_command_needs_cmd_hint: bool`. The bool is computed as
  `cfg!(target_os = "windows") && uninstall_command.contains('"')` — a
  compile-time platform gate avoids false positives from POSIX
  `shell_single_quote`'s `'"'"'` escape form, which also contains `"`.
- `enumerate_tool_installations` computes `source` once and threads it
  into `uninstall_command_from_paths`, removing a redundant
  `infer_install_source` call (review N1).

Frontend (src/components/settings/AboutSection.tsx + src/lib/api/settings.ts):
- Remove the JS helpers `buildUninstallCommand`, `dirOfPath`,
  `isWindowsPath`, `shellQuote`, `TOOL_NPM_PACKAGES`. Conflict rows now
  read `inst.uninstall_command` directly.
- Render a PowerShell-call-operator hint when
  `inst.uninstall_command_needs_cmd_hint` is true. Avoids string-match
  inference from the command (which fails on macOS user names containing
  `'`, e.g. `o'leary`, because `shell_single_quote`'s escape contains `"`).
- `ToolInstallation` TS interface gains the two new fields.

i18n (zh/en/ja):
- New key `settings.toolUninstallPwshHint` documents the PowerShell
  `&` (call operator) requirement for quoted paths.

Tests: 30 new cases under `commands::misc::tests::anchored_upgrade` cover
each POSIX branch (brew formula extraction, npm anchored with fallback,
pnpm, volta, bun, hermes), strong-quoting under `;` / `'` paths, the
fallback-only-for-anchored-branches inverse guard, plus mirror Windows
helpers for the user-shell quoter and a `path%foo%` integration case
demonstrating the literal `%` preservation contract. Total
`commands::misc` test count: 68.
2026-05-25 22:20:34 +08:00
Jason 671859748d feat(settings): extend anchored tool upgrades to Windows native paths
Apply macOS-side anchored upgrades (9984eccb) to Windows. Six tools now
upgrade via an absolute path derived from the install actually hit by the
command line, instead of bare `npm i -g` landing on PATH-first npm. WSL
tools explicitly bypass anchoring (Windows-host paths invalid in distro).

Scope: 7+ Windows package managers compress to 3 idioms in practice
(Scoop/Chocolatey/winget/nvm-windows/MS Store all just install node; the
global-package layer is still npm):
- volta  -> <sibling>\volta.exe install <pkg>
- pnpm   -> <sibling>\pnpm.cmd add -g <pkg>@latest
- others -> <sibling>\npm.cmd i -g <pkg>@latest

Cross-platform:
- infer_install_source: add /volta/ (no dot) and /pnpm/ matches so
  %LOCALAPPDATA%\{Volta,pnpm} route correctly.
- parent_dir: recognize both \ and /, take rightmost (Option<usize>
  Ord lets None<Some, so rfind('\\').max(rfind('/')) auto-picks).
- npm_package_for, default_install, installs_anchored_command:
  promoted from cfg(not(windows)) to all-platforms.
- plan_command_for: merged the two cfg branches; Windows+WSL short-
  circuits to wsl_tool_action_shell_command (not static_fallback) so
  the command shown to the user matches what build_tool_action_line
  actually runs.
- ToolInstallation: add #[serde(skip)] real: PathBuf, populated by
  enumerate, read by installs_anchored_command — no more double
  canonicalize, and closes a TOCTOU window between enumerate and anchor.

Windows-only helpers (#[cfg(target_os = "windows")]):
- sibling_bin_with_ext reads fs to pick .cmd vs .exe (Node installer
  drops .cmd, Volta drops .exe; pure string can't disambiguate).
- win_double_quote shared primitive; win_quote_path_for_batch handles
  cmd token-boundary chars (space, &, (, ), ^, ;, <, >, |, ,) by
  wrapping in quotes, and handles `%` via 4x escape (%%%%) to survive
  both .bat parser expansion AND `call`'s own second percent-expansion
  pass (Microsoft `call /?`: "percent (%) expansion is performed on
  each parameter").
- wsl_tool_action_shell_command wraps tool_action_shell_command so
  hermes inside WSL gets python3||python instead of Windows-target
  py||python (py launcher is Windows-only, missing in WSL distros).

Wire-up:
- build_tool_action_line Windows: WSL -> wsl_tool_action_shell_command
  + wsl.exe wrap; native update -> enumerate + anchored + static
  fallback. Everything gets `call ` prefix (.bat needs it for .cmd
  without replacing the current script; harmless for .exe).

Tests: 33 new — 10 platform-agnostic (install_source_classification,
parent_dir_cases) + 23 cfg-gated Windows-only (anchored_upgrade_windows,
windows_helpers). Anchored expected values use a small expect_quoted_path
mirror in the test mod so assertions stay correct on Windows hosts whose
%TEMP% itself contains spaces/special chars (e.g. user accounts named
"John Doe"); the 7 hardcoded-literal win_quote_* unit tests independently
lock the quoting rules themselves, so mirror drift would be caught by
either side.

Limitation: Windows cfg-gated tests don't run on macOS cargo test.
Validated on macOS host: cargo fmt clean, clippy --all-targets 0
warnings, cargo test --lib 1322 passed. Windows CI runs only on release
tag (release.yml has windows-2022); production validation needs cargo
test on a Windows machine before broad rollout.
2026-05-25 22:20:34 +08:00
Jason c6fd2415c3 fix(settings): enforce absolute paths for all anchored upgrade branches
- misc: extend sibling_bin derivation to claude/brew/volta/bun in addition
  to npm. Return Option<String> so the anchored-path invariant cannot be
  silently violated — when bin_path has no parent directory, propagate
  None and fall back to the static command at the call site instead of
  emitting a bare command that depends on the GUI process PATH.
- misc: factor out quote_path_if_spaced to keep all five anchored
  branches consistent when the resolved path contains spaces.
- AboutSection: add preflightTools lock + try/finally around
  probeToolInstallations so fast double-clicks cannot race two probe
  rounds into concurrent executeRun calls or duplicate confirm dialogs.
- Tests: cover sibling_bin None branch and space-quoting for every
  anchored branch (claude/brew/volta/bun).
2026-05-25 22:20:34 +08:00
Jason 108dda1772 feat(settings): prefer official installer for tool install with npm fallback
Bare `npm i -g <pkg>` was the install command for every managed tool, but
Anthropic and SST now both recommend their native installers over npm. The
update path already anchors to native installs (`claude update` and friends),
so install was the last place still forcing npm — even when the user's
intent was clearly to get the upstream-recommended install.

- New `install_command_for(tool)` (non-Windows only): claude and opencode
  now run the upstream installer with a `|| npm i -g ...@latest` POSIX
  short-circuit fallback, so the tool still installs if the URL is
  unreachable.
- codex / gemini / openclaw / hermes pass through to the original static
  command — they have no independent official installer today.
- `build_tool_lifecycle_command` now opens `set -o pipefail` alongside
  `set -e`: without it, `curl ... | bash` where curl fails would have bash
  exit 0 on empty stdin, silently masking the failure and skipping the
  `||` fallback.
- 6 new `install_strategy` unit tests pin the per-tool install command
  shape, mirroring the existing anchored_upgrade regression suite.

Update routing and Windows install behavior are unchanged.
2026-05-25 22:20:34 +08:00
Jason e25682d345 fix(proxy): source takeover model fields from target provider on managed accounts
When a managed-account provider (GitHub Copilot or Codex OAuth) is taken
over by the local proxy, the *_MODEL_NAME entries written to Claude live
config used to be snapshotted from the live file on disk, which still
held the *previous* provider's values during a switch. The result was a
stale display name lingering after the switch.

Read the model snapshot from the target provider's effective settings
(common-config merged) when the provider uses managed-account auth;
preserve the existing behavior of reading from the live config for
normal providers. The three takeover entry points now resolve the
effective provider up front so common-config writes flow through.
2026-05-25 22:20:34 +08:00
Jason 014c82d28b feat(settings): anchor tool upgrades to the actual install
Rework the About tool-upgrade flow so upgrades target the install the
command line is actually using, instead of running bare `npm i -g` and
landing on PATH's first npm — which used to move upgrades to the wrong
location or fail outright when the resolved bin had no sibling npm.

Anchored upgrade command (update path, non-Windows):
- claude native installer (~/.local/share/claude/versions/) -> `claude update`
- Homebrew formula (canonical path under /Cellar/) -> `brew upgrade <formula>`
- volta / bun -> `volta install` / `bun add -g`
- Node managers with sibling npm (nvm/fnm/mise/homebrew-npm) -> that
  directory's npm with `i -g <pkg>@latest`
- system / unknown sources (e.g. opencode install.sh under ~/.opencode/bin,
  ~/go/bin) -> fall back to the bare command, surfaced as anchored=false
  so the UI shows an honest "default entry not determinable" hint instead
  of pretending the upgrade is targeted.

Multi-install confirmation:
- When the probe finds >=2 installs, pop ToolUpgradeConfirmDialog showing
  each install (source badge + path + version + Default badge) and the
  resolved command before executing. Top-level text only asserts what is
  universally true ("won't update all of them; see each tool below");
  per-card text adapts to anchored vs unanchored.
- Pending upgrade state stores the full upgrade set; the dialog only
  shows the subset that needs confirmation, so non-conflicting tools in
  a batch still get upgraded after confirm.

Unified probe command:
- Merge the previous diagnose_tool_installations and plan_tool_upgrades
  into a single probe_tool_installations returning installs + is_conflict
  + needs_confirmation + command + anchored. Diagnose button, post-upgrade
  auto-diagnose, and pre-upgrade confirmation all share one IPC. The
  diagnose button's previous Promise.all of 6 IPCs is now a single call.

resolve_path_default robustness:
- The previous lines().next() was poisoned by interactive .zshrc output
  (welcome banners, p10k instant prompts, etc.), causing default-install
  detection to fail and dropping multi-install scenarios into the
  unanchored fallback even when one install was clearly the native one.
- Replaced with first_abs_path_line that scans for the first
  absolute-path line and ignores noise, mirroring how try_get_version
  already tolerates banner noise via a regex.

Diagnostic staleness fix:
- diagnoseToolSilently now clears stale diagnostics in the else branch
  when the conflict no longer holds (previously only wrote on conflict,
  never cleared, so externally resolving a conflict left the card stuck
  on a stale list until the user clicked Diagnose).
- Auto-diagnose now triggers after any successful update, not only when
  the version didn't change, so the card reflects the latest conflict
  state even when an anchored upgrade succeeds while another install
  remains.

Other:
- Shared ToolInstallRow between the conflict list and the confirmation
  dialog removes the duplicated per-install row JSX.
- Drop the new shell_quote_path helper in favor of reusing the file's
  existing POSIX-correct shell_single_quote, gated on whitespace.
- Collapse displayName lookup into a stable module-level helper to remove
  the `as ToolName` cast and avoid recreating the closure each render.
- 17 backend unit tests covering anchored command generation across each
  source, brew formula extraction, is_conflicting thresholds, default
  install resolution, and the welcome-banner scenario.
- i18n (zh/en/ja): new keys for confirmation dialog
  title/hint/will-run/confirm-button and the unanchored hint.
2026-05-25 22:20:34 +08:00
Jason ce232a1452 feat(settings): diagnose conflicting tool installations with uninstall hints
Add a "Diagnose installs" action to the About section that enumerates every
installation of each managed CLI, flags real conflicts (diverging versions
or mixed runnable state), and lists them under the affected tool card.

- backend: enumerate_tool_installations + diagnose_tool_installations command,
  sharing build_tool_search_paths with the single-probe scan; resolve the PATH
  default via the same login shell as version probing so the "Default" marker
  matches what the command line (and an upgrade) actually targets
- frontend: global diagnose button left of Refresh, per-card conflict list,
  and a copy-only uninstall command per install -- source-aware (npm/volta/
  bun/pip) and anchored to that install's own npm to avoid removing the wrong
  node version; marked with a red trash icon, never executed
- auto-diagnose silently after an upgrade that leaves the version unchanged
  or installs something that can't run
- i18n: zh/en/ja
2026-05-25 22:20:34 +08:00
Jason ea604a1827 fix(settings): surface "installed but not runnable" state in tool cards
After an install/update command succeeds, re-probe the tool version: if it
still can't be detected the tool is installed-but-unrunnable (e.g. Node too
old), so report a warning toast and show "installed · can't run" with the
cause, instead of a misleading "success" plus a stale version number.

Read the backend `installed_but_broken` flag rather than matching error
text; the card's current-version line, action button (no useless "install"
for a broken tool), and a "check environment" hint all key off it. Drop the
now-redundant version-clearing setState (the refresh merge already nulls it),
flatten the action ternary, and use extractErrorMessage in the catch path.

Adds toolNotRunnable / toolActionInstalledNotRunnable / installedNotRunnable
/ toolCheckEnv i18n keys (zh/en/ja).
2026-05-25 22:20:34 +08:00
Jason 768c5f9f39 fix(misc): probe tool versions faithfully instead of masking unrunnable installs
Unify the three probe paths (try_get_version / try_get_version_wsl /
scan_cli_version) on a cross-platform ShellProbe enum that distinguishes
"not installed" (shell exit 127) from "installed but --version failed"
(e.g. Node too old to run the freshly-upgraded CLI).

The found-but-broken case is now reported as-is and no longer falls back to
scan_cli_version. Previously the fallback surfaced a stale runnable copy
installed elsewhere (e.g. a Homebrew node vs the nvm node the upgrade wrote
to), making an upgrade look like it had no effect ("succeeded but version
unchanged").

Expose the state via a structured `installed_but_broken` flag on ToolVersion
so the frontend no longer infers it by string-matching the error text. Also
fixes a WSL path that could mislabel a genuinely-missing tool as broken, and
extracts the NOT_INSTALLED constant.
2026-05-25 22:20:34 +08:00
Jason f8b4d67b21 fix(settings): run batch updates per-tool and lock actions while busy
Update All previously sent every tool to the backend as one script, where
set -e (or errorlevel on Windows) aborts the whole batch on the first
failure, skipping the rest and not refreshing versions for tools that did
succeed. Run each tool as its own call instead: failures are isolated,
each tool's version refreshes as soon as it finishes, and the result is
summarized in a toast (success / partial / failure) listing which tools
failed.

Also derive an isAnyBusy flag and disable all install/update buttons,
the refresh button and the WSL shell selectors while any action is
running, so users can't trigger concurrent global npm/pip writes.

Add the toolActionPartial i18n key (zh/en/ja).
2026-05-25 22:20:34 +08:00
Jason 820c4db1b0 feat(misc): broaden CLI version detection to PATH and Windows managers
Extend scan_cli_version search paths with the PATH environment variable
and common Windows Node/version-manager locations (pnpm, Volta, nvm,
Scoop, Yarn). Entries from PATH are skipped when they point at the
Microsoft\WindowsApps App Execution Alias directory, which is what
previously caused bogus launches on Windows.

Add unit tests for PATH dedup, child-dir suffix expansion, and the
WindowsApps alias skip.
2026-05-25 22:20:34 +08:00
Jason d7ede24838 docs: update settings manual for tool management and Hermes
Add Hermes to the environment-check table and app-switcher list, fix the
OpenCode install command (opencode-ai), and describe the new update/install
flow. Align with the final implementation: drop the removed Install Missing
action, note that installs run silently with in-button progress, and rename
the section to Manual Install Commands (now collapsible).
2026-05-25 22:20:34 +08:00
Jason e3df86587d feat(settings): expand About page into a tool management panel
List all managed apps with current/latest versions, with per-tool install
and update buttons plus an Update All action. Installs and updates now run
silently: the button shows a spinner for the full duration, versions refresh
automatically when done, and failures surface the backend error detail in a
toast.

While loading, the button keeps its label and only swaps the icon for a
spinner, so width stays constant across zh/en/ja instead of jumping when the
text changes (e.g. Update -> Updating...).

Also collapses and renames the install-commands area to Manual Install
Commands, and removes the managed-apps badge row and the Install Missing
batch button.
2026-05-25 22:20:34 +08:00
Jason ee2d634d89 feat: add silent install/update lifecycle for managed CLI tools
Expand tool version detection to all six managed apps (including Hermes
via PyPI), and add a run_tool_lifecycle_action command that installs or
updates CLI tools silently: it captures the subprocess output and blocks
until the command actually finishes instead of popping a terminal window
(Windows uses CREATE_NO_WINDOW). On failure the last lines of stderr are
returned so the UI can surface a useful message.

Also restores the Windows version-detection path by gating try_get_version
behind cfg(not(windows)) so it no longer risks triggering the App
Execution Alias / protocol handler that previously disabled Windows.
2026-05-25 22:20:34 +08:00
Jason c12d20efd0 refactor(proxy): replace panic-prone unwrap/expect with safe patterns
Harden the proxy module against panics by removing optimistic
unwrap()/expect() calls in favor of pattern matching and graceful
fallbacks:

- copilot_optimizer/cache_injector: bind Value::Array/String directly
  instead of is_array()+as_array().unwrap(); use is_none_or and in-place
  string mutation
- hyper_client: gate the raw-write path with if-let + filter instead of
  has_cases + unwrap()
- gemini_shadow: recover poisoned RwLock via into_inner() rather than
  panicking, with warn logging
- streaming_codex_chat: replace expect("tool state exists") with
  let-else (return/continue)
- merge_tool_results: early-return when messages is absent
- sse: fall back to from_utf8_lossy on the UTF-8 boundary slice

No behavior change on the happy path; all proxy tests pass.
2026-05-25 22:20:34 +08:00
Jason 279b9eabde test: align stale tests with merged Codex preset and bucket changes
CI on main was red because two tests did not follow intentional changes
that were already merged into the codebase:

- codexChatProviderPresets.test.ts still expected the "Kimi For Coding"
  preset, which was removed in 16c3ef3f. Drop the corresponding entry
  from the expected presets map.
- import_export_sync.rs still asserted the legacy per-provider
  model_provider id ("rightcode"), but 9fac15b8 unified Codex
  third-party providers into the stable "custom" history bucket. Mirror
  the assertion update already applied to provider_service.rs.

No production code changed; both fixes only update test expectations.
2026-05-25 22:20:34 +08:00
Jason f9db9913a0 fix: coerce empty tool-call arguments to {} in Codex Chat transform
No-argument tool calls produced empty argument strings that passed
through both the streaming response path and the request transform
verbatim. Strict OpenAI-compatible upstreams (e.g. Minimax) reject
`arguments: ""` with a 400 "invalid function arguments json string",
while lenient ones (OpenAI, Kimi) silently treat it as an empty object.

Add canonicalize_tool_arguments / canonicalize_tool_arguments_str helpers
that coerce empty/whitespace arguments to "{}" and apply them at the four
tool-call argument sites (streaming finalize + three request/response
transform paths). Leave function_call_output content untouched, where an
empty string is valid.
2026-05-25 22:20:34 +08:00
Jason 11edc96a15 docs: document Codex Chat reasoning auto-detection
Add a "Reasoning Auto-Detection" subsection to the Codex local-routing
manual (zh/en/ja) with the provider capability matrix, and record the
feature plus the streaming-usage and tool-call reasoning backfill fixes
in the changelog. Drop the removed Kimi For Coding preset from the
changelog's Codex Chat preset list.
2026-05-25 22:20:34 +08:00
Jason 44d9aabbf3 feat: adaptive reasoning detection for Codex Chat providers
Auto-detect each Chat-routed Codex provider's reasoning interface from
its name, base URL, and model, then inject the matching thinking
parameter without manual configuration:

- Platform-first inference (OpenRouter, SiliconFlow) overrides model
  rules, since the same model exposes different reasoning controls
  depending on the hosting platform.
- Effort tiers are forwarded only to providers that support them
  (DeepSeek, OpenRouter, and StepFun's step-3.5-flash-2603); on/off-only
  providers (Kimi, GLM, Qwen, MiniMax, MiMo, SiliconFlow) drop the level
  instead of sending a field the upstream rejects.
- OpenRouter uses the native reasoning:{effort} object, clamps max to
  xhigh (its enum has no max), and forwards an explicit effort:"none" so
  reasoning can be turned off.
- StepFun falls back to inference so per-model effort support is honored
  (the static preset would have forced effort on step-3.5-flash too).

Includes the Codex provider-form reasoning controls, i18n strings
(zh/en/ja), and response-side reasoning extraction.
2026-05-25 22:20:33 +08:00
Jason 5048ed632d fix: inject stream_options.include_usage for Codex Chat streaming
Responses-to-Chat conversion did not set stream_options.include_usage,
so OpenAI-compatible upstreams (kimi/MiniMax, etc.) omitted the trailing
usage chunk in streaming mode. This caused token/cost/cache stats to be
recorded as zero for third-party streaming requests routed through the
Codex Chat path.

Inject include_usage when the request is streaming, merging into any
client-provided stream_options instead of overwriting it. Add tests for
the streaming, non-streaming, and merge cases.
2026-05-25 22:20:33 +08:00
Jason 7410494645 feat: remove Kimi For Coding preset from Codex
The Kimi For Coding preset pins users to a single coding-only model
(kimi-for-coding), restricting model selection. Drop it from the Codex
presets and trim the corresponding row in the trilingual user manual.
The general Kimi preset (Moonshot platform) is kept, and presets for
other apps are unchanged.
2026-05-25 22:20:33 +08:00
Jason b710c6549e fix: backfill placeholder reasoning_content for bare tool-call messages
Thinking models like kimi/Moonshot and DeepSeek reject any assistant
message carrying tool_calls without a non-empty reasoning_content. When
cross-turn history recovery misses (proxy restart drops the in-memory
cache, ambiguous call_id, or a turn produced no reasoning upstream), the
converted assistant message has none and the whole request fails with
'reasoning_content is missing in assistant tool call message'.

Add a final-stage backfill that runs after all input items are
processed, so genuine trailing reasoning items still attach first and a
placeholder is only injected when none remains. Mirrors the placeholder
behavior in transform::anthropic_to_openai_with_reasoning_content.
2026-05-25 22:20:33 +08:00
Jason 184cbcdc47 fix: reclassify ClaudeAPI as aggregator to re-enable model test
ClaudeAPI supports the health/stream check, but the third_party
category triggers the isClaudeThirdParty gate in ProviderCard that
disables the model test button for third-party Claude providers.
Recategorizing as aggregator restores the test action; the partner
star is unaffected since it is driven by isPartner, not category.

Applied to both the Claude Code and Claude Desktop presets.
2026-05-25 22:20:33 +08:00
Jason 04af87bc7b docs: document Codex Chat provider support in changelog and manual
Backfill the empty [Unreleased] CHANGELOG section with the Codex Chat
Completions feature (Chat-to-Responses bridge, 23 third-party presets,
model mapping table, Stream Check routing, error-envelope conversion,
"custom" history bucket) plus the community fixes landed since v3.15.0.

Update the zh/en/ja user manual: split the Codex preset tables by
upstream protocol (native Responses vs Chat Completions), add a "Codex
Local Routing and Model Mapping" section covering the Needs Local
Routing toggle and the model catalog, and note Chat-format probing in
the Stream Check guide. Manual wording matches the live UI strings.
2026-05-25 22:20:33 +08:00
Jason ead9e22b21 feat: convert Codex Chat error responses to Responses envelope
The Codex Chat-to-Responses bridge already rewrites successful upstream
responses to the Responses shape, but the error branch in
handle_codex_chat_to_responses_transform passed Chat-shaped error bodies
through untouched (MiniMax base_resp, raw OpenAI Chat error, text/plain
"Unauthorized" pages, etc.), leaving Codex clients unable to recognize the
error.

Add chat_error_to_response_error in transform_codex_chat to regularize all
upstream error shapes into the standard {error: {message, type, code, param}}
envelope, then wire it through a new handle_codex_chat_error_response that
preserves the original HTTP status code. Non-JSON error bodies (HTML, plain
text) are wrapped as Value::String and truncated to 1KB at a UTF-8 char
boundary to keep diagnostic context without flooding the response.

Also fix a pre-existing append-vs-insert pitfall in three rebuilt-body
branches (Claude transform, Codex Chat normal, Codex Chat error): http
Builder::header is append, so leaking the upstream Content-Type produced
two Content-Type headers when the rewritten body was JSON. Remove the
upstream value before writing application/json.
2026-05-25 22:20:33 +08:00
Jason 72bc912e0d feat: route Codex Chat providers through Stream Check
Codex Chat providers (apiFormat=openai_chat, e.g. DeepSeek, MiniMax, Kimi)
were incorrectly probed via /v1/responses by Stream Check, which the upstream
rejects. Detect chat routing via codex_provider_uses_chat_completions and
issue the probe against /chat/completions with a Chat-shaped body.

Also align URL fallback order with the production CodexAdapter::build_url:
origin-only base URLs (https://api.deepseek.com) must hit /v1/<endpoint>
first; bare /<endpoint> only as a fallback. The previous order made any
non-404 error on the bare path (401/400/405) flag the provider as down even
though /v1/<endpoint> would have succeeded.

- Lift origin-only detection into proxy::providers::is_origin_only_url so
  both build_url and Stream Check share a single source of truth.
- Collapse resolve_codex_stream_urls and resolve_codex_chat_stream_urls into
  a generic resolve_codex_endpoint_urls(base_url, is_full_url, endpoint),
  which also gives the Responses path a symmetric "full endpoint without
  is_full_url flag" fallback for free.
- Restrict reasoning_effort propagation in the Chat branch to OpenAI o-series
  models, mirroring transform_codex_chat's runtime check.
2026-05-25 22:20:33 +08:00
Jason 955904f719 refactor: rewrite Codex local routing toggle hints for clarity
Reframe OFF/ON hints as action guidance (when to enable) rather than
scenario descriptions, mirroring the Claude Desktop model mapping copy
style. Synced across zh/en/ja locales and the component-level
defaultValue fallback. The switch label "Needs Local Routing" is kept
unchanged to preserve the routing-layer semantics specific to Codex.
2026-05-25 22:20:33 +08:00
Jason 9d35709805 fix: collapse mid-stream system messages in Codex Responses to Chat conversion
MiniMax's OpenAI-compatible chat endpoint strict-rejects any non-leading
role=system message with "invalid params, chat content has invalid message
role: system (2013)". The Codex client uses role=developer (and occasionally
role=system) to inject collaboration_mode / permissions / skills blocks
mid-conversation, and responses_role_to_chat_role maps both to chat's
system role. The converted messages array therefore frequently contained
system entries past index 0, which DeepSeek and OpenAI tolerate but MiniMax
flags as 2013.

Collapse all system messages into a single leading system message before
returning the chat request. The rewrite preserves every system fragment
(joined by "\n\n" in original order) and leaves non-system messages
untouched, so it is lossless for permissive backends as well.

- Add collapse_system_messages_to_head in transform_codex_chat.rs.
- Run it on the messages vector at the end of responses_to_chat_completions
  before serializing.
- Cover the new path with two unit tests: one repros the MiniMax-shaped
  input (developer items between users) and asserts no system role past
  index 0; the other verifies non-system order is preserved and content
  is joined with "\n\n".
2026-05-25 22:20:33 +08:00
Jason f2935a3db9 feat: add Chat Completions routing for 22 Codex third-party presets
Enable openai_chat routing with explicit model catalogs across the major
Chinese/Asian providers (DeepSeek, Zhipu GLM, Kimi, MiniMax, Baidu Qianfan,
Bailian, StepFun, Volcengine Agent Plan, BytePlus, DouBaoSeed, ModelScope,
Longcat, BaiLing, Xiaomi MiMo, SiliconFlow, Novita AI, Nvidia, etc.). Each
preset declares its context window so the UI can size catalog rows when the
preset is picked.

Also lands two consistency fixes uncovered along the way:
- Include setCodexCatalogModels in resetCodexConfig's useCallback deps to
  match the new third parameter it consumes.
- Realign TheRouter Codex test to the "custom" model_provider bucket
  established by the recent third-party unification; the previous assertion
  predated that refactor and had been failing on HEAD.
2026-05-25 22:20:33 +08:00
Jason ad8bdf16ae fix: preserve Codex model catalog on live read of active provider
Editing the currently active Codex provider triggered `read_live_settings`,
which returned only { auth, config }, omitting `modelCatalog`. The form's
mapping table then initialized to empty, and a subsequent save wiped the
DB's `modelCatalog` field — silently destroying user-configured model
mappings after every CC Switch restart.

The mappings already live on disk as a projection in
`~/.codex/cc-switch-model-catalog.json` (pointed at by `config.toml`'s
`model_catalog_json`). Reverse-parse that file so live reads return the
same shape the save path writes.

- Add `read_codex_model_catalog_simplified_from_live` to recover
  `{ model, displayName?, contextWindow? }` entries from the catalog file.
- Skip user-managed external catalogs (filename != cc-switch-model-catalog.json)
  so we don't downgrade their richer structure to the simplified table.
- Squash display_name == slug and context_window == default (config's
  `model_context_window`, or 128_000 fallback) so blank inputs round-trip
  back to blank instead of materializing fallback values in the UI.
- Collapse all failure modes (missing file, parse error, no matching
  field) to Ok(None) so the editor stays openable when the projection
  file is absent or corrupt.
- Wire the new function into `read_live_settings`'s Codex branch.
- Cover the new pure helpers with 7 unit tests in codex_config::tests.
2026-05-25 22:20:33 +08:00
Jason b44f83f7c5 feat: unify Codex third-party providers into stable "custom" history bucket
Codex filters resume history by `model_provider`, so switching between
provider-specific ids like `rightcode` and `aihubmix` made past sessions
appear to vanish. Collapse all third-party providers into a single
stable bucket so cross-switch history stays visible.

- Normalize live `model_provider` to "custom" on every Codex write
  (reserved built-in ids like openai/ollama are preserved).
- Add device-level one-shot migration that rewrites historical JSONL
  session files and the `state_5.sqlite` threads table from legacy
  provider ids into the "custom" bucket. Backs up originals under
  `~/.cc-switch/backups/codex-history-provider-migration-v1/` and uses
  the SQLite Backup API for the state DB.
- Record completion in `settings.json` under `localMigrations` so the
  migration is strictly idempotent across launches.
- Update Codex provider preset templates to emit `model_provider = "custom"`
  out of the box.
2026-05-25 22:20:33 +08:00
Jason 2a4651a21e feat: preserve user-selected catalog model in Codex Chat requests
When Codex client sends a model from the catalog (e.g., user selected via /model),
preserve that choice instead of always replacing with config.toml's default model.

- Check if request model exists in modelCatalog before falling back to config model
- Remove CODEX_CHAT_CLIENT_MODEL constant (no longer needed)
- Add test coverage for catalog model preservation
2026-05-25 22:20:33 +08:00
Jason 9b9578206b fix: prevent infinite render loop in Codex model catalog
Break bidirectional sync cycle between catalogRows (child) and catalogModels (parent):
- Remove catalogModels from child→parent effect dependencies
- Track last sent data in ref to avoid redundant callbacks
- Sync ref when parent pushes new data to prevent false positives

Fixes severe UI jittering when adding/editing catalog entries.
2026-05-25 22:20:33 +08:00
Jason 791ced0034 fix: Codex model catalog WYSIWYG and config consolidation
- Remove mergeCodexDefaultCatalogModelForSave implicit injection (P1)
  The model mapping table is now the single source of truth; no hidden
  entries are prepended on save.

- Sync first catalog row model into config.toml on save
  Ensures Codex default request model matches the table's first entry
  instead of retaining a stale template value.

- Remove API Format selector from CodexFormFields (P3)
  wire_api is always 'responses'; the selector confused users into
  thinking they were changing the upstream protocol. Only the 'Needs
  Local Routing' toggle remains.

- Add restart hint to model mapping i18n text (P2)
  model_catalog_json is loaded at Codex startup; users are now informed
  that a restart is needed after changes.

- Unify write_codex_live_with_catalog helper (P4)
  Replaces three scattered prepare+write call sites in config.rs,
  provider/live.rs, and proxy.rs with a single entry point.

- Clean up useCodexConfigState dead state (P3 follow-up)
  Remove codexModelName, codexContextWindow, codexAutoCompactLimit and
  their handlers/effects since no component consumes them after the UI
  consolidation.
2026-05-25 22:20:33 +08:00
Jason 90b7f25111 - Restore Codex Chat reasoning fallback
- Add unique call-id fallback when Codex omits or rewrites previous_response_id.

- Keep ambiguous call ids unresolved to avoid cross-request history leaks.

- Cover fallback and ambiguity behavior with regression tests.
2026-05-25 22:20:33 +08:00
Jason 22fbe6f11a - Optimize Codex Chat cache stability
- Stop deriving Codex session/cache identity from `previous_response_id`.
  - Canonicalize parseable JSON string payloads in Chat and Responses tool conversions.
  - Add regression coverage for cache-sensitive conversion behavior.
2026-05-25 22:20:33 +08:00
Jason 74acf1e387 Add Codex Chat-to-Responses bridge
- Add Codex provider API format selection and model mapping for Chat-only upstreams.
- Convert Codex Responses requests to Chat Completions and rebuild Chat responses as Responses output.
- Preserve reasoning_content across non-streaming, streaming, tool calls, and previous_response_id follow-ups.
- Add a bounded Codex Chat history cache for restoring tool calls before tool outputs.
- Cover Chat bridge, compact routing, streaming, and history recovery with focused tests.
2026-05-25 22:20:33 +08:00
狂飙 5315fa284b Update 1.2-installation.md (#2949)
增加 Windows 运行后无提示的修复方法
2026-05-20 15:04:56 +08:00
Jason 00b6cc6809 fix: format providerConfigUtils.ts to pass CI checks 2026-05-19 16:40:19 +08:00
Jason 398f40dacb docs: recommend official Homebrew cask installation
- Remove personal tap requirement from all READMEs (en/zh/ja)
- Update v3.15.0 release notes to highlight official cask availability
- Add celebration banner noting Homebrew official repository inclusion
- Simplify installation to single command: brew install --cask cc-switch
2026-05-19 16:14:56 +08:00
Jason 09f67c1b38 Handle inline thinking in Codex Chat conversion
- Split leading <think> blocks from Chat content into Responses reasoning output.
- Keep assistant text output free of inline thinking tags.
- Support streamed inline thinking blocks before normal text deltas.
- Add regression coverage for MiniMax-style inline thinking responses.
2026-05-19 11:06:12 +08:00
Jason 79d6486e16 Improve Codex Chat reasoning conversion
- Convert Chat reasoning_content and reasoning fields into Responses reasoning output items.
- Emit Responses reasoning summary SSE events for streamed Chat reasoning deltas.
- Preserve output ordering when reasoning, text, and tool calls are streamed together.
- Add regression coverage for data-only Chat SSE errors, multiple tool calls, and compact routing.
2026-05-19 10:33:24 +08:00
Jason 1c82b8a3fa Add Chat Completions routing for Codex providers
- Add a Codex API format selector and routing badge for Chat Completions providers.
- Convert Codex Responses requests to upstream Chat Completions when routing is required.
- Convert Chat Completions JSON and SSE responses back to Responses format.
- Keep generated Codex wire_api values on Responses for Codex compatibility.
- Add i18n labels, provider metadata handling, and focused conversion tests.
2026-05-19 10:23:48 +08:00
Jason 61e68d754c fix(proxy): inject only ANTHROPIC_API_KEY for managed-account Claude takeover
- Provider: add uses_managed_account_auth / is_github_copilot helpers
  to identify managed-account providers (GitHub Copilot / Codex OAuth)
- ProxyService: choose auth policy by provider type when taking over
  Claude Live config. Managed accounts drop token env keys and write
  only the ANTHROPIC_API_KEY placeholder; other providers keep the
  existing ANTHROPIC_AUTH_TOKEN fallback behavior
- Forwarder: add outbound guard that refuses to send the PROXY_MANAGED
  placeholder upstream to *.githubcopilot.com and chatgpt.com
  /backend-api/codex
- Add unit tests covering detection, injection, and the outbound guard
2026-05-18 22:46:18 +08:00
Jason 76b4c8b509 chore: remove LionCC sponsor and presets
- Remove LionCC sponsor entry from all README files (en/zh/ja)
- Remove LionCCAPI presets from all provider configs
- Remove lionccapi i18n keys from all locales
- Keep lioncc.png icon file as requested
2026-05-18 16:59:13 +08:00
Jason ddde7f13b3 - docs: update user manual for v3.15.0
- Sync zh/en/ja manuals with Claude Desktop and Hermes support

- Update install requirements, official channels, and release asset guidance

- Document Usage Hero, Codex OAuth live models, Save Anyway, Hermes sessions, and Warp launch

- Correct tray and app-scope descriptions to match current implementation
2026-05-18 16:59:13 +08:00
mrzhao c9efec294b fix(skills): install correct skill from skills.sh search results (#2784)
* fix(skills): install correct skill from skills.sh search results

When multiple skills share the same directory name across different repos,
SkillCard was passing directory to onInstall/onUninstall, causing handleInstall
to always match the first result. Switch to using the unique key field
(directory:repoOwner:repoName) for precise identification.

* test(skills): add regression test for skills.sh install by key

Verifies that clicking install on the second card when two skills share
the same directory name correctly installs the second skill, not the first.

---------

Co-authored-by: mrzhao <mrzhao@iflytek.com>
2026-05-18 11:45:54 +08:00
Roger Deng 0977dcd1c1 fix skill sync copy fallback (#2791) 2026-05-18 11:40:45 +08:00
Roger Deng 6e8ee094f1 fix(usage): reduce price input step to 0.0001 for sub-cent precision (#2793)
The step was 0.01, preventing input of prices like DeepSeek's cache read
cost ($0.0028/million tokens). Extract step value to a constant and apply
to all four price fields.

Closes #2503
2026-05-18 11:38:32 +08:00
luw2007 5ae9c2605d fix(terminal): Ghostty opens clean window instead of cloning existing tabs (#2801)
When Ghostty is already running, `open -a` silently ignores `--args`,
and `open -na` clones all existing tabs into the new instance.

Add a dedicated `launch_macos_ghostty` that uses
`--quit-after-last-window-closed=true` and `-e bash <script>` to spawn
a single clean window running claude.

Also change `launch_macos_open_app` from `open -a` to `open -na` so
other terminals (Alacritty/Kitty/WezTerm/Kaku) correctly open a new
window when already running.

Closes #2798
2026-05-18 11:37:27 +08:00
BlueOcean 0fb7fd12e5 feat: add Xiaomi MiMo Token Plan presets (#2803)
* feat: add Xiaomi MiMo token plan presets

* fix: update Xiaomi MiMo provider presets

* fix: align MiMo V2.5 model specs with official documentation

- Update maxTokens from 32000 to 131072 (128K) for mimo-v2.5-pro and mimo-v2.5
- Update contextWindow from 262144 to 1048576 (1M) for mimo-v2.5
- Aligns with official specs from Xiaomi MiMo documentation
- Ensures consistency between OpenClaw and OpenCode presets

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-05-18 10:38:03 +08:00
Tiancrimson 5c79cf64a4 fix(gemini-native): resolve functionResponse.name and replay thought_signature for synthesized tool call IDs (#2814)
* fix(gemini-native): resolve functionResponse.name and thought_signature replay for synthesized tool call IDs

Two related bugs in the Gemini Native format conversion layer:

1. **functionResponse.name resolution** (422 error): When Gemini's parallel
   function calls omit the id field, cc-switch synthesizes gemini_synth_*
   IDs. These are stored in the shadow store but can be lost in long sessions,
   causing subsequent tool_result blocks to fail. Fix: pre-scan all assistant
   messages in the request body to seed the tool_name_by_id map, and add a
   last-resort fallback that scans the current content array for matching
   tool_use blocks.

2. **thought_signature replay** (400 error): The Anthropic Messages format
   strips thoughtSignature from tool_use blocks, but Gemini requires it on
   every functionCall in multi-turn tool-use exchanges. Fix: build a
   thought_signature_by_id map from shadow turns and attach thoughtSignature
   when converting tool_use back to functionCall.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* style: run cargo fmt on transform_gemini.rs

---------

Co-authored-by: Tiancrimson <tiancrimson@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Jason <farion1231@gmail.com>
2026-05-18 10:25:35 +08:00
LaoYueHanNi bbce75fcda fix(session): 修复session log模式下子Agent token统计遗漏 (#2821)
* fix(session): 修复session log模式下子Agent token统计遗漏

collect_jsonl_files() 只扫描了两层目录,遗漏了子Agent的JSONL日志文件,
导致子Agent的独立token使用数据完全未统计到session费用中。
(仅影响session log模式,proxy代理模式不受影响)

* refactor(session): optimize collect_jsonl_files logic

- Replace two independent if statements with if-else for mutually exclusive conditions
- Remove unnecessary clone() when pushing file paths
- Add clarifying comments for main session vs subagent files
- Apply cargo fmt for consistent formatting

Performance improvement: Eliminates redundant clone() operations when
processing .jsonl files, as a path cannot be both a file and a directory.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-05-18 10:00:57 +08:00
iamryan ed33990b9c fix-codex-mise-detection (#2822) 2026-05-18 09:38:08 +08:00
Zylo 8786f44c5a Fix race condition in useEffect hooks and type assertion bug (#2827)
- Add active flag pattern to 3 useEffect hooks in App.tsx to prevent
  event listener leaks when component unmounts before async setup completes
- Add guard check in useSettings.ts to prevent undefined from being
  stored in localStorage when payload.language is missing

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 09:36:44 +08:00
Jason 4f0f103a8a Add Claude Desktop user guide docs
- Add the Claude Desktop provider guide in English, Chinese, and Japanese.
- Add localized screenshots for import, provider setup, model mapping, and local routing.
- Link the guide from the v3.15.0 release notes and user manual indexes.
2026-05-16 20:18:49 +08:00
Jason c460a404dc Add Claude Desktop official preset
- Add Claude Desktop Official to the Claude Desktop preset list.
- Treat selected official presets as official mode in the form.
- Cover the official preset with a preset-order regression test.
2026-05-16 19:49:59 +08:00
Jason 6172bfd549 docs(release-notes): soften imposter warning wording in en/ja notes 2026-05-16 13:26:53 +08:00
Jason 1232b49b74 docs(release-notes): soften imposter warning wording in zh notes 2026-05-16 13:25:09 +08:00
Jason 3640a4e27d docs(release-notes): remove emoji from imposter site warning 2026-05-16 13:21:44 +08:00
Jason fed892d307 docs(release-notes): add imposter site warning to v3.15.0 notes 2026-05-16 13:19:33 +08:00
Jason 9e3f168903 chore(release): bump version to 3.15.0 2026-05-16 11:21:18 +08:00
Jason 9e6a7a0d81 - Fix proxy test helper clippy warning
- Mark `should_force_identity_encoding` as test-only.

- Keep runtime forwarding behavior unchanged.

- Verified with local CI checks and no-bundle Tauri build.
2026-05-15 23:45:26 +08:00
Jason 4a631b28c7 chore(i18n): simplify modelMappingOffHint to action-oriented copy 2026-05-15 23:33:48 +08:00
Jason ec8afd63ea refactor(presets): render presets in array order and prioritize partners
Remove the category-based grouping logic from ProviderPresetSelector,
letting the array position in each preset config file be the single
source of truth for display order. Move partner presets (PatewayAI,
火山Agentplan, BytePlus, DouBaoSeed) right after Shengsuanyun across
all 6 config files so they appear earlier in the UI.
2026-05-15 23:28:59 +08:00
Jason 9050442b65 feat(presets): add BytePlus provider preset as partner
Add BytePlus (international Volcengine) to Claude, Claude Desktop,
Hermes, OpenCode, and OpenClaw with byteplus icon, 256K context window,
and trilingual promotion text.
2026-05-15 22:45:04 +08:00
Jason d94eb6729b feat(presets): add 火山Agentplan provider preset as partner
Add Volcengine Ark Agentplan to Claude, Claude Desktop, Hermes,
OpenCode, and OpenClaw with huoshan icon and trilingual promotion.
2026-05-15 22:28:26 +08:00
Jason a0131c9a2b chore(presets): update DouBaoSeed endpoint, links, and add as partner
Switch Anthropic-format base URL from /api/coding to /api/compatible,
update website/apiKey URLs to Volcengine console with tracking params,
and promote DouBaoSeed to partner with trilingual promotion text.
2026-05-15 22:00:55 +08:00
Jason 58cd5302ae chore(presets): switch RelaxyCode icon to custom relaxcode.png
Replace the generic claude icon with a dedicated relaxcode.png icon
for the RelaxyCode provider presets.
2026-05-15 17:55:47 +08:00
Jason 3fd38b0a3d feat(presets): add RelaxyCode provider presets
Add RelaxyCode as a new third-party provider with support for:
- Claude Code preset (Anthropic native protocol)
- Codex preset (gpt-5.5 model)
- Claude Desktop preset (direct mode with passthrough routes)

RelaxyCode is an enterprise-grade AI programming platform providing
unified access to Claude Code, Codex, and Gemini CLI models.
2026-05-15 17:38:26 +08:00
Jason 18ffddbfa5 feat(presets): add RunAPI provider presets
Add RunAPI as a new partner provider with support for:
- Claude Code preset (Anthropic native protocol)
- Codex preset (gpt-5.5 model)
- Claude Desktop preset (direct mode with passthrough routes)
- OpenCode preset (@ai-sdk/anthropic)
- OpenClaw preset (anthropic-messages protocol)
- Hermes preset (anthropic_messages mode)
- Icon configuration (runapi.jpg)
- i18n support (zh/en/ja) with ¥14 free credit promotion

RunAPI is a high-performance AI model API gateway supporting 150+
mainstream models (OpenAI, Claude, Gemini, DeepSeek, Grok) with
prices as low as 10% of official rates.
2026-05-15 17:20:46 +08:00
Jason d6bbbf72f0 feat(presets): add ClaudeCN provider presets
Add ClaudeCN as a new partner provider with support for:
- Claude Code preset (Anthropic native protocol)
- Codex preset (gpt-5.5 model)
- Claude Desktop preset (direct mode with passthrough routes)
- OpenCode preset (@ai-sdk/anthropic)
- OpenClaw preset (anthropic-messages protocol)
- Hermes preset (anthropic_messages mode)
- Icon configuration (claudecn.png)
- i18n support (zh/en/ja) with enterprise service promotion

ClaudeCN is an enterprise-grade AI gateway operated by a registered
company, supporting enterprise procurement processes with corporate
payments, contracts, and compliance guarantees.
2026-05-14 23:28:07 +08:00
Jason df11df4d9c feat(presets): add ClaudeAPI provider presets
Add ClaudeAPI as a new partner provider with support for:
- Claude Code preset (using ANTHROPIC_AUTH_TOKEN field)
- Claude Desktop preset (direct mode with passthrough routes)
- Icon configuration (ClaudeApi.png)
- i18n support (zh/en/ja) with test credit promotion

ClaudeAPI provides official Anthropic API keys and AWS Bedrock
routing with support for Tool Use and 1M context.
2026-05-14 23:07:49 +08:00
Jason 4eb5543d9f refactor(presets): switch 20 Claude Desktop providers from proxy to direct mode
- Change mode from "proxy" to "direct" for 20 third-party/aggregator providers
- Simplify PipeLLM from mappedRoutes to passthroughRoutes for consistency
- Reduces unnecessary proxy layer overhead for providers that support direct API calls

Affected providers: ShengSuanYun, AIHubMix, DMXAPI, PackyAPI, PatewayAI,
Cubence, AIGoCode, RightCodes, AICodeMirror, AICoding, CrazyRouter,
SSSAICode, ModelVerse, CompShare, MicuAPI, CTOK, E-FlowCode,
VibeCodingAPI, LemonData, PipeLLM
2026-05-14 22:52:54 +08:00
Jason 08cd5ab56e feat(presets): add PatewayAI provider presets
Add PatewayAI as a new partner provider with support for:
- Claude Code preset (using ANTHROPIC_API_KEY field)
- Codex preset (gpt-5.5 model)
- Claude Desktop preset (proxy mode with passthrough routes)
- Icon configuration (pateway.jpg)
- i18n support (zh/en/ja) with $3 registration bonus promotion

PatewayAI provides reliable API routing services for Claude Code,
Codex, and Gemini models.
2026-05-14 22:36:45 +08:00
Jason b642ef0633 fix(failover): patch P1-P3 reliability gaps surfaced by team review
- Forwarder buffers non-streaming bodies and primes streaming first
  chunk before signaling success, so body timeouts and SSE first-chunk
  failures route through the circuit breaker instead of being recorded
  as success on response-header arrival
- Atomic enable-failover: switch to P1 before persisting the flag, and
  roll back auto-added queue entries when the switch is rejected
  (e.g. official providers)
- Hot-reload circuit breaker config on per-app proxy config change
  instead of waiting for a proxy restart
- FailoverToggle / FailoverQueueManager / AutoFailoverConfigPanel
  require proxy takeover for the active app; the backend command also
  rejects enabling when takeover is off
- ProviderHealthBadge consumes the backend is_healthy flag instead of
  hardcoding the 5-failure threshold

Cleanup:
- impl From<&AppProxyConfig> for CircuitBreakerConfig and use it from
  the command layer
- Collapse three identical TabsContent blocks into a single map
2026-05-14 21:35:02 +08:00
Jason 940161fb0e feat(providers): add routing support badges for Claude Code and Codex
Add visual indicators for routing capabilities on provider cards:
- Claude Code: "Needs Routing" badge for non-official providers with non-anthropic API formats
- Claude Code: "No Routing Support" badge for official providers
- Codex: "No Routing Support" badge for official providers

The badges help users understand which providers support format conversion through routing.
2026-05-14 17:51:42 +08:00
Jason 0d09555503 chore(partners): cross-link BytePlus/Volcengine entries in READMEs 2026-05-14 16:13:35 +08:00
Jason cb45c22b63 chore(presets): migrate OpenClaudeCode to MicuAPI domain
Replace all openclaudecode.cn URLs with micuapi.ai across all
provider presets (Claude, Codex, Hermes, OpenClaw, OpenCode,
Claude Desktop). This includes website URLs, API key URLs, and
base URLs.
2026-05-14 15:41:52 +08:00
Jason 8dabb9fab9 chore(presets): update CrazyRouter API endpoints to cn subdomain
Update all CrazyRouter baseURL configurations from crazyrouter.com
to cn.crazyrouter.com across all supported applications (Claude,
Codex, Gemini, Hermes, OpenClaw, OpenCode, Claude Desktop).

Website and registration URLs remain unchanged.
2026-05-14 15:40:41 +08:00
Jason 99304ffcfd chore(partners): remove DDSHub partner integration
Remove DDSHub from all provider presets (Claude, Claude Desktop, Codex, Hermes),
i18n files (zh/en/ja), README docs, and icon system. Physical assets retained for
potential future restoration.
2026-05-14 15:35:35 +08:00
Jason 543e057e20 fix(providers): disable model test for third-party Claude providers
Most third-party Claude Code providers now reject requests from
non-official clients, so the model test button would just produce
noisy failures (or worse, trigger risk controls on the provider
side). Treat third-party Claude providers the same way as official /
Copilot / Codex OAuth: pass onTest=undefined so ProviderActions
renders the test button in its existing disabled visual state.
2026-05-14 15:26:54 +08:00
Jason 73bc4eb65d feat(codex-oauth): fetch model list from ChatGPT backend on demand
- Add `get_codex_oauth_models` Tauri command reusing the managed OAuth
  access token to hit `chatgpt.com/backend-api/codex/models`; HTTP and
  multi-shape JSON parsing live in `services::codex_oauth_models` so the
  command stays thin.
- Unify the Claude form's "fetch models" button across normal / Copilot /
  Codex OAuth presets, drop the auto-load effect for Copilot in favor of
  explicit clicks, and guard against stale responses with a requestId ref.
- Add Vitest coverage for both Copilot and Codex OAuth paths asserting no
  request on mount and the correct account id on click; add Rust unit
  tests for the four model-list payload shapes.
2026-05-14 15:03:31 +08:00
Jason f93b935d5f fix(proxy): expose real provider model names in Claude Code menu under takeover
When proxy takeover is active, write per-role *_MODEL aliases for routing
and *_MODEL_NAME with the upstream provider's real model name so the
Claude Code model menu reflects the active provider instead of stale
display names from a previous switch. Preserves the [1M] capability marker
for Sonnet/Opus, and strips it from implicit display names.
2026-05-14 12:16:00 +08:00
Jason 402570ce31 fix(usage): pricing routing, SSE lifecycle, and validation hardening
* model pricing routing: extend prefix-match families (gpt-/o1-o5/
  gemini-/deepseek-/qwen-/glm-/kimi-/minimax-) with per-family dash
  thresholds so short base IDs like gpt-5 no longer mis-match
  gpt-5-mini; strip ISO and 8-digit date suffixes via UTF-8-safe
  byte matching so claude-haiku-4-5-20251001 falls back to
  claude-haiku-4-5 pricing
* SSE collector: SseUsageFinishGuard (RAII) guarantees finish() on
  early return or panic; AtomicBool fast path lets push() skip the
  Mutex once first-event time is recorded
* validation: shared validate_cost_multiplier / validate_pricing_source
  helpers across DAO and service layers; PRICING_SOURCE_RESPONSE /
  PRICING_SOURCE_REQUEST constants replace string literals; price
  fields in update_model_pricing now reject empty / non-decimal /
  negative input before INSERT
* backfill: add backfill_missing_usage_costs_for_model so a single
  price edit only scans matching rows instead of the full log table;
  startup backfill remains full-scan
* session_usage{,_codex,_gemini}: share find_model_pricing helper from
  usage_stats; metadata_modified_nanos centralizes mtime precision
* frontend: NON_NEGATIVE_DECIMAL_REGEX + isNonNegativeDecimalString
  replace three copies of the same multiplier regex; isUnpricedUsage
  surfaces zero-cost rows that have usage tokens (cached per row to
  avoid double evaluation); invalidate usageKeys.all on pricing mutate
  so backfilled rows refresh
2026-05-14 11:53:51 +08:00
Jason 206125b4e3 fix(proxy): patch P0-P3 routing/lifecycle issues across forwarder paths
* stream_check: thread Result from get_auth_headers via map_err so
  the workspace builds again
* forwarder: scope rectifier / budget-rectifier flags per-provider so
  failover can still apply rectification on the next attempt
* forwarder: categorize before record_result; route NonRetryable and
  ClientAbort through release_permit_neutral so client-side failures
  don't pollute circuit breaker or DB health
* handler_context: parse Gemini model from uri.path() and strip both
  ?query and :action verb defensively in extract_gemini_model_from_path
* forwarder + response_processor + handlers: introduce
  ActiveConnectionGuard (RAII) so active_connections decrement covers
  the full streaming body lifetime, not just response headers
* claude_desktop_config: use sort_by_key to clear the clippy gate
2026-05-14 09:23:21 +08:00
Jason 85131d37d8 refactor(proxy): extract handle_rectifier_retry_failure helper
The signature (RECT-003) and budget (RECT-012) rectifier branches each
carried ~50 lines of identical "provider error -> record + continue /
client error -> release permit + return" handling. The only piece that
varied between them was a log label ("整流" vs "budget 整流").

Move the shared logic into RequestForwarder::handle_rectifier_retry_failure
that returns Option<ForwardError> — None means "continue to the next
provider", Some(err) means "terminal failure, return to the client".
Each call site shrinks from ~50 lines to ~17, drops one level of
indentation, and the two branches now provably cannot drift apart.

forwarder.rs nets ~40 lines smaller.
2026-05-14 08:22:07 +08:00
Jason 039784af73 refactor(proxy): share auth_header_value helper across provider adapters
claude.rs and gemini.rs each defined an identical `hv` closure that wrapped
`HeaderValue::from_str` into a ProxyError::AuthError result, and codex.rs
spelled the same conversion out inline. /simplify reviewers flagged this
as drift-prone copy-paste.

Move the conversion into a single `pub fn auth_header_value` in
providers/adapter.rs and have the three adapters import it locally. Same
error wording everywhere, one place to update if HeaderValue semantics
ever change.
2026-05-14 08:21:53 +08:00
Jason 3c35972548 fix(proxy-ui): accept IPv6 listen addresses in ProxyPanel validation
The backend already understands `::` -> `::1` and wraps IPv6 literals
in brackets (services/proxy.rs), but the panel's save-time validator
only accepted localhost, 0.0.0.0, and IPv4 dotted-quads. Users who
wanted to listen on an IPv6 loopback had to bypass the UI and edit
config directly.

Add an isValidIpv6 helper that requires at least one ':' and round-trips
through `new URL('http://[<addr>]/')` so the platform's built-in IPv6
parser does the heavy lifting (covers compressed `::`, full 8-group
form, zone IDs). Update the invalidAddress copy in zh / en / ja so the
error message reflects the new accepted set.
2026-05-13 23:36:44 +08:00
Jason 5d3d9067af feat(proxy): forward client HTTP method instead of hard-coding POST
The forwarder used to call client.post(&url) / http::Method::POST in
both the reqwest and hyper paths, and the Gemini route table only
registered POST /v1beta/*. As a result anything the Gemini SDK / CLI
sent as GET (models list, models/<id> info) hit a 404 at the router
and bypassed the local proxy's stats, rectifiers, and failover.

Thread the request method end-to-end:

- ProviderAdapter forwarder API now takes the http::Method by reference
  per attempt and dispatches client.request(method, &url) for reqwest
  and method.clone() for the hyper raw path.
- All five callers in handlers.rs (handle_messages_for_app for Claude /
  Claude Desktop, handle_chat_completions, handle_responses,
  handle_responses_compact, handle_gemini) pull the method out of the
  incoming axum::extract::Request and pass it on.
- handle_gemini tolerates an empty body (GET endpoints have none) and
  the forwarder skips serializing / sending a body for GET / HEAD —
  attaching JSON to a GET makes Gemini reject the request.
- server.rs swaps the Gemini routes to any(handle_gemini) so the same
  handler handles GET / POST / PUT / DELETE, and adds /gemini/v1/*
  for the GA path version.
2026-05-13 23:36:36 +08:00
Jason f2ae9823cb fix(proxy): move client-request counters out of per-attempt loop
Three statistics-shape issues fixed together so the dashboard reflects
client requests, not provider attempts:

1. active_connections never moved off zero — the field had no caller in
   the entire crate. Wrap forward_with_retry into a thin entry point
   that saturating_add(1) on enter and saturating_sub(1) on exit; every
   inner return path is covered automatically.

2. total_requests counted attempts, not requests. A single client call
   that failed over P1 -> P2 -> success was recorded as
   total=2 / success=1 -> 50% success rate. Move the increment and the
   last_request_at refresh into the wrapper so they fire once per
   client request regardless of how many providers were tried.

3. current_provider / current_provider_id stay inside the inner loop
   because they are intentionally per-attempt ("what am I trying right
   now?") — moving them would break the live-failover indicator.

Refactor: split forward_with_retry into a public wrapper + private
forward_with_retry_inner. Every existing `return Err(...)` inside inner
remains correct because the wrapper always runs the decrement on its
return.
2026-05-13 23:28:16 +08:00
Jason b06e0fa538 fix(proxy): wire AppProxyConfig.max_retries into request forwarder
The UI has exposed "请求失败时的重试次数 (0-10, default 3)" since the
auto-failover panel was added, but the value was silently dropped —
RequestForwarder never received it and the per-provider loop walked the
whole list regardless. From the user's perspective the setting was
inert.

Thread AppProxyConfig.max_retries through create_forwarder into
RequestForwarder, derive max_attempts = max_retries + 1 (so max_retries=0
matches the UI copy "0 retries" = single attempt), and break the loop
once attempts hit the cap. The check is placed before the circuit
breaker allow-permit so an over-cap iteration does not waste a HalfOpen
probe slot.

When auto-failover is disabled we also force max_retries to 0, mirroring
how timeouts already bypass in that mode — "no failover" should mean
"one provider, one try", not "limited retries against the same list".
2026-05-13 23:25:15 +08:00
Jason 84aa87c3dd fix(proxy): map Anthropic tool_choice to OpenAI Chat nested form
The Chat-Completions transformer used to forward tool_choice verbatim,
but the two APIs disagree on shape:

  Anthropic   "any" | {"type":"tool","name":"X"}
  OpenAI Chat "required" | {"type":"function","function":{"name":"X"}}

Pass-through made the upstream return 400 for any tool-forcing client
(Claude Code, Copilot, etc.). The Responses-API transformer already had
the equivalent map_tool_choice_to_responses helper; this commit adds a
sibling map_tool_choice_to_chat with the chat-specific *nested* function
selector and five regression tests covering string / object × any /
auto / none / tool.

The two helpers are intentionally not merged: the difference between
flat and nested function selectors is exactly what the original bug
was, so keeping them as separate self-documenting functions reduces the
chance of the same regression returning.
2026-05-13 23:20:55 +08:00
Jason cb4ecd3951 fix(proxy): refine failover decisions in forwarder
Two related changes to make per-provider failover behave correctly.

1. Bucket UpstreamError by status code in categorize_proxy_error.

   The old "every UpstreamError is Retryable" rule meant a malformed
   client request (400 / 422) would be replayed against every provider
   in the queue: errors amplified N-fold, the circuit breaker accrued
   unwarranted failure counts, and quota was burned. Now
   400 / 405 / 406 / 413 / 414 / 415 / 422 / 501 are NonRetryable since
   the request itself is wrong and no provider will accept it.
   401 / 403 / 404 / 408 / 409 / 429 / 451 and all 5xx remain Retryable
   because the next provider may carry a different key, quota, region,
   or model mapping.

2. Make the rectifier-retry path participate in failover.

   Both the signature (RECT-003) and budget (RECT-012) rectifier branches
   used to "return Err(...)" after the retry failed, short-circuiting the
   per-provider loop. A provider-side failure (5xx / Timeout /
   ForwardFailed) now records the circuit breaker, accumulates into
   last_error / last_provider, and "continue"s to the next provider —
   matching the normal Retryable arm. Client-side failures still return
   immediately since a different provider cannot fix a malformed payload.
2026-05-13 23:20:45 +08:00
Jason c3d810a22b fix(proxy): tighten takeover detection and use fallback restore on disable
Two related drift bugs in the takeover state machine:

1. The "already taken over?" guard used has_backup OR live_taken_over, so
   either condition alone would short-circuit. After a user or anomalous
   flow restores Live manually the backup row still made set_takeover
   return success, leaving the UI claiming takeover while requests bypass
   the local proxy. Tighten to AND so the rebuild branch repairs the two
   "split brain" states (backup-only and placeholder-only).

2. Disabling takeover called the bare restore_live_config_for_app, which
   silently Ok()s when the backup is missing. If the backup was lost while
   Live still held proxy placeholders (PROXY_MANAGED token / local proxy
   URL), the client config was left broken with no error surfaced. Route
   the disable path through the already-existing
   restore_live_config_for_app_with_fallback (backup → SSOT → cleanup).
   The line 354 takeover-failure rollback intentionally keeps the bare
   variant since that path must preserve the backup for retry.
2026-05-13 23:12:15 +08:00
Jason 9a8f52021d fix(proxy): extract Gemini request model from URI path correctly
split('/') strips the slashes, so find(|s| s.starts_with("models/")) never
matched any segment and request_model fell through to "unknown" for every
Gemini call, poisoning usage records, per-request billing, and logs.

Match the literal "models" segment and take the next one, stripping any
:action suffix and query string. The extraction is now a pub(crate) free
function so it can be unit-tested directly; seven regression tests cover
action suffixes, dotted versions, the /gemini/ proxy prefix, query
strings, the bare list endpoint, and missing-segment paths.
2026-05-13 23:12:06 +08:00
Jason c9a6afc0b7 fix(proxy): return Result from get_auth_headers to avoid panic on bad credentials
User-pasted API keys can contain control chars or CR/LF that make
HeaderValue::from_str return Err; the previous unwrap inside every
adapter turned such input into a process-wide panic instead of a request
error. The trait now returns Result<_, ProxyError>; Claude/Codex/Gemini
impls propagate ProxyError::AuthError so the client sees a 401 with the
underlying parse error instead of a crash. Adds a regression test that
pastes a CRLF-containing key and asserts AuthError.
2026-05-13 23:12:00 +08:00
Jason 58648a9c53 chore: drop trailing blank line in sql_helpers tests
Rustfmt cleanup, no behavioral change.
2026-05-13 23:11:52 +08:00
Jason aa5e58d060 fix(usage): correct cache cost semantics and silence pricing warn storm
- Split CostCalculator into per-app cache semantics: Anthropic's
  input_tokens is already fresh input, while Codex/Gemini include
  cached tokens in their prompt count. The old shared formula
  double-subtracted cache_read for Claude, under-billing input cost.
- Backfill now reads cost_multiplier from the per-log snapshot column
  instead of re-querying providers.meta, so historical rows are no
  longer rewritten with the current multiplier.
- Move the "pricing not found" warn out of find_model_pricing_row;
  emit it only when a brand new log is written, and skip placeholder
  models (unknown / empty / null / none) entirely.
- Broaden model id normalization: strip namespace prefixes
  (anthropic./openai./global./bedrock.), bedrock-style -vN suffixes,
  reasoning effort suffixes (-low/-medium/-high/-xhigh/-minimal),
  Claude Desktop's claude-<non-anthropic> wrapper, dot-to-dash for
  Claude, and try a LIKE prefix match for Claude short route ids
  (e.g. claude-haiku-4-5 -> claude-haiku-4-5-20251001).
- Fall back to request_model when the stored model is missing, so
  early Codex session rows with model=unknown can still be priced.
2026-05-13 17:51:35 +08:00
Jason 4b57f7e113 feat(claude-code): role-based model mapping with display names and 1M flag
- Replace the four flat env inputs with a Sonnet/Opus/Haiku role table.
  Each row exposes ANTHROPIC_DEFAULT_*_MODEL plus a new display name
  field ANTHROPIC_DEFAULT_*_MODEL_NAME, and Sonnet/Opus gain a
  "Declare 1M" checkbox that toggles the [1M] suffix.
- Strip the [1M] context-capability marker before forwarding non-Copilot
  requests upstream. Copilot keeps its existing [1m]->-1m normalization.
- Claude Desktop import now consumes ANTHROPIC_DEFAULT_*_MODEL_NAME as
  label_override, closing the Claude Code -> Claude Desktop displayName
  pipeline; add_route's merge logic is shared between hashmap branches.
- Unify the [1M] marker as ONE_M_CONTEXT_MARKER across
  claude_desktop_config and proxy::model_mapper; rename the strip
  helper to strip_one_m_suffix_for_upstream.
- Collapse useModelState's seven duplicated useState initializers and
  the useEffect parse block into a single parseModelsFromConfig call.
- Add tests/hooks/useModelState.test.tsx and a Claude Desktop import
  test covering Kimi K2 -> label_override. i18n (en/ja/zh) updated.
2026-05-13 17:06:05 +08:00
Jason 84bac6dce6 refactor(claude-desktop): lock route IDs to sonnet/opus/haiku roles
Adapt to Claude Desktop 1.6259.1+ fail-all validation which only
accepts claude-(sonnet|opus|haiku)-* route IDs. Branded model names
(DeepSeek, Kimi, GLM, etc.) now live in a new labelOverride field
instead of being embedded in route IDs.

- Backend auto-repairs legacy unsafe routes to the next free
  sonnet/opus/haiku slot instead of erroring
- Frontend swaps the free-form route input for a role dropdown plus
  menu display name field
- Add CLAUDE_DESKTOP_ROLE_ROUTE_IDS as the single source of truth
  for role-to-route mapping; presets and form both consume it
- Drop the dead displayName alias on ClaudeDesktopModelRoute and the
  ineffective /v1/models display_name injection (UI ignores it)
- Update i18n (en/ja/zh) and form focus test for the new fields
2026-05-13 15:22:23 +08:00
Jason edf28b6422 feat(usage): filter-driven Hero with cache-normalized totals
- Normalize OpenAI/Gemini input_tokens semantics in SQL via the new
  fresh_input_sql helper (cache_read subtracted at query time, no data
  migration). Recovers correct cache hit rates for Codex/Gemini.
- Add get_usage_summary_by_app endpoint for per-app split (single
  UNION ALL + GROUP BY, avoids N+1).
- Replace UsageSummaryCards + AppBreakdownRail with a single
  filter-driven UsageHero card; clicking a filter button now truly
  changes the displayed numbers and the title accent color.
- Tighten KNOWN_APP_TYPES to the 3 app_types whose token data is
  reliably collected (claude/codex/gemini); hide claude-desktop,
  hermes, opencode, openclaw filter buttons and i18n keys.
- Flag cache_creation as N/A for OpenAI-style protocols (Codex,
  Gemini); show a "partial" tooltip when the All view mixes both
  protocol families.
2026-05-13 10:27:29 +08:00
Jason c12364a940 feat(claude-desktop): rework Claude Code import flow
- Derive route keys from the upstream model name (pass-through style)
  instead of fixed Claude aliases, and translate the legacy [1M] suffix
  into the supports1m field at the import boundary. Three Claude aliases
  mapped to the same upstream now collapse to a single route (e.g.
  MiniMax-M2 across SONNET/OPUS/HAIKU env produces one
  claude-MiniMax-M2 -> MiniMax-M2 row), with [1M] OR-aggregated.
- Add an import-time safety net that rebuilds claude-desktop-official
  when missing, so users who deleted it can recover via the normal
  import button without losing customizations on other providers.
- Hide API key and endpoint URL inputs in the official provider edit
  form to mirror Claude Code's behavior and prevent user confusion.
- Reword the empty-state import button label for clarity.
2026-05-12 21:31:30 +08:00
Jason 60a3628360 refactor(claude-desktop): replace [1M] suffix with supports1m field
inferenceModels entries now emit {name, supports1m: true} objects when
1M is enabled (plain strings otherwise), instead of appending a " [1M]"
suffix to model IDs. Route IDs and upstream model IDs are stored
verbatim; the suffix is rejected on input rather than silently stripped,
and proxy request mapping now requires an exact route_id match.
2026-05-12 17:40:32 +08:00
Jason ea4cdaad27 fix(ui): center Monitor badge icon in app switcher
The Monitor glyph's visual weight skews upward (screen rect dominates
while the stand is two thin lines), making it appear off-center inside
the 11px Claude Desktop badge. Add a per-badge offsetY config and
apply translateY(0.5px) to compensate.
2026-05-12 16:43:03 +08:00
Jason 44d4ea81af - 修复 Claude Desktop 模型输入框失焦
- 为动态模型行添加稳定 rowId,避免编辑模型 ID 时重挂载

- 增加模型映射和直连模型列表焦点保持回归测试
2026-05-12 11:47:45 +08:00
Jason 270f49a4a6 - 恢复 Claude Desktop 共享功能入口
- 将 Claude Desktop 的 Prompts、Skills、Sessions 映射到 Claude Code 配置

- 恢复 Claude Desktop 顶部功能按钮组

- 继续复用统一 MCP 面板入口
2026-05-12 11:36:57 +08:00
Jason 6a3c2fe0ba - 支持 Claude Desktop 使用 Copilot/Codex OAuth 供应商
- 放开本地路由托管 OAuth 供应商校验,允许动态 Token
- 新增 Claude Desktop Copilot/Codex 预设与账号选择
- 添加 OAuth proxy 回归测试
2026-05-12 11:30:11 +08:00
Jason 953b7cdcf9 refactor(claude-desktop): drop displayName from model route schema
Claude Desktop's new model menu reads model IDs directly and ignores the
display_name field, so a separate displayName slot added UI noise without
any product value. Collapse the routeId / model / displayName tuple down
to routeId / model, and let the route ID carry the user-visible name
through a non-editable claude- prefix rendered next to the input.

Drop display_name from ClaudeDesktopModelRoute, ClaudeDesktopDefaultRoute,
and ResolvedModelRoute on the Rust side plus the matching TS interfaces,
stop emitting it in /v1/models responses, derive route IDs from upstream
model IDs when picked via the model dropdown, and update zh/en/ja copy to
describe the new two-field layout.
2026-05-12 10:46:35 +08:00
Jason 417ad8149d fix(ui): hide empty toolbar capsule when Claude Desktop is active
Claude Desktop disables Skills, Prompts, Sessions, and MCP, which left
the secondary toolbar capsule next to the app switcher completely empty
but still rendered as a grey rounded pill. Wrap the capsule in an
activeApp !== "claude-desktop" guard so it disappears entirely, and
drop the two inner guards that this outer check makes redundant.
2026-05-11 23:15:57 +08:00
Jason 968c75bdbe feat(ui): use "Claude Code" label in app visibility settings
The app visibility section in Settings showed "Claude" for the first
entry, identical to "Claude Desktop" at a glance. Add a dedicated
i18n key apps.claudeCode and point the settings panel at it, while
leaving apps.claude untouched so other panels (MCP, Skills, Usage,
etc.) keep their shorter "Claude" label.
2026-05-11 23:15:30 +08:00
Jason ed41a7a7b9 feat(ui): distinguish Claude Code vs Claude Desktop in app switcher
The two Claude entries shared the same orange logo, making them hard to
tell apart at a glance. Rename the first entry to "Claude Code" and
overlay a Terminal badge on its logo; overlay a Monitor badge on the
Claude Desktop logo. Changes are scoped to AppSwitcher only; other
panels (MCP, Skills, Usage, etc.) continue to show "Claude".
2026-05-11 22:56:53 +08:00
271 changed files with 36910 additions and 5031 deletions
+207 -1
View File
@@ -7,9 +7,215 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [3.16.0] - 2026-05-29
Development since v3.15.0 focuses on making third-party Codex providers work like first-class citizens through Chat Completions routing, stabilizing Codex provider identity and history, adding an in-app managed CLI tool lifecycle, expanding the partner preset catalog, refreshing the default model / pricing matrix around GPT-5.5 and Claude Opus 4.8, and improving usage observability, localization, docs, and proxy robustness.
**Stats**: 101 commits | 221 files changed | +27,063 insertions | -3,052 deletions
### Highlights
- **Codex Chat Completions routing**: Codex providers can now be served by OpenAI-compatible Chat Completions upstreams. CC Switch converts Codex Responses requests into Chat Completions, rebuilds JSON and SSE responses back into Responses shape, preserves reasoning / `<think>` / tool-call state, normalizes error envelopes, and probes Chat-format providers correctly in Stream Check.
- **Codex third-party provider state is unified and safer**: third-party Codex providers now share the stable `custom` model-provider bucket, with a one-shot migration for historical JSONL sessions and `state_5.sqlite` threads, plus fixes that preserve OAuth login state, user-selected catalog models, and user-authored provider ids during live reads / switches.
- **Managed CLI tool management**: the About page is now a tool management panel for Claude, Codex, Gemini, OpenCode, OpenClaw, and Hermes, with install / update actions, update-all, conflict diagnostics, source-aware anchored upgrades, WSL handling, and visible "installed but not runnable" states.
- **Provider ecosystem and model matrix refresh**: added APIKEY.FUN, APINebula, AtlasCloud, SudoCode, Xiaomi MiMo Token Plan, and Claude Desktop Official presets; refreshed partner links and default models / pricing across apps; upgraded the default Claude Opus model line to 4.8 and GPT defaults to 5.5 where applicable.
- **Usage and docs polish**: Usage Dashboard updates now react immediately when logs are written, custom usage-script summaries and subagent session-log accounting were fixed, Traditional Chinese UI localization landed, and a German README plus expanded Claude Desktop / Codex Chat / tool-management manuals were added.
- **Proxy and conversion hardening**: fixed Codex Chat reasoning / cache / usage edge cases, DeepSeek Anthropic tool-thinking history, Claude-compatible empty `tool_calls` streams, managed-account takeover auth, MiMo reasoning output, Gemini Native tool-call replay, and several panic-prone proxy paths.
### Added
- **Codex Chat Completions Routing**: Codex providers can now be served by upstreams that only speak the OpenAI Chat Completions API. CC Switch's local proxy converts Codex's outgoing Responses requests into Chat Completions and rebuilds the Chat response (both JSON and SSE) back into Responses shape, preserving `reasoning_content`, inline `<think>` blocks, streamed reasoning summaries, tool calls, and `previous_response_id` follow-ups. A bounded Codex Chat history cache restores tool calls before their tool outputs.
- **22 Codex Third-Party Provider Presets with Chat Routing**: Enabled Chat Completions routing with explicit model catalogs for major Chinese/Asian providers — DeepSeek, Zhipu GLM (+ en), Kimi, MiniMax (+ en), StepFun (+ en), Baidu Qianfan Coding Plan, Bailian, ModelScope, Longcat, BaiLing, Xiaomi MiMo (+ Token Plan), Volcengine Agentplan, BytePlus, DouBao Seed, SiliconFlow (+ en), Novita AI, and Nvidia. Each preset declares its context window so the UI can size the model-mapping rows.
- **Codex Model Mapping Table**: Codex provider forms now expose a model catalog (model + display name + context window per row) that is the single source of truth for the upstream model list, projected to `~/.codex/cc-switch-model-catalog.json`.
- **Codex Chat Providers in Stream Check**: Stream Check now probes Chat-format Codex providers against `/chat/completions` with a Chat-shaped body instead of `/v1/responses`, and aligns its URL fallback order with the production `CodexAdapter` (origin-only base URLs hit `/v1/<endpoint>` first) so a non-404 error on the bare path no longer flags a working provider as down.
- **Codex Chat Reasoning Auto-Detection**: When a Codex provider is served through Chat Completions routing, CC Switch now auto-detects the upstream's reasoning interface from its name, base URL, and model — injecting the correct thinking parameter (`thinking:{type}`, `enable_thinking`, `reasoning_split`, top-level `reasoning_effort`, or OpenRouter's native `reasoning:{effort}` object) with no manual setup. Aggregator/hosting platforms (OpenRouter, SiliconFlow) are matched platform-first, since the same model can expose different reasoning controls on different platforms. Providers that only expose a thinking on/off switch (Kimi, GLM, Qwen, MiniMax, MiMo, SiliconFlow) drop the effort *level* instead of forwarding an unsupported field — so changing Codex's reasoning effort has no effect for them — while providers with real effort tiers (DeepSeek, OpenRouter, and StepFun's `step-3.5-flash-2603` only) pass the level through. OpenRouter specifically uses the native `reasoning:{effort}` object, clamps `max` to `xhigh` (its enum has no `max`), and forwards an explicit `effort:"none"` so reasoning can be turned off.
- **Codex Goal Mode and Remote Compaction Controls**: Codex config editing now exposes a Goal Mode toggle and a Remote Compaction toggle for third-party providers; new Codex templates default to `disable_response_storage = true` while still allowing explicit goal support.
- **Xiaomi MiMo Token Plan Presets**: Added Xiaomi MiMo Token Plan presets with specs aligned to the official documentation (#2803).
- **Claude Desktop Official Preset**: Added a Claude Desktop Official preset that restores the native Claude Desktop login, plus a localized Claude Desktop user guide (en / zh / ja).
- **Managed CLI Tool Lifecycle**: Added silent install / update commands for managed CLI tools, latest-version checks, per-tool and batch actions, update-all, and diagnostics for multiple installations across PATH, Homebrew, npm, pnpm, bun, volta, fnm, nvm, scoop, WinGet, Windows native paths, and WSL.
- **Source-Aware Tool Diagnostics**: The Settings / About surface can now diagnose conflicting tool installations, show the concrete install source and version for each path, and generate backend-planned upgrade commands anchored to the actual installation source.
- **Real-Time Usage Refresh**: The backend now emits `usage-log-recorded` when proxy logs, session-log syncs, or rollups write usage data; Usage Dashboard listens for that event and invalidates its queries immediately instead of waiting for the next polling interval (#3027).
- **Traditional Chinese Localization**: Added `zh-TW` UI localization and a settings language option (#3093).
- **German README**: Added `README_DE.md` and linked it from the existing README language switchers (#2994).
- **New Partner Presets**: Added APIKEY.FUN, APINebula, AtlasCloud, and SudoCode partner presets across the supported app surfaces, with partner copy, icons, and README entries.
### Changed
- **Codex Third-Party Providers Unified into a "custom" History Bucket**: Codex filters resume history by `model_provider`, so switching between provider-specific ids made past sessions appear to vanish. All third-party providers now normalize to a single stable `custom` bucket (reserved built-in ids like `openai` / `ollama` are preserved), with a one-shot device migration that rewrites historical JSONL sessions and the `state_5.sqlite` threads table and backs up originals under `~/.cc-switch/backups/codex-history-provider-migration-v1/`.
- **Codex Provider Form Simplified**: Removed the API Format selector from the Codex form (`wire_api` is always `responses`, so the selector misleadingly implied a protocol change); the model mapping table is now the only source of truth with no hidden default entries, and the form notes that a Codex restart is required after catalog changes since `model_catalog_json` is loaded at startup. Only the "Needs Local Routing" toggle remains.
- **Codex Local Routing Toggle Hints Rewritten**: Reframed the OFF / ON hints as action guidance (when to enable) rather than scenario descriptions, synced across zh / en / ja.
- **Codex Live Config Preservation**: Live Codex config reads no longer force-rewrite a user's `model_provider` field, and provider-scoped `experimental_bearer_token` handling now preserves OAuth login state when switching between third-party providers.
- **Tool Install / Upgrade Strategy**: Managed tool installation now prefers official native installers where available, falls back to package managers when appropriate, runs self-update first for compatible tools, anchors upgrades to the detected install source, and locks duplicate batch actions while work is in flight.
- **About Page Becomes Tool Management**: The About settings page now presents installed / latest versions, install and update actions, conflict diagnostics, WSL shell preferences, and clearer status for broken or unrunnable tools.
- **Default Models and Pricing Refreshed**: Upgraded the default Claude Opus model to 4.8, moved GPT-based presets and templates to GPT-5.5 where applicable, refreshed pricing seeds, aligned Claude Desktop model mapping with Claude Code's three-role tiers, and renamed the OpenCode Go preset to drop a stale model suffix.
- **Partner Links Refreshed**: Updated ShengSuanYun referral links, Atlas Cloud UTM links, and partner copy across README locales and provider metadata.
- **Homebrew Official Cask Installation**: Installation simplified to `brew install --cask cc-switch` now that CC Switch is in the official Homebrew repository; the personal-tap requirement was removed from all READMEs.
- **Shared Frontend Utilities**: Replaced JSON stringify / parse deep-copy patterns with a shared `deepClone` helper and extracted a shared `useTauriEvent` hook (#3140).
### Fixed
- **OpenAI Responses API usage parsing robustness**: Hardened `build_anthropic_usage_from_responses()` and the Responses → Anthropic SSE translator so a missing or malformed upstream `usage` no longer produces `"usage": null` in `message_delta`. This unblocks strict Anthropic clients (notably the VSCode Claude Code extension) that crashed with "Cannot read properties of null (reading 'output_tokens')" against providers such as Codex OAuth and DashScope's `compatible-mode/v1/responses` endpoint. Added OpenAI field-name fallbacks (`prompt_tokens` / `completion_tokens`), null/empty/partial object handling, and preserved cache token fields even when input/output tokens are missing (#2422).
- **Codex Chat Error Responses Converted to Responses Envelope**: The Codex Chat-to-Responses bridge previously passed upstream error bodies through untouched, leaving Codex clients unable to recognize MiniMax `base_resp`, raw OpenAI Chat errors, or plain-text / HTML error pages. Errors are now regularized into the standard `{error: {message, type, code, param}}` envelope with the original HTTP status preserved; non-JSON bodies are wrapped and truncated to 1KB at a UTF-8 char boundary. Also fixed a pre-existing append-vs-insert bug that emitted a duplicate `Content-Type` header on rewritten JSON bodies.
- **Codex Mid-Stream System Messages Collapsed**: MiniMax's OpenAI-compatible endpoint strict-rejects any non-leading `system` message (error 2013). All `system` fragments are now collapsed into a single leading message (joined in original order), losslessly for permissive backends too.
- **Codex Model Catalog Wiped After Restart**: Editing the active Codex provider triggered a live read that omitted `modelCatalog`, so a subsequent save silently destroyed user-configured model mappings. Live reads now reverse-parse the on-disk catalog projection to round-trip the same shape the save path writes.
- **Codex Model Catalog Infinite Render Loop**: Broke a bidirectional sync cycle between the catalog table and its parent state that caused severe UI jittering when adding or editing entries.
- **Codex Chat Preserves User-Selected Catalog Model**: A model the client selects from the catalog (e.g. via `/model`) is no longer overwritten by `config.toml`'s default model.
- **Codex Chat Reasoning and Cache Stability**: Restored a unique call-id fallback when Codex omits or rewrites `previous_response_id`, stopped deriving cache identity from `previous_response_id`, and canonicalized parseable JSON string payloads in tool conversions for stable prefix-cache reuse.
- **Codex Chat Streaming Usage Recovered**: The Responses-to-Chat conversion now injects `stream_options.include_usage` (merging into any client-provided `stream_options`) when a request is streaming, so OpenAI-compatible upstreams like Kimi and MiniMax emit the trailing usage chunk again. Previously their streamed token / cost / cache stats were recorded as zero on the Codex Chat path.
- **Codex Chat Tool-Call Reasoning Backfill**: Thinking models like Kimi/Moonshot and DeepSeek reject an assistant message that carries `tool_calls` without a non-empty `reasoning_content`. When cross-turn history recovery misses (proxy restart, ambiguous `call_id`, or a turn with no upstream reasoning), a placeholder `reasoning_content` is now backfilled in a final pass — genuine trailing reasoning still attaches first — so the request no longer fails with `reasoning_content is missing in assistant tool call message`.
- **Managed-Account Claude Takeover Auth**: Managed-account providers (GitHub Copilot / Codex OAuth) now drop token env keys and write only the `ANTHROPIC_API_KEY` placeholder when taking over Claude Live config, with an outbound guard that refuses to send the `PROXY_MANAGED` placeholder upstream.
- **Claude Desktop Profile Sync During Takeover**: Claude Desktop profile data is now synced during proxy takeover, model routes align with the Claude Code three-role tiers, and the Cowork egress profile has been corrected (#3157, #3172).
- **Managed-Account Takeover Model Fields**: Local Routing now sources takeover model fields from the target provider on managed accounts instead of carrying stale model values.
- **DeepSeek Anthropic Tool Thinking History**: Normalized DeepSeek Anthropic-compatible tool-thinking history so later turns can replay reasoning / tool-call context without malformed messages (#3203).
- **Claude-Compatible Empty Tool Calls in Streams**: Fixed a Claude-compatible streaming edge case where an empty `tool_calls` array reset block state and broke streamed responses (#2915).
- **MiMo Reasoning for Claude Code Proxy**: Added MiMo `reasoning_content` support on the Claude Code proxy path (#2990).
- **Gemini Native Tool-Call Robustness**: Fixed `functionResponse.name` resolution (422) and `thought_signature` replay (400) for synthesized tool-call IDs in long multi-turn sessions (#2814).
- **Session Log Subagent Token Accounting**: `collect_jsonl_files()` now scans subagent JSONL logs that were previously missed, so subagent token usage is counted in session cost (session-log mode only) (#2821).
- **Usage Dashboard / Sync Stability**: Fixed a Codex usage-sync panic on non-ASCII model names, custom usage-script summaries, and missing real-time refresh after usage rollups (#3027, #3129).
- **ZhiPu Coding-Plan Quota Tier Ordering**: When the 5-hour bucket is at 0% utilization, ZhiPu's API omits `nextResetTime`; the old `i64::MAX` sentinel sorted those entries last, letting the weekly bucket incorrectly claim the five-hour slot. Tiers now sort so a missing `nextResetTime` maps to the five-hour bucket, so tray and usage quota display stays correct for ZhiPu coding plans.
- **Skills Install by Key**: Installing from skills.sh search results now uses the unique key instead of the directory name, so skills that share a directory name install the correct one (#2784); also fixed a skill sync copy fallback (#2791).
- **Usage Price Input Precision**: Reduced the price input step to 0.0001 so sub-cent costs like DeepSeek cache reads can be entered (#2793, closes #2503).
- **Ghostty Clean Window Launch**: Ghostty now opens a single clean window instead of cloning existing tabs, and other terminals open a new window via `open -na` (#2801, closes #2798).
- **Tool Version and Update Reliability**: Version probing no longer masks unrunnable installs, prerelease tools are handled correctly in version checks, batch updates run per tool, install / update buttons stay locked during preflight, anchored upgrade branches enforce absolute paths, and WSL installer paths use native Unix installers when needed.
- **Codex mise Detection**: Fixed Codex mise environment detection (#2822).
- **Codex Archived Sessions**: Codex archived sessions are now included in session discovery (#2861).
- **Codex Chat Empty Tool Arguments**: Empty tool-call argument payloads are coerced to `{}` during Codex Chat conversion so upstreams and clients receive valid JSON.
- **Claude Provider Deeplink Imports**: Importing Claude providers through deeplinks now preserves custom environment fields (#2928).
- **OMO Recommended Models**: Synced OMO recommended models with upstream defaults and improved Fill Recommended feedback.
- **ShengSuanYun Model IDs Prefixed for Routing**: ShengSuanYun (胜算云) presets now carry the vendor prefixes the upstream gateway requires — `anthropic/…`, `google/…`, and `openai/…` (e.g. `anthropic/claude-sonnet-4.6`, `google/gemini-3.1-pro-preview`) — across the Claude Code, Claude Desktop, Codex, Gemini, OpenCode, and OpenClaw presets, including the Claude Code routing env (`ANTHROPIC_MODEL` / `ANTHROPIC_DEFAULT_{HAIKU,SONNET,OPUS}_MODEL`), so they resolve to valid upstream models instead of failing to route.
- **ClaudeAPI Model Test Re-Enabled**: Reclassified the ClaudeAPI preset (Claude Code and Claude Desktop) from `third_party` to `aggregator` so its model test button is no longer disabled by the third-party Claude gate; the partner star is unaffected since it is driven by `isPartner`, not category.
- **About Version Check**: Version checks now handle prerelease tool versions without misclassifying update state.
- **App Switcher Text Clipping**: Removed a fixed width constraint that clipped app-switcher text (#3161).
- **useEffect Race Condition**: Added an active-flag pattern to App.tsx effects to prevent listener leaks on unmount, and guarded against storing `undefined` language in localStorage (#2827).
### Removed
- **LionCC Sponsor and Presets**: Removed the LionCC sponsor entry and LionCCAPI presets across READMEs, provider configs, and locales (icon asset retained).
- **AICoding Partner Entry**: Removed the AICoding partner from README sponsor listings, provider presets, and i18n metadata.
- **Kimi For Coding Codex Preset**: Removed the Kimi For Coding preset from the Codex preset catalog.
- **CLI Uninstall Command Hints**: Dropped generated CLI uninstall command hints from the tool-management UI while keeping conflict diagnostics visible.
### Docs
- **Codex Chat Provider Support**: Documented Chat Completions routing, provider support, reasoning auto-detection, and Local Routing guidance in the changelog and user manual.
- **Settings Manual Refresh**: Updated settings documentation for the new managed tool lifecycle and Hermes installer behavior.
- **Claude Desktop Guide**: Added localized Claude Desktop guide pages and screenshots for provider setup, import, model mapping, and Local Routing context.
- **Installation Docs**: Updated installation docs and READMEs to recommend the official Homebrew cask and refreshed the v3.15.0 release-note imposter-site warning wording across locales.
## [3.15.0] - 2026-05-16
Development since v3.14.1 focuses on a dedicated Claude Desktop surface with third-party provider switching through a proxy gateway, a large reverse-proxy hardening pass (reliability, retries, cache, takeover, Gemini/Vertex/Codex paths), expansion of the third-party provider preset catalog (BytePlus / Volcengine / ClaudeAPI / ClaudeCN / RunAPI / RelaxyCode / PatewayAI / Baidu Qianfan), role-based model mapping with a 1M context flag, Codex OAuth live model discovery, and a long tail of usage, OAuth, Codex, and session quality-of-life fixes.
**Stats**: 127 commits | 211 files changed | +17,980 insertions | -2,748 deletions
### Highlights
- **Claude Desktop becomes a first-class managed surface** with third-party provider switching through an in-app proxy gateway, role-based model mapping (sonnet / opus / haiku) with a 1M context flag, Copilot/Codex OAuth provider reuse, and 44 imported provider presets translated from the Claude Code catalog. Note: 20 Claude Desktop presets now default to direct mode instead of routing through the proxy — verify connectivity if you previously relied on proxy routing for these presets.
- **Major reverse-proxy hardening**: P0P3 lifecycle, retry, failover, and rectifier patches; pooled HTTPS reuse for non-Anthropic backends; Codex/Responses cache hit-rate improvements; correct Anthropic ↔ OpenAI `tool_choice` mapping; Vertex AI URL preservation; Gemini path-based model extraction; takeover detection refinement; IPv6 listen address support.
- **Provider Ecosystem Expansion**: Added BytePlus, Volcengine Agentplan, ClaudeAPI, ClaudeCN, RunAPI, RelaxyCode, PatewayAI, and Baidu Qianfan Coding Plan partner presets; promoted DouBao Seed to partner status; routing-support badges now surface on provider cards.
- **Role-Based Model Mapping for Claude Code**: Display-name-aware sonnet / opus / haiku route mapping with a `supports1m` flag replaces the legacy `[1M]` suffix and decouples routing from raw model IDs.
- **Codex OAuth Live Model Discovery**: ChatGPT Codex providers now fetch the live model list from the ChatGPT backend on demand instead of relying on a static list.
- **Usage Dashboard Filter-Driven Hero**: A new filter-driven Hero card with cache-normalized totals replaces the legacy summary block, paired with cache-cost-semantics fixes that silence a noisy pricing warning storm.
- **DeepSeek tool-call reasoning and zero-usage final deltas**: DeepSeek tool calls now return `reasoning_content` alongside `tool_calls` (#2543), and the final `message_delta` event always includes a usage block (even when zero) so strict Anthropic clients no longer crash on `null` (#2485).
### Added
- **Claude Desktop Third-Party Provider Switching via Proxy Gateway**: Added a dedicated Claude Desktop surface that brokers third-party Claude providers through CC Switch's in-app proxy, with a routing-support badge for providers that need it, role-based model route mapping locked to `sonnet` / `opus` / `haiku`, Copilot/Codex OAuth provider reuse, a redesigned Claude Code import flow, app-switcher differentiation between "Claude Code" and "Claude Desktop", and 44 provider presets translated from the Claude Code catalog.
- **Routing Support Badges on Provider Cards**: Provider cards in both Claude Code and Codex panels now show a routing-support badge so users can tell at a glance which providers can be served through Local Routing.
- **Codex OAuth Live Model List**: ChatGPT Codex providers now fetch the current model list from the ChatGPT backend on demand, replacing the previously hardcoded selection.
- **Role-Based Model Mapping with 1M Flag**: Claude Code model mapping is now role-based (`sonnet` / `opus` / `haiku`) with display names and a `supports1m` flag, replacing the legacy `[1M]` suffix to decouple routing from raw model IDs.
- **Filter-Driven Usage Hero**: The usage dashboard's Hero summary is now filter-driven with cache-normalized totals so the figures line up with the active date range and provider filters.
- **Provider Form "Save Anyway" Prompt**: Softened provider form validation with a "save anyway" prompt so non-blocking input issues no longer prevent saving (#2307).
- **Universal Provider Duplicate Action**: Added a duplicate action for universal providers from the provider list (#2416).
- **Persisted Tauri Window State**: Window position and size now persist across launches (#2377).
- **Tray Icon Tooltip**: The system tray icon now shows a tooltip on hover for clearer at-a-glance state (#2417).
- **Warp Terminal Session Launch**: Added support for launching Warp and executing a saved session inside it (#2466).
- **DeepSeek `reasoning_content` for Tool Calls**: DeepSeek tool-calling responses now return `reasoning_content` together with `tool_calls` so callers can render both (#2543).
- **Baidu Qianfan Coding Plan for Claude Code**: Added a Baidu Qianfan Coding Plan preset for Claude Code (#2322).
- **Compshare Coding Plan Preset (Cross-App)**: Added Compshare Coding Plan preset across claude / codex / hermes / openclaw.
- **Partner Provider Presets**: Added BytePlus, Volcengine Agentplan, ClaudeAPI, ClaudeCN, RunAPI, RelaxyCode, and PatewayAI provider presets; promoted DouBao Seed to partner status with refreshed endpoint and links.
- **44 Claude Desktop Provider Presets**: Translated 44 provider presets from the Claude Code catalog into the new Claude Desktop surface.
### Changed
- **20 Claude Desktop Presets Switched from Proxy to Direct Mode**: 20 Claude Desktop presets now ship in direct mode instead of routing through the proxy by default, reducing setup friction for users who don't need proxy-specific compatibility shims. Verify connectivity if you previously relied on proxy routing for these presets.
- **Claude Desktop Operational Notes**: Switching a Claude Desktop provider now writes CC Switch's managed 3P profile and requires restarting Claude Desktop to take effect; proxy-mode providers require CC Switch Local Routing to stay running.
- **Failover / Local Routing Guardrails**: Failover controls now require the target app's Local Routing takeover to be enabled, and stopping only the proxy service is blocked while any app still depends on takeover state.
- **Usage Accounting Semantics**: Usage summaries now report cache-normalized real total tokens and cache hit rate; historical token and cost totals may shift after deduplication and pricing recalculation, but should be more accurate.
- **Provider Preset Rendering Order**: Provider preset lists now render in author-defined array order with partners prioritized at the top, replacing the previous implicit sort.
- **Model Mapping Hint Copy Simplified**: `modelMappingOffHint` was rewritten as action-oriented copy across zh / en / ja.
- **CC Switch Brand Surface Unified to ccswitch.io**: All in-app and README references now point at ccswitch.io as the sole official website; the release notes template also surfaces ccswitch.io.
- **Theme Switch Simplified**: Removed the circular reveal animation; theme changes are now an instant cross-fade.
- **Claude Code App Switcher Differentiation**: The app switcher now visually distinguishes "Claude Code" from "Claude Desktop" and uses the "Claude Code" label in the app visibility settings.
- **CI: Claude Review on Opus 4.7**: Upgraded the Claude review GitHub Action to Opus 4.7, tuned the prompt to reduce nitpick noise, added an `@claude` review-only Code Action, pinned PR head SHA for checkout, and dropped a `--max-turns 5` limit.
- **Dependency Bumps**: `actions/checkout` 4 → 6 (#2517), `pnpm/action-setup` 5 → 6 (#2518), `softprops/action-gh-release` 2 → 3 (#2519), `actions/stale` 9 → 10 (#2520).
- **DeepSeek Presets Switched to V4**: DeepSeek presets now ship V4 (flash / pro) with refreshed pricing seeds.
- **Codex 1M Context Toggle Hidden in Provider Edit Form**: The 1M context-window toggle is no longer surfaced in the Codex provider edit form to reduce knob count for a setting that has no effect in current Codex deployments.
- **OpenClaudeCode Migrated to MicuAPI Domain**: Updated the OpenClaudeCode preset to the MicuAPI domain; refreshed Micu API links to `micuapi.ai`.
- **CrazyRouter Endpoints Switched to `cn` Subdomain**: Updated CrazyRouter preset endpoints to the `cn` subdomain.
- **RelaxyCode Custom Icon**: Switched RelaxyCode preset icon to a custom `relaxcode.png` asset.
- **Kimi For Coding Doc URL**: Updated Kimi For Coding website URL to the `/code/docs/` path.
- **SiliconFlow International Site Shows USD**: Balance display now correctly shows USD for the SiliconFlow international site (was incorrectly displaying CNY).
### Fixed
- **OpenAI Responses API Usage Parsing Robustness**: Hardened `build_anthropic_usage_from_responses()` and the Responses → Anthropic SSE translator so a missing or malformed upstream `usage` no longer produces `"usage": null` in `message_delta`. This unblocks strict Anthropic clients (notably the VSCode Claude Code extension) that crashed with "Cannot read properties of null (reading 'output_tokens')" against providers such as Codex OAuth and DashScope's `compatible-mode/v1/responses` endpoint. Added OpenAI field-name fallbacks (`prompt_tokens` / `completion_tokens`), null/empty/partial object handling, and preserved cache token fields even when input/output tokens are missing (#2422).
- **Proxy Reliability Patches (P0P3)**: Multiple rounds of routing, lifecycle, retry, and rectifier patches across the request-forwarder paths; extracted a shared `handle_rectifier_retry_failure` helper and a shared `auth_header_value` helper across provider adapters.
- **Proxy: Pooled HTTPS Connection Reuse**: Non-Anthropic backends now reuse pooled HTTPS connections instead of opening a fresh TLS session per request, materially reducing per-request latency.
- **Proxy: Forward Client HTTP Method**: The proxy forwards the client's actual HTTP method instead of hard-coding `POST`, so non-POST upstream endpoints (e.g. GET `/v1/models`) work correctly.
- **Proxy: Per-Attempt Counters and `max_retries` Wiring**: Client-request counters moved out of the per-attempt loop, and `AppProxyConfig.max_retries` is now correctly wired into the request forwarder.
- **Proxy: Failover Decision Refinements**: Refined failover decision logic in the forwarder so retryable / unretryable errors are classified more accurately.
- **Proxy: Takeover Detection Tightening**: Tightened takeover detection and use fallback restore when disabling takeover so leftover state no longer strands a provider.
- **Proxy: Anthropic ↔ OpenAI `tool_choice` Mapping**: Anthropic `tool_choice` is now correctly mapped to the OpenAI Chat nested form during format conversion.
- **Proxy: Gemini Request Model Extraction**: Gemini request model is now correctly extracted from the URI path (not the body) so transformed traffic reports the right model.
- **Proxy: Auth Header Error Handling**: `get_auth_headers` now returns `Result` instead of panicking on bad credentials.
- **Proxy: IPv6 Listen Address Validation**: The Proxy panel now accepts IPv6 listen addresses.
- **Proxy: Codex / Responses Cache Hit Rate**: Improved cache hit rate for Codex and OpenAI Responses requests by stabilizing cache key derivation; only emit `prompt_cache_key` when a real client-provided session identity is available so unrelated conversations no longer collapse onto a single key; canonicalize (sort) JSON keys in outgoing request bodies and `tool_call` arguments / `tool_result` content for byte-identical prefix-cache reuse; thread `session_id` into the usage logger for request correlation.
- **Proxy: JSON Schema Underscore Fields Preserved**: Private-parameter filtering now preserves underscore-prefixed field names inside JSON Schema name maps such as `properties`, `patternProperties`, `definitions`, and `$defs`, so user-defined schema keys like `_id` and `_meta` survive the filter.
- **Proxy: Read Tool Empty Pages**: Drop empty pages from `Read` tool inputs so providers don't reject the request (#2472).
- **Proxy: Per-Request Hot-Path Trim**: Trimmed per-request hot-path work and database wait time.
- **Proxy: Real Provider Model Names Under Takeover**: The Claude Code menu now exposes the real provider model names when running under takeover, instead of a stale alias.
- **Proxy: Zero Usage in Final Message Delta**: The final `message_delta` event always includes a usage block (even when zero) so strict Anthropic clients no longer crash on `null` (#2485).
- **Proxy: Streaming `message_delta` Deduplication**: Deduplicated streaming `message_delta` events that some upstreams emit twice (#2366).
- **Proxy: Scoped `reasoning_content` Preserved for Tool Calls**: Tool-call paths now correctly preserve the scoped `reasoning_content` field during transformation; Kimi / Moonshot OpenAI Chat compatibility paths keep the field while generic OpenAI-compatible requests stay free of it (#2367).
- **Proxy: Vertex AI Full URL Preserved**: Full Vertex AI URLs are no longer truncated during proxy forwarding (#2415).
- **Proxy: Leading Billing Header Stripped from System Content**: Strips the leading billing-header content that some upstreams prepend to the system message (#2350).
- **Proxy: Claude Auth Strategy from `ANTHROPIC_*` Env Var**: The Claude auth strategy is now derived from the actual `ANTHROPIC_*` env variable name rather than an opaque heuristic.
- **Third-Party Claude Providers: Disable Model Test**: Model probing is now disabled for third-party Claude providers where the gateway doesn't implement `/v1/models` consistently.
- **Model-Fetch: `/models` Subpath for Anthropic-Compatible Providers**: `/models` discovery now works for Anthropic-compatible subpath providers.
- **Copilot: Claude Model ID Resolution Against Live `/models`**: Copilot-backed providers now resolve Claude model IDs against the live `/models` list to avoid stale ID mismatches.
- **Codex: Skip `environment_context` Injection When Extracting Session Title**: Session title extraction no longer pulls in `environment_context` noise (#2439).
- **Codex: Hide Subagent Sessions**: Codex subagent sessions are now hidden from the main session list (#2445).
- **Codex Startup Live Import Duplication**: Fixed a duplicate-import bug in the Codex startup live-import path (#2590).
- **Codex Provider Switch History Drift**: Switching the active Codex provider no longer changes existing session history (#2349).
- **Codex Usage Log Message**: Corrected a misleading log message for Codex session usage (#2473).
- **Claude: Persist Max Effort via Env**: `max` effort now correctly persists via the env variable on restart (#2493).
- **Claude Desktop: Match Proxy Model Route Without `[1M]` Suffix**: Route matching no longer requires the legacy `[1M]` suffix.
- **Claude Desktop: Provider Form Focus Loss**: Fixed an input that lost focus while editing in the Claude Desktop provider form.
- **Claude Desktop: Spurious Proxy-Stopped Status Alert**: Removed an alert that fired spuriously when the proxy was intentionally stopped.
- **Claude Desktop: Empty Toolbar Capsule Hidden**: Hides the empty toolbar capsule when Claude Desktop is the active app.
- **UI: Monitor Badge Icon Centering**: Centered the Monitor badge icon in the app switcher.
- **Linux: Theme Selection Segfault**: Prevented selecting a theme from causing a segfault on Linux (#2502).
- **Terminal: iTerm Fallback on Cold Launch**: Prevented iTerm from being selected as a fallback on cold launch when not actually present (#2448).
- **Config: Sort JSON Keys Alphabetically**: Config writes now sort JSON keys alphabetically for deterministic output (#2469).
- **Import Existing Side-Effect Free**: Made "import existing" side-effect free (#2429).
- **Coding Plan: Zhipu Weekly Tier by Reset Time**: Corrected the Zhipu weekly tier name to match the actual reset time (#2420).
- **DashScope: Usage Parsing Robustness**: Hardened DashScope usage parsing so a malformed payload no longer crashes the VSCode Claude Code extension (#2425).
- **Usage: Prevent Double-Counting Between Proxy and Session-Log Sources**: Deduplicated usage records sourced from both the proxy and session logs.
- **Usage: Cache Cost Semantics + Pricing Warn Storm**: Corrected cache-cost semantics and silenced a noisy pricing warning storm that fired on every request.
- **CI: Frontend Formatting and Linux Clippy Restored**: Restored frontend formatting and Linux clippy checks in CI.
- **Proxy Test Helper Clippy Warning**: Fixed a clippy warning in the proxy test helper.
### Removed
- **Hermes Agent Usage Tracking Integration**: Removed the in-cycle Hermes Agent usage tracking integration after upstream behavior changes made it impractical to keep in sync. The integration was never enabled in any released version — a zero-cost rendering bug found during its development was fixed before the integration was rolled back.
- **Theme Switch Circular Reveal Animation**: Removed the circular reveal animation used during theme switching; the animation caused jank on slower compositors and added little visible value.
- **DDSHub Partner Integration**: Removed DDSHub as a partner preset and dropped the cross-link blurbs across READMEs.
### Docs
- **README Sponsor Refresh (zh / en / ja)**: Added BytePlus, ClaudeCN, RunAPI, and PatewayAI sponsor entries; cross-linked BytePlus and Volcengine entries; refreshed the Crazyrouter $2 credit claim flow, the Compshare blurb, the Right Code blurb, and other sponsor logos and listings; flattened the LionCC logo onto a white background; switched the Chinese README's sponsor logo to the Volcengine artwork; added Hermes Agent to the README subtitles.
- **Release Notes Template**: Surfaces `ccswitch.io` in the release notes template.
- **Brand Surface**: Documented `ccswitch.io` as the sole official website across READMEs and in-app references.
## [3.14.1] - 2026-04-23
+18 -20
View File
@@ -13,7 +13,7 @@
### 🌐 The Only Official Website: **[ccswitch.io](https://ccswitch.io)**
English | [中文](README_ZH.md) | [日本語](README_JA.md) | [Changelog](CHANGELOG.md)
English | [中文](README_ZH.md) | [日本語](README_JA.md) | [Deutsch](README_DE.md) | [Changelog](CHANGELOG.md)
</div>
@@ -63,7 +63,7 @@ Register now via <a href="https://pateway.ai/?ch=etzpm8&aff=WB6M6F67#/">this lin
<tr>
<td width="180"><a href="https://www.byteplus.com/en/product/modelark?utm_campaign=hw&utm_content=ccswitch&utm_medium=devrel_tool_web&utm_source=OWO&utm_term=ccswitch"><img src="assets/partners/logos/byteplus.png" alt="BytePlus" width="150"></a></td>
<td>Thanks to Dola seed for sponsoring this project! Dola Seed 2.0 is a fullmodal general large model independently developed by ByteDance for the global market. Built on a unified multimodal architecture, it supports joint understanding and generation of text, images, audio, and video. It natively enables agent collaboration, with strong reasoning, longtask execution, tool integration, and coding capabilities. It is widely applicable to smart cockpits, personal assistants, education, customer support, marketing, retail, and other scenarios. It excels in multimodal perception, endtoend complex task delivery, stable interaction, and data security, and is readily accessible and deployable via the ModelArk platform.Register via <a href="https://www.byteplus.com/en/product/modelark?utm_campaign=hw&utm_content=ccswitch&utm_medium=devrel_tool_web&utm_source=OWO&utm_term=ccswitch">this link</a> to get 500,000 tokens of free inference quota per model.</td>
<td>Thanks to Dola seed for sponsoring this project! Dola Seed 2.0 is a fullmodal general large model independently developed by ByteDance for the global market. Built on a unified multimodal architecture, it supports joint understanding and generation of text, images, audio, and video. It natively enables agent collaboration, with strong reasoning, longtask execution, tool integration, and coding capabilities. It is widely applicable to smart cockpits, personal assistants, education, customer support, marketing, retail, and other scenarios. It excels in multimodal perception, endtoend complex task delivery, stable interaction, and data security, and is readily accessible and deployable via the ModelArk platform.Register via <a href="https://www.byteplus.com/en/product/modelark?utm_campaign=hw&utm_content=ccswitch&utm_medium=devrel_tool_web&utm_source=OWO&utm_term=ccswitch">this link</a> to get 500,000 tokens of free inference quota per model.<a href="https://www.volcengine.com/activity/agentplan?utm_campaign=hw&utm_content=ccswitch&utm_medium=devrel_tool_web&utm_source=OWO&utm_term=ccswitch"> >>中国大陆地区的开发者请点击这里</a></td>
</tr>
<tr>
@@ -86,11 +86,6 @@ Register now via <a href="https://pateway.ai/?ch=etzpm8&aff=WB6M6F67#/">this lin
<td>Thanks to Compshare for sponsoring this project! Compshare is UCloud's AI cloud platform, providing stable and comprehensive domestic and international model APIs with just one key. Featuring cost-effective monthly and per-use domestic-model Coding Plan packages, alongside stable officially-relayed overseas models. Supports Claude Code, Codex, and API access. Enterprise-grade high concurrency, 24/7 technical support, and self-service invoicing. Users who register via <a href="https://www.compshare.cn/coding-plan?ytag=GPU_YY_YX_git_cc-switch">this link</a> will receive a free 5 CNY platform trial credit!</td>
</tr>
<tr>
<td width="180"><a href="https://aicoding.sh/i/CCSWITCH"><img src="assets/partners/logos/aicoding.jpg" alt="AICoding" width="150"></a></td>
<td>Thanks to AICoding.sh for sponsoring this project! AICoding.sh — Global AI Model API Relay Service at Unbeatable Prices! Claude Code at 19% of original price, GPT at just 1%! Trusted by hundreds of enterprises for cost-effective AI services. Supports Claude Code, GPT, Gemini and major domestic models, with enterprise-grade high concurrency, fast invoicing, and 24/7 dedicated technical support. CC Switch users who register via <a href="https://aicoding.sh/i/CCSWITCH">this link</a> get 10% off their first top-up!</td>
</tr>
<tr>
<td width="180"><a href="https://crazyrouter.com/register?aff=OZcm&ref=cc-switch"><img src="assets/partners/logos/crazyrouter.png" alt="Crazyrouter" width="150"></a></td>
<td>Thanks to Crazyrouter for sponsoring this project! Crazyrouter is a high-performance AI API aggregation platform — one API key for 300+ models including Claude Code, Codex, Gemini CLI, and more. All models at 55% of official pricing with auto-failover, smart routing, and unlimited concurrency. Crazyrouter offers an exclusive deal for CC Switch users: register via <a href="https://crazyrouter.com/register?aff=OZcm&ref=cc-switch">this link</a> and contact customer support to claim <strong>$2 free credit</strong>, plus enter promo code `CCSWITCH` on your first top-up for an extra <strong>30% bonus credit</strong>! </td>
@@ -121,22 +116,11 @@ Register now via <a href="https://pateway.ai/?ch=etzpm8&aff=WB6M6F67#/">this lin
<td>Thanks to CTok.ai for sponsoring this project! CTok.ai is dedicated to building a one-stop AI programming tool service platform. We offer professional Claude Code packages and technical community services, with support for Google Gemini and OpenAI Codex. Through carefully designed plans and a professional tech community, we provide developers with reliable service guarantees and continuous technical support, making AI-assisted programming a true productivity tool. Click <a href="https://ctok.ai">here</a> to register!</td>
</tr>
<tr>
<td width="180"><a href="https://vibecodingapi.ai"><img src="assets/partners/logos/lioncc.png" alt="LionCC" width="150"></a></td>
<td>Thanks to LionCC for sponsoring this project! LionCC is built for Vibe Coders who pursue the ultimate development experience. We provide stable, low-latency, and competitively priced computing services for Claude Code, Codex, and OpenClaw, saving up to 50% in costs. After registering, add customer service on WeChat (HSQBJ088888888) with the code "cc-switch" to receive $10 in free credits (10 million tokens). For other collaborations, follow the blog @LionCC.ai. Click <a href="https://vibecodingapi.ai">here</a> to register!</td>
</tr>
<tr>
<td width="180"><a href="https://console.claudeapi.com/register?aff=pCLD"><img src="assets/partners/logos/claudeapi.png" alt="ClaudeAPI" width="150"></a></td>
<td>This project is sponsored by <a href="https://console.claudeapi.com/register?aff=pCLD">Claude API</a>. Direct Claude API access — connect Claude Code and Agent apps in 3 minutes. New users can claim a free trial credit.Powered by official Anthropic API keys + AWS Bedrock official channels. No reverse engineering, no model degradation. Full support for Opus / Sonnet / Haiku model lineup, with official capabilities preserved including Tool Use, 1M context window, and more. Built for Claude Code power users, Agent engineers, and enterprise engineering teams. Invoicing and dedicated team support available. Click <a href="https://console.claudeapi.com/register?aff=pCLD">here</a> to register!</td>
</tr>
<tr>
<td width="180"><a href="https://ddshub.short.gy/ccswitch"><img src="assets/partners/logos/dds.png" alt="DDS" width="150"></a></td>
<td>Thanks to DDS for sponsoring this project! DDS Hub is a reliable and high-performance Claude API proxy service. We provides cost-effective domestic Claude direct acceleration services for both individual and enterprise users. We offer stable and low-latency Claude Max number pools, with full support for Claude Haiku, Opus, Sonnet and other flagship models. Invoices are available for recharges of 1000 RMB or more. Enterprise customers can also enjoy customized grouping and dedicated technical support services.
Exclusive benefit for CC Switch users: Register via <a href="https://ddshub.short.gy/ccswitch">the link </a>below and enjoy an extra 10% credit on your first recharge (please contact the group admin to claim after recharging)!</td>
</tr>
<tr>
<td width="180"><a href="https://claudecn.top"><img src="assets/partners/logos/claudecn.jpg" alt="ClaudeCN" width="150"></a></td>
<td>Thanks to ClaudeCN for sponsoring this project! ClaudeCN is an enterprise-grade AI gateway platform operated by a registered company. It delivers high-availability commercial API access to popular models including Claude, GPT, and DeepSeek, and is built around formal enterprise procurement workflows — corporate bank transfers, signed contracts, and full compliance. Register via <a href="https://claudecn.top">this link</a>!</td>
@@ -147,6 +131,21 @@ Exclusive benefit for CC Switch users: Register via <a href="https://ddshub.shor
<td>Thanks to RunAPI for sponsoring this project! RunAPI is a high-performance and reliable AI model API gateway — one API key gives you access to 150+ mainstream models including OpenAI, Claude, Gemini, DeepSeek, and Grok, with prices as low as 10% of the official rate and excellent stability. It works seamlessly with Claude Code, OpenClaw, and other tools. Exclusive benefit for CC Switch users: register and contact customer support to claim a free ¥14 credit. Register via <a href="https://runapi.co">this link</a>!</td>
</tr>
<tr>
<td width="180"><a href="https://apikey.fun/register?aff=CCSwitch"><img src="assets/partners/logos/apikey_banner.png" alt="APIKEY.FUN" width="150"></a></td>
<td>Thanks to APIKEY.FUN for sponsoring this project! APIKEY.FUN is a professional enterprise-grade AI relay platform dedicated to providing stable, efficient, and low-cost AI model API access for enterprises and individual developers. The platform supports popular mainstream models such as Claude, OpenAI, and Gemini, with prices as low as 7% of official rates. Register through this project's <a href="https://apikey.fun/register?aff=CCSwitch">exclusive link</a> to enjoy an exclusive offer of up to <strong>permanent 5% off top-ups</strong>.</td>
</tr>
<tr>
<td width="180"><a href="https://apinebula.com/02rw5X"><img src="assets/partners/logos/apinebula_banner.png" alt="APINebula" width="150"></a></td>
<td>Thanks to APINEBULA for sponsoring this project! APINEBULA, an enterprise-grade AI aggregation platform under Galaxy Video Bureau, leverages extensive platform resources to provide developers, teams, and enterprises with stable, cost-effective access to large language model APIs. The platform integrates leading, full-powered models like Claude, GPT, and Gemini, allowing you to connect to the world's top AI models through a single API, with prices starting as low as 10% of the original cost. Designed for AI programming, Agent development, and business system integration, APINEBULA supports enterprise-grade high concurrency, formal contracts, corporate bank transfers, and invoicing services. APINEBULA provides special discounts for our software users: register using <a href="https://apinebula.com/02rw5X">this link</a> and enter the <strong>"ccswitch"</strong> promo code during your first recharge to get <strong>10% off</strong>.</td>
</tr>
<tr>
<td width="180"><a href="https://www.atlascloud.ai/coding-plan?utm_source=github&utm_campaign=cc-switch"><img src="assets/partners/logos/atlascloud_banner.png" alt="Atlas Cloud" width="150"></a></td>
<td>Atlas Cloud is a full-modal AI inference platform that gives developers a single AI API to access video generation, image generation, and LLM APIs. Instead of managing multiple vendor integrations, you connect once and get unified access to 300+ curated models across all modalities. Check out Atlas Cloud's new <a href="https://www.atlascloud.ai/coding-plan?utm_source=github&utm_campaign=cc-switch">coding plan</a> promotion for more budget-friendly API access!</td>
</tr>
</table>
</details>
@@ -173,7 +172,7 @@ Modern AI-powered coding relies on CLI tools like Claude Code, Codex, Gemini CLI
## Features
[Full Changelog](CHANGELOG.md) | [Release Notes](docs/release-notes/v3.12.3-en.md)
[Full Changelog](CHANGELOG.md) | [Release Notes](docs/release-notes/v3.15.0-en.md)
### Provider Management
@@ -303,7 +302,6 @@ Download the latest `CC-Switch-v{version}-Windows.msi` installer or `CC-Switch-v
**Method 1: Install via Homebrew (Recommended)**
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
+533
View File
@@ -0,0 +1,533 @@
<div align="center">
# CC Switch
### Der All-in-One-Manager für Claude Code, Codex, Gemini CLI, OpenCode, OpenClaw & Hermes Agent
[![Version](https://img.shields.io/github/v/release/farion1231/cc-switch?color=blue&label=version)](https://github.com/farion1231/cc-switch/releases)
[![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-lightgrey.svg)](https://github.com/farion1231/cc-switch/releases)
[![Built with Tauri](https://img.shields.io/badge/built%20with-Tauri%202-orange.svg)](https://tauri.app/)
[![Downloads](https://img.shields.io/github/downloads/farion1231/cc-switch/total)](https://github.com/farion1231/cc-switch/releases/latest)
<a href="https://trendshift.io/repositories/15372" target="_blank"><img src="https://trendshift.io/api/badge/repositories/15372" alt="farion1231%2Fcc-switch | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
### 🌐 Die einzige offizielle Website: **[ccswitch.io](https://ccswitch.io)**
[English](README.md) | [中文](README_ZH.md) | [日本語](README_JA.md) | Deutsch | [Changelog](CHANGELOG.md)
</div>
## ❤️Sponsoren
> [Möchten Sie hier erscheinen?](mailto:farion1231@gmail.com)
<details open>
<summary>Zum Einklappen klicken</summary>
[![MiniMax](assets/partners/banners/minimax-en.jpeg)](https://platform.minimax.io/subscribe/coding-plan?code=ClLhgxr2je&source=link)
MiniMax-M2.7 ist ein großes Sprachmodell der nächsten Generation, das auf autonome Weiterentwicklung und praxisnahe Produktivität ausgelegt ist. Anders als herkömmliche Modelle beteiligt sich M2.7 aktiv an seiner eigenen Verbesserung — durch Agententeams, dynamische Werkzeugnutzung und Reinforcement-Learning-Schleifen. Es liefert starke Leistung im Software-Engineering (56,22 % bei SWE-Pro, 55,6 % bei VIBE-Pro, 57,0 % bei Terminal Bench 2) und überzeugt bei komplexen Büro-Workflows mit einem führenden Wert von 1495 ELO bei GDPval-AA. Mit originalgetreuer Bearbeitung von Word-, Excel- und PowerPoint-Dateien sowie einer Befolgungsrate von 97 % über 40+ komplexe Skills hinweg setzt M2.7 einen neuen Standard für den Aufbau KI-nativer Workflows und Organisationen.
[Klicken Sie hier](https://platform.minimax.io/subscribe/coding-plan?code=ClLhgxr2je&source=link), um exklusive 12 % Rabatt auf den MiniMax Token Plan zu erhalten!
---
<table>
<tr>
<td width="180"><a href="https://www.packyapi.com/register?aff=cc-switch"><img src="assets/partners/logos/packycode.png" alt="PackyCode" width="150"></a></td>
<td>Danke an PackyCode für die Unterstützung dieses Projekts! PackyCode ist ein zuverlässiger und effizienter API-Relay-Anbieter, der Relay-Dienste für Claude Code, Codex, Gemini und mehr bereitstellt. PackyCode bietet Sonderrabatte für Nutzer unserer Software: Registrieren Sie sich über <a href="https://www.packyapi.com/register?aff=cc-switch">diesen Link</a> und geben Sie beim ersten Aufladen den Gutscheincode „cc-switch" ein, um 10 % Rabatt zu erhalten.</td>
</tr>
<tr>
<td width="180"><a href="https://aigocode.com/invite/CC-SWITCH"><img src="assets/partners/logos/aigocode.png" alt="AIGoCode" width="150"></a></td>
<td>Danke an AIGoCode für die Unterstützung dieses Projekts! AIGoCode ist eine All-in-One-Plattform, die Claude Code, Codex und die neuesten Gemini-Modelle integriert und Ihnen stabile, effiziente und äußerst kostengünstige KI-Coding-Dienste bietet. Die Plattform stellt flexible Abonnementpläne bereit, birgt kein Risiko einer Kontosperrung, ermöglicht Direktzugriff ohne VPN und reagiert blitzschnell. AIGoCode hat ein besonderes Angebot für CC-Switch-Nutzer vorbereitet: Wenn Sie sich über <a href="https://aigocode.com/invite/CC-SWITCH">diesen Link</a> registrieren, erhalten Sie bei Ihrer ersten Aufladung zusätzliche 10 % Bonusguthaben!</td>
</tr>
<tr>
<td width="180"><a href="https://www.shengsuanyun.com/?from=CH_4HHXMRYF"><img src="assets/partners/logos/shengsuanyun.png" alt="Shengsuanyun" width="150"></a></td>
<td>Danke an Shengsuanyun für die Unterstützung dieses Projekts! Shengsuanyun ist eine Superfabrik für KI-native Teams — eine Plattform zur parallelen Ausführung von KI-Aufgaben in industrieller Qualität. Ihr Modellmarktplatz bündelt die Fähigkeiten von Claude, ChatGPT, Gemini und weiteren in- und ausländischen LLM- und Multimedia-Modellen mit Direktbezug. Absolut kein Reverse Engineering und keine Verwässerung — die plattformweite Modell-SLA-Verfügbarkeit erreicht 99,7 %, und die <a href="https://watch.shengsuanyun.com/status/shengsuanyun">Monitoring-Dashboards</a> zeigen durchgehend grün an. Es bietet außerdem unternehmensgerechte, anpassbare Gateways für fein abgestufte Kosten- und Berechtigungsverwaltung im Team, intelligentes Routing, Sicherheitsschutz und BYOK-Hosting (Bring Your Own Key). Die Plattform rechnet nach Nutzung sowie über einen Token-Plan (in Kürze verfügbar) ab, und Rechnungsstellung ist möglich. Registrieren Sie sich über <a href="https://www.shengsuanyun.com/?from=CH_4HHXMRYF">diesen Link</a> als Neukunde und erhalten Sie ein Guthaben von ¥10 sowie 10 % Bonus auf Ihre erste Aufladung.</td>
</tr>
<tr>
<td width="180"><a href="https://www.aicodemirror.com/register?invitecode=9915W3"><img src="assets/partners/logos/aicodemirror.jpg" alt="AICodeMirror" width="150"></a></td>
<td>Danke an AICodeMirror für die Unterstützung dieses Projekts! AICodeMirror stellt offizielle, hochstabile Relay-Dienste für Claude Code / Codex / Gemini CLI bereit, mit unternehmensgerechter Nebenläufigkeit, schneller Rechnungsstellung und rund um die Uhr verfügbarem dediziertem technischem Support.
Offizielle Kanäle von Claude Code / Codex / Gemini zu 38 % / 2 % / 9 % des Originalpreises, mit zusätzlichen Rabatten beim Aufladen! AICodeMirror bietet besondere Vorteile für CC-Switch-Nutzer: Registrieren Sie sich über <a href="https://www.aicodemirror.com/register?invitecode=9915W3">diesen Link</a> und erhalten Sie 20 % Rabatt auf Ihre erste Aufladung; Unternehmenskunden erhalten bis zu 25 % Rabatt!</td>
</tr>
<tr>
<td width="180"><a href="https://pateway.ai/?ch=etzpm8&aff=WB6M6F67#/"><img src="assets/partners/logos/pateway.png" alt="PatewayAI" width="150"></a></td>
<td>Danke an PatewayAI für die Unterstützung dieses Projekts! PatewayAI ist ein API-Relay-Anbieter für anspruchsvolle KI-Entwickler, der sich auf das direkte Relayen offizieller hochwertiger Modell-APIs konzentriert. Er bietet die komplette Claude-Reihe und die Codex-Serie, zu 100 % aus offiziellen Kanälen bezogen — keine Verwässerung, keine Fälschungen, Überprüfung ausdrücklich erwünscht. Die Abrechnung ist transparent, und jede Rechnung auf Token-Ebene lässt sich Zeile für Zeile prüfen.
Er unterstützt zudem unternehmensgerechte Nebenläufigkeit und stellt Unternehmenskunden eine dedizierte Verwaltungsplattform bereit — formelle Verträge und Rechnungsstellung sind verfügbar; Kontaktdaten finden Sie auf der offiziellen Website.
Registrieren Sie sich jetzt über <a href="https://pateway.ai/?ch=etzpm8&aff=WB6M6F67#/">diesen Link</a> und erhalten Sie ein Testguthaben von 3 $. Aufladungen sind ab 60 % des Originalpreises möglich, mit einem beidseitigen Empfehlungsbonus von bis zu 150 $!</td>
</tr>
<tr>
<td width="180"><a href="https://www.byteplus.com/en/product/modelark?utm_campaign=hw&utm_content=ccswitch&utm_medium=devrel_tool_web&utm_source=OWO&utm_term=ccswitch"><img src="assets/partners/logos/byteplus.png" alt="BytePlus" width="150"></a></td>
<td>Danke an Dola seed für die Unterstützung dieses Projekts! Dola Seed 2.0 ist ein voll-modales Allzweck-Großmodell, das von ByteDance eigenständig für den globalen Markt entwickelt wurde. Aufbauend auf einer einheitlichen multimodalen Architektur unterstützt es das gemeinsame Verstehen und Generieren von Text, Bildern, Audio und Video. Es ermöglicht von Haus aus die Zusammenarbeit von Agenten und verfügt über starke Fähigkeiten in den Bereichen Schlussfolgern, Ausführung langer Aufgaben, Werkzeugintegration und Programmierung. Es ist breit einsetzbar — etwa für intelligente Cockpits, persönliche Assistenten, Bildung, Kundensupport, Marketing, Einzelhandel und weitere Szenarien. Es überzeugt bei multimodaler Wahrnehmung, der Ende-zu-Ende-Bewältigung komplexer Aufgaben, stabiler Interaktion und Datensicherheit und ist über die ModelArk-Plattform einfach zugänglich und bereitstellbar. Registrieren Sie sich über <a href="https://www.byteplus.com/en/product/modelark?utm_campaign=hw&utm_content=ccswitch&utm_medium=devrel_tool_web&utm_source=OWO&utm_term=ccswitch">diesen Link</a> und erhalten Sie pro Modell ein kostenloses Inferenzkontingent von 500.000 Token.<a href="https://www.volcengine.com/activity/agentplan?utm_campaign=hw&utm_content=ccswitch&utm_medium=devrel_tool_web&utm_source=OWO&utm_term=ccswitch"> >>中国大陆地区的开发者请点击这里</a></td>
</tr>
<tr>
<td width="180"><a href="https://cloud.siliconflow.cn/i/drGuwc9k"><img src="assets/partners/logos/silicon_en.jpg" alt="SiliconFlow" width="150"></a></td>
<td>Danke an SiliconFlow für die Unterstützung dieses Projekts! SiliconFlow ist eine leistungsstarke KI-Infrastruktur- und Modell-API-Plattform, die schnellen und zuverlässigen Zugriff auf Sprach-, Audio-, Bild- und Videomodelle an einem Ort bietet. Mit nutzungsbasierter Abrechnung, breiter Unterstützung multimodaler Modelle, Hochgeschwindigkeitsinferenz und unternehmensgerechter Stabilität hilft SiliconFlow Entwicklern und Teams, KI-Anwendungen effizienter zu erstellen und zu skalieren. Registrieren Sie sich über <a href="https://cloud.siliconflow.cn/i/drGuwc9k">diesen Link</a> und schließen Sie die Identitätsverifizierung ab, um ein Bonusguthaben von ¥16 zu erhalten, das für alle Modelle der Plattform nutzbar ist. SiliconFlow ist zudem nun mit OpenClaw kompatibel, sodass Nutzer einen SiliconFlow-API-Schlüssel verbinden und große KI-Modelle kostenlos aufrufen können.</td>
</tr>
<tr>
<td width="180"><a href="https://cubence.com/signup?code=CCSWITCH&source=ccs"><img src="assets/partners/logos/cubence.png" alt="Cubence" width="150"></a></td>
<td>Danke an Cubence für die Unterstützung dieses Projekts! Cubence ist ein zuverlässiger und effizienter API-Relay-Anbieter, der Relay-Dienste für Claude Code, Codex, Gemini und mehr mit flexiblen Abrechnungsoptionen einschließlich nutzungsbasierter und monatlicher Pläne bereitstellt. Cubence bietet Sonderrabatte für CC-Switch-Nutzer: Registrieren Sie sich über <a href="https://cubence.com/signup?code=CCSWITCH&source=ccs">diesen Link</a> und geben Sie beim Aufladen den Gutscheincode „CCSWITCH" ein, um bei jeder Aufladung 10 % Rabatt zu erhalten!</td>
</tr>
<tr>
<td width="180"><a href="https://www.dmxapi.cn/register?aff=bUHu"><img src="assets/partners/logos/dmx-en.jpg" alt="DMXAPI" width="150"></a></td>
<td>Danke an DMXAPI für die Unterstützung dieses Projekts! DMXAPI stellt mehr als 200 Unternehmenskunden globale Großmodell-API-Dienste bereit. Ein API-Schlüssel für alle Modelle weltweit. Zu den Funktionen gehören: sofortige Rechnungsstellung, unbegrenzte Nebenläufigkeit, ab 0,15 $, technischer Support rund um die Uhr. GPT/Claude/Gemini durchgehend zu 32 % Rabatt, inländische Modelle 2050 % Rabatt, exklusive Claude-Code-Modelle zu 66 % Rabatt! <a href="https://www.dmxapi.cn/register?aff=bUHu">Hier registrieren</a></td>
</tr>
<tr>
<td width="180"><a href="https://www.compshare.cn/coding-plan?ytag=GPU_YY_YX_git_cc-switch"><img src="assets/partners/logos/ucloud.png" alt="Compshare" width="150"></a></td>
<td>Danke an Compshare für die Unterstützung dieses Projekts! Compshare ist die KI-Cloud-Plattform von UCloud, die mit nur einem Schlüssel stabile und umfassende in- und ausländische Modell-APIs bereitstellt. Sie bietet kostengünstige Coding-Plan-Pakete für inländische Modelle mit monatlicher und nutzungsbasierter Abrechnung sowie stabile, offiziell gerelayte ausländische Modelle. Unterstützt Claude Code, Codex und API-Zugriff. Unternehmensgerechte hohe Nebenläufigkeit, technischer Support rund um die Uhr und Self-Service-Rechnungsstellung. Wer sich über <a href="https://www.compshare.cn/coding-plan?ytag=GPU_YY_YX_git_cc-switch">diesen Link</a> registriert, erhält ein kostenloses Plattform-Testguthaben von 5 CNY!</td>
</tr>
<tr>
<td width="180"><a href="https://crazyrouter.com/register?aff=OZcm&ref=cc-switch"><img src="assets/partners/logos/crazyrouter.png" alt="Crazyrouter" width="150"></a></td>
<td>Danke an Crazyrouter für die Unterstützung dieses Projekts! Crazyrouter ist eine leistungsstarke KI-API-Aggregationsplattform — ein API-Schlüssel für mehr als 300 Modelle, darunter Claude Code, Codex, Gemini CLI und weitere. Alle Modelle zu 55 % des offiziellen Preises, mit automatischem Failover, intelligentem Routing und unbegrenzter Nebenläufigkeit. Crazyrouter bietet ein exklusives Angebot für CC-Switch-Nutzer: Registrieren Sie sich über <a href="https://crazyrouter.com/register?aff=OZcm&ref=cc-switch">diesen Link</a> und kontaktieren Sie den Kundensupport, um <strong>2 $ Gratisguthaben</strong> zu erhalten; geben Sie zusätzlich bei Ihrer ersten Aufladung den Gutscheincode `CCSWITCH` ein, um <strong>30 % Bonusguthaben</strong> zu bekommen! </td>
</tr>
<tr>
<td width="180"><a href="https://www.right.codes/register?aff=CCSWITCH"><img src="assets/partners/logos/rightcode.jpg" alt="RightCode" width="150"></a></td>
<td>Danke an Right Code für die Unterstützung dieses Projekts! Right Code stellt zuverlässig Routing-Dienste für Modelle wie Claude Code, Codex und Gemini bereit, wahlweise mit nutzungsbasierter Abrechnung oder monatlichem Abonnement. Rechnungen sind beim Aufladen verfügbar, und Unternehmens- sowie Teamkunden erhalten dedizierten Einzelsupport. Right Code bietet außerdem einen exklusiven Rabatt für CC-Switch-Nutzer: Registrieren Sie sich über <a href="https://www.right.codes/register?aff=CCSWITCH">diesen Link</a> und erhalten Sie bei jeder Aufladung nutzungsbasiertes Guthaben in Höhe von 5 % des gezahlten Betrags.</td>
</tr>
<tr>
<td width="180"><a href="https://www.sssaicode.com/register?ref=DCP0SM"><img src="assets/partners/logos/sssaicode.png" alt="SSSAiCode" width="150"></a></td>
<td>Danke an SSSAiCode für die Unterstützung dieses Projekts! SSSAiCode ist ein stabiler und zuverlässiger API-Relay-Dienst, der sich der Bereitstellung stabiler, zuverlässiger und erschwinglicher Claude- und Codex-Modelldienste widmet, mit schneller Rechnungsstellung am selben Tag. SSSAiCode bietet ein besonderes Angebot für CC-Switch-Nutzer: Registrieren Sie sich über <a href="https://www.sssaicode.com/register?ref=DCP0SM">diesen Link</a> und erhalten Sie bei jeder Aufladung 10 $ zusätzliches Guthaben!</td>
</tr>
<tr>
<td width="180"><a href="https://www.micuapi.ai/register?aff=aOYQ"><img src="assets/partners/logos/mikubanner.svg" alt="Micu" width="150"></a></td>
<td>Danke an Micu API für die Unterstützung dieses Projekts! Micu API ist ein globaler LLM-Relay-Anbieter, der sich der Bereitstellung des besten Preis-Leistungs-Verhältnisses bei hoher Stabilität widmet. Gestützt auf ein eingetragenes Unternehmen als Kernabsicherung wird jedes Risiko einer Diensteinstellung ausgeschlossen, mit schneller offizieller Rechnungsstellung! Wir stehen für „kostenloses Ausprobieren": Aufladungen sind schon ab ¥1 ohne Mindestbetrag möglich, und gebührenfreie Rückerstattungen sind jederzeit möglich! Micu API bietet ein exklusives Angebot für CC-Switch-Nutzer: Registrieren Sie sich über <a href="https://www.micuapi.ai/register?aff=aOYQ">diesen Link</a> und geben Sie beim Aufladen den Gutscheincode „ccswitch" ein, um <strong>10 % Rabatt</strong> zu erhalten!</td>
</tr>
<tr>
<td width="180"><a href="https://lemondata.cc/r/FFX1ZDUP"><img src="assets/partners/logos/lemondata.png" alt="LemonData" width="150"></a></td>
<td>Danke an LemonData für die Unterstützung dieses Projekts! LemonData ist eine leistungsstarke KI-API-Aggregationsplattform — ein API-Schlüssel für mehr als 300 Modelle, darunter GPT, Claude, Gemini, DeepSeek und weitere. Alle Modelle zu Preisen 3070 % unter den offiziellen Tarifen, mit automatischem Failover, intelligentem Routing und unbegrenzter Nebenläufigkeit. Neukunden erhalten bei der Registrierung sofort 1 $ Gratisguthaben — registrieren Sie sich über <a href="https://lemondata.cc/r/FFX1ZDUP">diesen Link</a>, um Ihren Bonus einzulösen und sofort mit dem Entwickeln zu beginnen</strong>!</td>
</tr>
<tr>
<td width="180"><a href="https://ctok.ai"><img src="assets/partners/logos/ctok.png" alt="CTok" width="150"></a></td>
<td>Danke an CTok.ai für die Unterstützung dieses Projekts! CTok.ai widmet sich dem Aufbau einer Komplettlösung für KI-Programmierwerkzeuge. Wir bieten professionelle Claude-Code-Pakete und Dienste einer technischen Community, mit Unterstützung für Google Gemini und OpenAI Codex. Durch sorgfältig gestaltete Pläne und eine professionelle Tech-Community geben wir Entwicklern verlässliche Servicegarantien und kontinuierlichen technischen Support an die Hand und machen KI-gestützte Programmierung zu einem echten Produktivitätswerkzeug. Klicken Sie <a href="https://ctok.ai">hier</a>, um sich zu registrieren!</td>
</tr>
<tr>
<td width="180"><a href="https://console.claudeapi.com/register?aff=pCLD"><img src="assets/partners/logos/claudeapi.png" alt="ClaudeAPI" width="150"></a></td>
<td>Dieses Projekt wird von <a href="https://console.claudeapi.com/register?aff=pCLD">Claude API</a> gesponsert. Direkter Claude-API-Zugriff — verbinden Sie Claude Code und Agent-Apps in 3 Minuten. Neukunden können ein kostenloses Testguthaben einlösen. Betrieben mit offiziellen Anthropic-API-Schlüsseln + offiziellen AWS-Bedrock-Kanälen. Kein Reverse Engineering, keine Modellverschlechterung. Volle Unterstützung der Modellreihe Opus / Sonnet / Haiku, mit erhaltenen offiziellen Fähigkeiten einschließlich Tool Use, 1M-Kontextfenster und mehr. Entwickelt für Claude-Code-Power-User, Agent-Ingenieure und technische Unternehmensteams. Rechnungsstellung und dedizierter Team-Support verfügbar. Klicken Sie <a href="https://console.claudeapi.com/register?aff=pCLD">hier</a>, um sich zu registrieren!</td>
</tr>
<tr>
<td width="180"><a href="https://claudecn.top"><img src="assets/partners/logos/claudecn.jpg" alt="ClaudeCN" width="150"></a></td>
<td>Danke an ClaudeCN für die Unterstützung dieses Projekts! ClaudeCN ist eine unternehmensgerechte KI-Gateway-Plattform, die von einem eingetragenen Unternehmen betrieben wird. Sie bietet hochverfügbaren kommerziellen API-Zugriff auf beliebte Modelle wie Claude, GPT und DeepSeek und ist auf formelle Unternehmensbeschaffungsprozesse ausgerichtet — Banküberweisungen von Firmen, unterzeichnete Verträge und volle Compliance. Registrieren Sie sich über <a href="https://claudecn.top">diesen Link</a>!</td>
</tr>
<tr>
<td width="180"><a href="https://runapi.co"><img src="assets/partners/logos/runapi.jpg" alt="RunAPI" width="150"></a></td>
<td>Danke an RunAPI für die Unterstützung dieses Projekts! RunAPI ist ein leistungsstarkes und zuverlässiges KI-Modell-API-Gateway — ein API-Schlüssel gibt Ihnen Zugriff auf mehr als 150 gängige Modelle, darunter OpenAI, Claude, Gemini, DeepSeek und Grok, zu Preisen ab 10 % des offiziellen Tarifs und mit ausgezeichneter Stabilität. Es arbeitet nahtlos mit Claude Code, OpenClaw und weiteren Werkzeugen zusammen. Exklusiver Vorteil für CC-Switch-Nutzer: Registrieren Sie sich und kontaktieren Sie den Kundensupport, um ein kostenloses Guthaben von ¥14 einzulösen. Registrieren Sie sich über <a href="https://runapi.co">diesen Link</a>!</td>
</tr>
<tr>
<td width="180"><a href="https://apikey.fun/register?aff=CCSwitch"><img src="assets/partners/logos/apikey_banner.png" alt="APIKEY.FUN" width="150"></a></td>
<td>Danke an APIKEY.FUN für die Unterstützung dieses Projekts! APIKEY.FUN ist eine professionelle KI-Relay-Plattform auf Enterprise-Niveau, die Unternehmen und einzelnen Entwicklern stabilen, effizienten und kostengünstigen Zugriff auf KI-Modell-APIs bietet. Die Plattform unterstützt beliebte Mainstream-Modelle wie Claude, OpenAI und Gemini, mit Preisen ab 7 % der offiziellen Tarife. Wer sich über den <a href="https://apikey.fun/register?aff=CCSwitch">exklusiven Link</a> dieses Projekts registriert, kann ein exklusives Angebot von bis zu <strong>dauerhaft 5 % Rabatt auf Aufladungen</strong> erhalten.</td>
</tr>
<tr>
<td width="180"><a href="https://apinebula.com/02rw5X"><img src="assets/partners/logos/apinebula_banner.png" alt="APINebula" width="150"></a></td>
<td>Danke an APINEBULA für die Unterstützung dieses Projekts! APINEBULA ist eine Enterprise-KI-Aggregationsplattform unter Galaxy Video Bureau und nutzt umfangreiche Plattformressourcen, um Entwicklern, Teams und Unternehmen stabilen und kosteneffizienten Zugang zu APIs großer Sprachmodelle zu bieten. Die Plattform bündelt führende vollwertige Modelle wie Claude, GPT und Gemini. Über eine einzige API erhalten Sie Zugriff auf weltweit führende KI-Modelle, mit Preisen ab 10 % des Originalpreises. APINEBULA ist für KI-Programmierung, Agent-Entwicklung und Integration in Geschäftssysteme ausgelegt und unterstützt enterprise-grade hohe Parallelität, formale Verträge, Firmenüberweisungen und Rechnungsstellung. APINEBULA bietet Nutzern dieser Software besondere Rabatte: Registrieren Sie sich über <a href="https://apinebula.com/02rw5X">diesen Link</a> und geben Sie beim ersten Aufladen den Aktionscode <strong>"ccswitch"</strong> ein, um <strong>10 % Rabatt</strong> zu erhalten.</td>
</tr>
<tr>
<td width="180"><a href="https://www.atlascloud.ai/coding-plan?utm_source=github&utm_campaign=cc-switch"><img src="assets/partners/logos/atlascloud_banner.png" alt="Atlas Cloud" width="150"></a></td>
<td>Atlas Cloud ist eine vollmodale KI-Inferenzplattform, die Entwicklern über eine einzige KI-API Zugriff auf Videogenerierung, Bildgenerierung und LLM-APIs bietet. Statt mehrere Anbieterintegrationen zu verwalten, verbinden Sie sich einmal und erhalten einheitlichen Zugriff auf mehr als 300 kuratierte Modelle über alle Modalitäten hinweg. Sehen Sie sich die neue <a href="https://www.atlascloud.ai/coding-plan?utm_source=github&utm_campaign=cc-switch">Coding-Plan</a>-Aktion von Atlas Cloud für kostengünstigeren API-Zugang an!</td>
</tr>
</table>
</details>
## Warum CC Switch?
Modernes KI-gestütztes Programmieren stützt sich auf CLI-Werkzeuge wie Claude Code, Codex, Gemini CLI, OpenCode und OpenClaw — doch jedes hat sein eigenes Konfigurationsformat. Der Wechsel des API-Anbieters bedeutet, JSON-, TOML- oder `.env`-Dateien von Hand zu bearbeiten, und es gibt keine einheitliche Möglichkeit, MCP und Skills über mehrere Werkzeuge hinweg zu verwalten.
**CC Switch** gibt Ihnen eine einzige Desktop-App, um alle fünf CLI-Werkzeuge zu verwalten. Statt Konfigurationsdateien von Hand zu bearbeiten, erhalten Sie eine visuelle Oberfläche, um Anbieter mit einem Klick zu importieren und sofort zwischen ihnen zu wechseln — mit 50+ integrierten Anbieter-Presets, einheitlicher MCP- und Skills-Verwaltung und schnellem Umschalten über das System-Tray. Das Ganze gestützt auf eine zuverlässige SQLite-Datenbank mit atomaren Schreibvorgängen, die Ihre Konfigurationen vor Beschädigung schützen.
- **Eine App, fünf CLI-Werkzeuge** — Verwalten Sie Claude Code, Codex, Gemini CLI, OpenCode und OpenClaw über eine einzige Oberfläche
- **Kein manuelles Bearbeiten mehr** — 50+ Anbieter-Presets einschließlich AWS Bedrock, NVIDIA NIM und Community-Relays; einfach auswählen und umschalten
- **Einheitliche MCP- & Skills-Verwaltung** — Ein Panel zur Verwaltung von MCP-Servern und Skills über vier Apps hinweg mit bidirektionaler Synchronisierung
- **Schnellumschaltung über System-Tray** — Wechseln Sie Anbieter sofort über das Tray-Menü, ohne die vollständige App öffnen zu müssen
- **Cloud-Synchronisierung** — Synchronisieren Sie Anbieterdaten geräteübergreifend über Dropbox, OneDrive, iCloud oder WebDAV-Server
- **Plattformübergreifend** — Native Desktop-App für Windows, macOS und Linux, gebaut mit Tauri 2
- **Integrierte Hilfsprogramme** — Enthält diverse Hilfsprogramme für die Login-Bestätigung beim Erststart, das Umgehen von Signaturen, die Synchronisierung von Plugin-Erweiterungen und mehr
## Screenshots
| Hauptoberfläche | Anbieter hinzufügen |
| :-----------------------------------------------: | :--------------------------------------------: |
| ![Hauptoberfläche](assets/screenshots/main-en.png) | ![Anbieter hinzufügen](assets/screenshots/add-en.png) |
## Funktionen
[Vollständiges Changelog](CHANGELOG.md) | [Release Notes](docs/release-notes/v3.15.0-en.md)
### Anbieterverwaltung
- **5 CLI-Werkzeuge, 50+ Presets** — Claude Code, Codex, Gemini CLI, OpenCode, OpenClaw; Schlüssel kopieren und mit einem Klick importieren
- **Universelle Anbieter** — Eine Konfiguration synchronisiert sich mit mehreren Apps (OpenCode, OpenClaw)
- Umschaltung mit einem Klick, Schnellzugriff über System-Tray, Sortierung per Drag-and-drop, Import/Export
### Proxy & Failover
- **Lokaler Proxy mit Hot-Switching** — Formatkonvertierung, automatisches Failover, Circuit Breaker, Anbieter-Health-Monitoring und Request-Rectifier
- **Übernahme auf App-Ebene** — Claude, Codex oder Gemini unabhängig über den Proxy leiten, bis hinunter auf einzelne Anbieter
### MCP, Prompts & Skills
- **Einheitliches MCP-Panel** — Verwalten Sie MCP-Server über 4 Apps hinweg mit bidirektionaler Synchronisierung und Deep-Link-Import
- **Prompts** — Markdown-Editor mit App-übergreifender Synchronisierung (CLAUDE.md / AGENTS.md / GEMINI.md) und Backfill-Schutz
- **Skills** — Installation mit einem Klick aus GitHub-Repositorys oder ZIP-Dateien, Verwaltung eigener Repositorys, mit Unterstützung für Symlinks und Dateikopien
### Nutzungs- & Kostenverfolgung
- **Nutzungs-Dashboard** — Verfolgen Sie Ausgaben, Anfragen und Token mit Trenddiagrammen, detaillierten Anfrageprotokollen und eigener Preisgestaltung pro Modell
### Session Manager & Workspace
- Durchsuchen, suchen und stellen Sie den Gesprächsverlauf über alle Apps hinweg wieder her
- **Workspace-Editor** (OpenClaw) — Bearbeiten Sie Agent-Dateien (AGENTS.md, SOUL.md usw.) mit Markdown-Vorschau
### System & Plattform
- **Cloud-Synchronisierung** — Eigenes Konfigurationsverzeichnis (Dropbox, OneDrive, iCloud, NAS) und WebDAV-Server-Synchronisierung
- **Deep Link** (`ccswitch://`) — Importieren Sie Anbieter, MCP-Server, Prompts und Skills per URL
- Dunkles / Helles / System-Theme, automatischer Start, automatischer Updater, atomare Schreibvorgänge, automatische Backups, i18n (zh/en/ja)
## FAQ
<details>
<summary><strong>Welche KI-CLI-Werkzeuge unterstützt CC Switch?</strong></summary>
CC Switch unterstützt fünf Werkzeuge: **Claude Code**, **Codex**, **Gemini CLI**, **OpenCode** und **OpenClaw**. Jedes Werkzeug verfügt über dedizierte Anbieter-Presets und Konfigurationsverwaltung.
</details>
<details>
<summary><strong>Muss ich das Terminal nach einem Anbieterwechsel neu starten?</strong></summary>
Bei den meisten Werkzeugen ja — starten Sie Ihr Terminal oder das CLI-Werkzeug neu, damit die Änderungen wirksam werden. Die Ausnahme ist **Claude Code**, das derzeit das Hot-Switching von Anbieterdaten ohne Neustart unterstützt.
</details>
<details>
<summary><strong>Meine Plugin-Konfiguration ist nach einem Anbieterwechsel verschwunden — was ist passiert?</strong></summary>
CC Switch bietet eine Funktion „Gemeinsames Konfigurations-Snippet", um gemeinsame Daten (über API-Schlüssel und Endpunkte hinaus) zwischen Anbietern weiterzugeben. Gehen Sie zu „Anbieter bearbeiten" → „Panel für gemeinsame Konfiguration" → klicken Sie auf „Aus aktuellem Anbieter extrahieren", um alle gemeinsamen Daten zu speichern. Aktivieren Sie beim Anlegen eines neuen Anbieters die Option „Gemeinsame Konfiguration schreiben" (standardmäßig aktiviert), um die Plugin-Daten in den neuen Anbieter aufzunehmen. Alle Ihre Konfigurationspunkte bleiben im Standardanbieter erhalten, der beim ersten Start der App importiert wurde.
</details>
<details>
<summary><strong>Installation unter macOS</strong></summary>
CC Switch für macOS ist von Apple code-signiert und notarisiert. Sie können es direkt herunterladen und installieren — es sind keine zusätzlichen Schritte erforderlich. Wir empfehlen die Verwendung des `.dmg`-Installationsprogramms.
</details>
<details>
<summary><strong>Warum kann ich den aktuell aktiven Anbieter nicht löschen?</strong></summary>
CC Switch folgt dem Designprinzip der „minimalen Eingriffstiefe" — selbst wenn Sie die App deinstallieren, funktionieren Ihre CLI-Werkzeuge weiterhin normal. Das System behält immer eine aktive Konfiguration bei, da das Löschen aller Konfigurationen das entsprechende CLI-Werkzeug unbrauchbar machen würde. Wenn Sie ein bestimmtes CLI-Werkzeug selten verwenden, können Sie es in den Einstellungen ausblenden. Wie Sie zurück zum offiziellen Login wechseln, erfahren Sie in der nächsten Frage.
</details>
<details>
<summary><strong>Wie wechsle ich zurück zum offiziellen Login?</strong></summary>
Fügen Sie einen offiziellen Anbieter aus der Preset-Liste hinzu. Führen Sie nach dem Wechsel den Abmelde-/Anmelde-Vorgang aus; anschließend können Sie frei zwischen dem offiziellen Anbieter und Drittanbietern wechseln. Codex unterstützt den Wechsel zwischen verschiedenen offiziellen Anbietern, was das Umschalten zwischen mehreren Plus- oder Team-Konten erleichtert.
</details>
<details>
<summary><strong>Wo werden meine Daten gespeichert?</strong></summary>
- **Datenbank**: `~/.cc-switch/cc-switch.db` (SQLite — Anbieter, MCP, Prompts, Skills)
- **Lokale Einstellungen**: `~/.cc-switch/settings.json` (gerätebezogene UI-Einstellungen)
- **Backups**: `~/.cc-switch/backups/` (automatisch rotiert, behält die 10 neuesten)
- **Skills**: `~/.cc-switch/skills/` (standardmäßig per Symlink mit den entsprechenden Apps verbunden)
- **Skill-Backups**: `~/.cc-switch/skill-backups/` (vor der Deinstallation automatisch erstellt, behält die 20 neuesten)
</details>
## Dokumentation
Ausführliche Anleitungen zu jeder Funktion finden Sie im **[Benutzerhandbuch](docs/user-manual/en/README.md)** — es deckt Anbieterverwaltung, MCP/Prompts/Skills, Proxy & Failover und mehr ab.
## Schnellstart
### Grundlegende Verwendung
1. **Anbieter hinzufügen**: Klicken Sie auf „Add Provider" → Wählen Sie ein Preset oder erstellen Sie eine eigene Konfiguration
2. **Anbieter wechseln**:
- Hauptoberfläche: Anbieter auswählen → auf „Enable" klicken
- System-Tray: Anbietername direkt anklicken (sofort wirksam)
3. **Wirksam werden**: Starten Sie Ihr Terminal oder das entsprechende CLI-Werkzeug neu, um die Änderungen anzuwenden (Claude Code erfordert keinen Neustart)
4. **Zurück zum Offiziellen**: Fügen Sie ein „Official Login"-Preset hinzu, starten Sie das CLI-Werkzeug neu und folgen Sie dann seinem Login-/OAuth-Vorgang
### MCP, Prompts, Skills & Sessions
- **MCP**: Klicken Sie auf die Schaltfläche „MCP" → Server über Vorlagen oder eigene Konfiguration hinzufügen → Synchronisierung pro App umschalten
- **Prompts**: Klicken Sie auf „Prompts" → Presets mit dem Markdown-Editor erstellen → Aktivieren, um mit den Live-Dateien zu synchronisieren
- **Skills**: Klicken Sie auf „Skills" → GitHub-Repositorys durchsuchen → mit einem Klick in allen Apps installieren
- **Sessions**: Klicken Sie auf „Sessions" → Gesprächsverlauf über alle Apps hinweg durchsuchen, suchen und wiederherstellen
> **Hinweis**: Beim Erststart können Sie bestehende CLI-Werkzeug-Konfigurationen manuell als Standardanbieter importieren.
## Download & Installation
### Systemanforderungen
- **Windows**: Windows 10 und höher
- **macOS**: macOS 12 (Monterey) und höher
- **Linux**: Ubuntu 22.04+ / Debian 11+ / Fedora 34+ und andere gängige Distributionen
### Windows-Nutzer
Laden Sie das neueste Installationsprogramm `CC-Switch-v{version}-Windows.msi` oder die portable Version `CC-Switch-v{version}-Windows-Portable.zip` von der Seite [Releases](../../releases) herunter.
### macOS-Nutzer
**Methode 1: Installation über Homebrew (empfohlen)**
```bash
brew install --cask cc-switch
```
Aktualisieren:
```bash
brew upgrade --cask cc-switch
```
**Methode 2: Manueller Download**
Laden Sie `CC-Switch-v{version}-macOS.dmg` (empfohlen) oder `.zip` von der Seite [Releases](../../releases) herunter.
> **Hinweis**: CC Switch für macOS ist von Apple code-signiert und notarisiert. Sie können es direkt installieren und öffnen.
### Arch-Linux-Nutzer
**Installation über paru (empfohlen)**
```bash
paru -S cc-switch-bin
```
### Linux-Nutzer
Laden Sie den neuesten Linux-Build von der Seite [Releases](../../releases) herunter:
- `CC-Switch-v{version}-Linux.deb` (Debian/Ubuntu)
- `CC-Switch-v{version}-Linux.rpm` (Fedora/RHEL/openSUSE)
- `CC-Switch-v{version}-Linux.AppImage` (universell)
> **Flatpak**: Nicht in den offiziellen Releases enthalten. Sie können es selbst aus dem `.deb` bauen — eine Anleitung finden Sie unter [`flatpak/README.md`](flatpak/README.md).
<details>
<summary><strong>Architekturüberblick</strong></summary>
### Designprinzipien
```
┌─────────────────────────────────────────────────────────────┐
│ Frontend (React + TS) │
│ ┌─────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Components │ │ Hooks │ │ TanStack Query │ │
│ │ (UI) │──│ (Bus. Logic) │──│ (Cache/Sync) │ │
│ └─────────────┘ └──────────────┘ └──────────────────┘ │
└────────────────────────┬────────────────────────────────────┘
│ Tauri IPC
┌────────────────────────▼────────────────────────────────────┐
│ Backend (Tauri + Rust) │
│ ┌─────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Commands │ │ Services │ │ Models/Config │ │
│ │ (API Layer) │──│ (Bus. Layer) │──│ (Data) │ │
│ └─────────────┘ └──────────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
**Kern-Designmuster**
- **SSOT** (Single Source of Truth): Alle Daten werden in `~/.cc-switch/cc-switch.db` (SQLite) gespeichert
- **Zweischichtiger Speicher**: SQLite für synchronisierbare Daten, JSON für gerätebezogene Einstellungen
- **Bidirektionale Synchronisierung**: Schreiben in Live-Dateien beim Umschalten, Backfill aus den Live-Dateien beim Bearbeiten des aktiven Anbieters
- **Atomare Schreibvorgänge**: Das Muster aus temporärer Datei + Umbenennen verhindert die Beschädigung von Konfigurationen
- **Nebenläufigkeitssicher**: Eine durch Mutex geschützte Datenbankverbindung vermeidet Race Conditions
- **Geschichtete Architektur**: Klare Trennung (Commands → Services → DAO → Database)
**Schlüsselkomponenten**
- **ProviderService**: Anbieter-CRUD, Umschaltung, Backfill, Sortierung
- **McpService**: Verwaltung von MCP-Servern, Import/Export, Synchronisierung von Live-Dateien
- **ProxyService**: Lokaler Proxy-Modus mit Hot-Switching und Formatkonvertierung
- **SessionManager**: Durchsuchen des Gesprächsverlaufs über alle unterstützten Apps hinweg
- **ConfigService**: Konfigurations-Import/-Export, Backup-Rotation
- **SpeedtestService**: Messung der Latenz von API-Endpunkten
</details>
<details>
<summary><strong>Entwicklungsleitfaden</strong></summary>
### Umgebungsanforderungen
- Node.js 18+
- pnpm 8+
- Rust 1.85+
- Tauri CLI 2.8+
### Entwicklungsbefehle
```bash
# Abhängigkeiten installieren
pnpm install
# Entwicklungsmodus (Hot Reload)
pnpm dev
# Typprüfung
pnpm typecheck
# Code formatieren
pnpm format
# Codeformatierung prüfen
pnpm format:check
# Frontend-Unit-Tests ausführen
pnpm test:unit
# Tests im Watch-Modus ausführen (für die Entwicklung empfohlen)
pnpm test:unit:watch
# Anwendung bauen
pnpm build
# Debug-Version bauen
pnpm tauri build --debug
```
### Entwicklung des Rust-Backends
```bash
cd src-tauri
# Rust-Code formatieren
cargo fmt
# Clippy-Prüfungen ausführen
cargo clippy
# Backend-Tests ausführen
cargo test
# Bestimmte Tests ausführen
cargo test test_name
# Tests mit dem Feature test-hooks ausführen
cargo test --features test-hooks
```
### Testleitfaden
**Frontend-Tests**:
- Verwendet **vitest** als Test-Framework
- Verwendet **MSW (Mock Service Worker)**, um Tauri-API-Aufrufe zu mocken
- Verwendet **@testing-library/react** für Komponententests
**Tests ausführen**:
```bash
# Alle Tests ausführen
pnpm test:unit
# Watch-Modus (automatische erneute Ausführung)
pnpm test:unit:watch
# Mit Coverage-Bericht
pnpm test:unit --coverage
```
### Tech-Stack
**Frontend**: React 18 · TypeScript · Vite · TailwindCSS 3.4 · TanStack Query v5 · react-i18next · react-hook-form · zod · shadcn/ui · @dnd-kit
**Backend**: Tauri 2.8 · Rust · serde · tokio · thiserror · tauri-plugin-updater/process/dialog/store/log
**Testing**: vitest · MSW · @testing-library/react
</details>
<details>
<summary><strong>Projektstruktur</strong></summary>
```
├── src/ # Frontend (React + TypeScript)
│ ├── components/
│ │ ├── providers/ # Anbieterverwaltung
│ │ ├── mcp/ # MCP-Panel
│ │ ├── prompts/ # Prompts-Verwaltung
│ │ ├── skills/ # Skills-Verwaltung
│ │ ├── sessions/ # Session Manager
│ │ ├── proxy/ # Proxy-Modus-Panel
│ │ ├── openclaw/ # OpenClaw-Konfigurationspanels
│ │ ├── settings/ # Einstellungen (Terminal/Backup/About)
│ │ ├── deeplink/ # Deep-Link-Import
│ │ ├── env/ # Verwaltung von Umgebungsvariablen
│ │ ├── universal/ # App-übergreifende Konfiguration
│ │ ├── usage/ # Nutzungsstatistik
│ │ └── ui/ # shadcn/ui-Komponentenbibliothek
│ ├── hooks/ # Eigene Hooks (Geschäftslogik)
│ ├── lib/
│ │ ├── api/ # Tauri-API-Wrapper (typsicher)
│ │ └── query/ # TanStack-Query-Konfiguration
│ ├── locales/ # Übersetzungen (zh/en/ja)
│ ├── config/ # Presets (providers/mcp)
│ └── types/ # TypeScript-Definitionen
├── src-tauri/ # Backend (Rust)
│ └── src/
│ ├── commands/ # Tauri-Befehlsschicht (nach Domäne)
│ ├── services/ # Geschäftslogikschicht
│ ├── database/ # SQLite-DAO-Schicht
│ ├── proxy/ # Proxy-Modul
│ ├── session_manager/ # Sitzungsverwaltung
│ ├── deeplink/ # Deep-Link-Verarbeitung
│ └── mcp/ # MCP-Synchronisierungsmodul
├── tests/ # Frontend-Tests
└── assets/ # Screenshots & Partnerressourcen
```
</details>
## Mitwirken
Issues und Vorschläge sind willkommen!
Bitte stellen Sie vor dem Einreichen von PRs Folgendes sicher:
- Typprüfung besteht: `pnpm typecheck`
- Formatprüfung besteht: `pnpm format:check`
- Unit-Tests bestehen: `pnpm test:unit`
Eröffnen Sie für neue Funktionen bitte vor dem Einreichen eines PR ein Issue zur Diskussion. PRs für Funktionen, die nicht gut zum Projekt passen, können geschlossen werden.
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=farion1231/cc-switch&type=Date)](https://www.star-history.com/#farion1231/cc-switch&Date)
## Lizenz
MIT © Jason Young
+17 -20
View File
@@ -13,7 +13,7 @@
### 🌐 唯一の公式サイト:**[ccswitch.io](https://ccswitch.io)**
[English](README.md) | [中文](README_ZH.md) | 日本語 | [Changelog](CHANGELOG.md)
[English](README.md) | [中文](README_ZH.md) | 日本語 | [Deutsch](README_DE.md) | [Changelog](CHANGELOG.md)
</div>
@@ -86,11 +86,6 @@ Claude Code / Codex / Gemini 公式チャンネルが最安で元価格の 38% /
<td>Compshare のご支援に感謝します!Compshare は UCloud 傘下の AI クラウドプラットフォームで、国内外の安定した包括的なモデル API を 1 つのキーだけで利用可能。月額・都度課金のコストパフォーマンスに優れた国内モデル Coding Plan パッケージを提供し、公式リレーによる安定した海外モデルも利用できます。Claude Code、Codex および API アクセスに対応。エンタープライズ級の高同時接続、24 時間年中無休のテクニカルサポート、セルフサービス請求書発行に対応。<a href="https://www.compshare.cn/coding-plan?ytag=GPU_YY_YX_git_cc-switch">こちらのリンク</a>から登録すると、無料で 5 元分のプラットフォーム体験クレジットがもらえます!</td>
</tr>
<tr>
<td width="180"><a href="https://aicoding.sh/i/CCSWITCH"><img src="assets/partners/logos/aicoding.jpg" alt="AICoding" width="150"></a></td>
<td>AICoding.sh のご支援に感謝します!AICoding.sh —— グローバル AI モデル API 超お得な中継サービス!Claude Code 81% オフ、GPT 99% オフ!数百社の企業に高コストパフォーマンスの AI サービスを提供。Claude Code、GPT、Gemini および国内主要モデルに対応、エンタープライズ級の高同時接続、迅速な請求書発行、24 時間年中無休の専属テクニカルサポート。<a href="https://aicoding.sh/i/CCSWITCH">こちらのリンク</a>から登録した CC Switch ユーザーは、初回チャージ 10% オフ!</td>
</tr>
<tr>
<td width="180"><a href="https://crazyrouter.com/register?aff=OZcm&ref=cc-switch"><img src="assets/partners/logos/crazyrouter.png" alt="Crazyrouter" width="150"></a></td>
<td>Crazyrouter のご支援に感謝します!Crazyrouter は高性能 AI API アグリゲーションプラットフォームです。1 つの API キーで Claude Code、Codex、Gemini CLI など 300 以上のモデルにアクセス可能。全モデルが公式価格の 55% で利用でき、自動フェイルオーバー、スマートルーティング、無制限同時接続に対応。CC Switch ユーザー向けの限定特典:<a href="https://crazyrouter.com/register?aff=OZcm&ref=cc-switch">こちらのリンク</a>から登録後、カスタマーサポートまでご連絡いただくと <strong>$2 の無料クレジット</strong> を受け取れます。さらに初回チャージ時にプロモコード `CCSWITCH` を入力すると <strong>30% のボーナスクレジット</strong> が追加されます!</td>
@@ -120,23 +115,11 @@ Claude Code / Codex / Gemini 公式チャンネルが最安で元価格の 38% /
<td>CTok.ai のご支援に感謝します!CTok.ai はワンストップ AI プログラミングツールサービスプラットフォームの構築に取り組んでいます。Claude Code のプロフェッショナルプランと技術コミュニティサービスを提供し、Google Gemini や OpenAI Codex にも対応しています。丁寧に設計されたプランと専門的な技術コミュニティを通じて、開発者に安定したサービス保証と継続的な技術サポートを提供し、AI アシストプログラミングを真の生産性ツールにします。<a href="https://ctok.ai">こちら</a>から登録してください!</td>
</tr>
<tr>
<td width="180"><a href="https://vibecodingapi.ai"><img src="assets/partners/logos/lioncc.png" alt="LionCC" width="150"></a></td>
<td>LionCC のご支援に感謝します!LionCC は究極の開発体験を追求する「Vibe Coders」のために生まれました。Claude Code、Codex、OpenClaw 向けに安定・低遅延・お得な価格の計算リソースサービスを提供し、最大 50% のコスト削減を実現します。登録後、カスタマーサービスの WeChatHSQBJ088888888)を追加し、合言葉「cc-switch」を送信すると、10 ドル分のクレジット(1,000 万トークン)がもらえます。その他のコラボレーションについてはブログ @LionCC.ai をフォローしてください。<a href="https://vibecodingapi.ai">こちら</a>から登録してください!</td>
</tr>
<tr>
<td width="180"><a href="https://console.claudeapi.com/register?aff=pCLD"><img src="assets/partners/logos/claudeapi.png" alt="ClaudeAPI" width="150"></a></td>
<td>本プロジェクトは <a href="https://console.claudeapi.com/register?aff=pCLD">Claude API</a> がスポンサーです。Claude API 直結 — わずか 3 分で Claude Code や Agent アプリに接続可能。新規ユーザーにはテストクレジットを提供しています。Anthropic 公式キーおよび AWS Bedrock 公式チャネルに基づいており、リバースエンジニアリングや性能劣化はありません。Opus / Sonnet / Haiku の全モデルラインナップをサポートし、Tool Use や 1M コンテキストなどの公式機能をすべて保持しています。Claude Code ヘビーユーザー、Agent エンジニア、企業技術チームに最適です。請求書発行およびチーム対応が可能です。<a href="https://console.claudeapi.com/register?aff=pCLD">こちら</a>から登録してください!</td>
</tr>
<tr>
<td width="180"><a href="https://ddshub.short.gy/ccswitch"><img src="assets/partners/logos/dds.png" alt="DDS" width="150"></a></td>
<td>本プロジェクトのスポンサーである DDS に感謝いたします! DDS(呆呆獣 / DDS Hub)は、Claude に特化した信頼性とパフォーマンスの高い API プロキシサービスです。個人および企業ユーザーの皆様に、圧倒的なコストパフォーマンスを誇る Claude 直結アクセラレーションサービスを提供しています。Claude Haiku / Opus / Sonnet などのフルスペックモデルを完全サポートし、安定した低遅延のアクセスを実現します。
1,000人民元以上のチャージで領収書(発票)の発行が可能です。さらに、企業のお客様にはカスタマイズされたグループ管理や専用テクニカルサポートをご提供しています。
CC Switch ユーザー限定特典: 専用リンクからご<a href="https://ddshub.short.gy/ccswitch">登録</a>いただくと、初回チャージ時に 10% の追加ボーナスクレジット をプレゼントいたします!(※チャージ完了後、グループ管理人へご連絡の上お受け取りください。)</td>
</tr>
<tr>
<td width="180"><a href="https://claudecn.top"><img src="assets/partners/logos/claudecn.jpg" alt="ClaudeCN" width="150"></a></td>
<td>本プロジェクトのスポンサーである ClaudeCN に感謝いたします!ClaudeCN は、実体のある企業によって運営されるエンタープライズ向け AI ゲートウェイプラットフォームです。Claude、GPT、DeepSeek など主要モデルへの高可用な商用 API アクセスを提供し、企業の調達プロセスにも対応 — 法人振込や正式契約に対応し、コンプライアンス面でも安心してご利用いただけます。<a href="https://claudecn.top">こちら</a>からご登録ください!</td>
@@ -147,6 +130,21 @@ CC Switch ユーザー限定特典: 専用リンクからご<a href="https://d
<td>本プロジェクトのスポンサーである RunAPI に感謝いたします!RunAPI は高効率で安定した AI モデル API ゲートウェイです。一つの API Key で、OpenAI、Claude、Gemini、DeepSeek、Grok など 150 種類以上の主要モデルにアクセス可能。料金は公式価格の最大 10%、安定性にも優れ、Claude Code や OpenClaw などのツールとシームレスに連携できます。CC Switch ユーザー限定特典:ご登録後にカスタマーサポートへご連絡いただくと、14 元の無料クレジットを進呈いたします。<a href="https://runapi.co">こちら</a>からご登録ください!</td>
</tr>
<tr>
<td width="180"><a href="https://apikey.fun/register?aff=CCSwitch"><img src="assets/partners/logos/apikey_banner.png" alt="APIKEY.FUN" width="150"></a></td>
<td>APIKEY.FUN のご支援に感謝します!APIKEY.FUN は、企業および個人開発者向けに安定・高効率・低コストな AI モデル API 接続サービスを提供する、プロフェッショナルなエンタープライズ級 AI リレープラットフォームです。Claude、OpenAI、Gemini などの主要人気モデルに対応し、料金は公式価格の 7% から利用できます。本プロジェクトの<a href="https://apikey.fun/register?aff=CCSwitch">専用リンク</a>から登録すると、最大で<strong>チャージ永久 5% オフ</strong>の特別優待も受けられます。</td>
</tr>
<tr>
<td width="180"><a href="https://apinebula.com/02rw5X"><img src="assets/partners/logos/apinebula_banner.png" alt="APINebula" width="150"></a></td>
<td>本プロジェクトは「APINEBULA」のスポンサーシップにより運営されています!APINEBULA は、「銀河録像局」傘下のエンタープライズ向け AI 統合プラットフォームです。大手の豊富なリソースを背景に、開発者、チーム、そして企業ユーザーの皆様へ、安定性とコストパフォーマンスに優れた大規模言語モデル(LLM)の API 連携サービスを提供しています。Claude、GPT、Gemini をはじめとする世界中の主要なフルスペック(満血)モデルを 1 つの API に集約。世界トップクラスの AI モデルを、<strong>最大 90% OFF(元の価格の 1 割〜)</strong>という圧倒的な低価格でご利用いただけます。また、企業向けの高度な並行処理(高コンカレンシー)、正式な契約締結、法人口座振り込み、請求書・領収書発行など、ビジネス利用に必要なサポートも万全です。AI プログラミング、AI エージェント開発、業務システムへの統合など、様々なシーンに最適です。<a href="https://apinebula.com/02rw5X">こちらのリンク</a>から登録し、チャージ時にプロモコード <strong>「ccswitch」を入力すると、さらに 10% OFF</strong> の割引特典が適用されます!</td>
</tr>
<tr>
<td width="180"><a href="https://www.atlascloud.ai/coding-plan?utm_source=github&utm_campaign=cc-switch"><img src="assets/partners/logos/atlascloud_banner.png" alt="Atlas Cloud" width="150"></a></td>
<td>Atlas Cloud は、1 つの API で動画・画像生成や LLM(大規模言語モデル)を利用できる全モーダル対応の AI 推論プラットフォームです。複数のベンダーを個別に管理する手間を省き、一度の接続で 300 以上の厳選されたマルチモーダルモデルにアクセスできます。より低コストで API を利用できる、開発者向けの新しい<a href="https://www.atlascloud.ai/coding-plan?utm_source=github&utm_campaign=cc-switch">「コーディングプラン」</a>プロモーションをぜひチェックしてください!</td>
</tr>
</table>
</details>
@@ -173,7 +171,7 @@ CC Switch ユーザー限定特典: 専用リンクからご<a href="https://d
## 特長
[完全な更新履歴](CHANGELOG.md) | [リリースノート](docs/release-notes/v3.12.3-ja.md)
[完全な更新履歴](CHANGELOG.md) | [リリースノート](docs/release-notes/v3.15.0-ja.md)
### プロバイダ管理
@@ -303,7 +301,6 @@ CC Switch は「最小限の介入」という設計原則に従っています
**方法 1: Homebrew でインストール(推奨)**
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
+22 -23
View File
@@ -13,7 +13,7 @@
### 🌐 唯一官方网站:**[ccswitch.io](https://ccswitch.io)**
[English](README.md) | 中文 | [日本語](README_JA.md) | [更新日志](CHANGELOG.md)
[English](README.md) | 中文 | [日本語](README_JA.md) | [Deutsch](README_DE.md) | [更新日志](CHANGELOG.md)
</div>
@@ -63,7 +63,7 @@ Claude Code / Codex / Gemini 官方渠道低至 3.8 / 0.2 / 0.9 折,充值更
<tr>
<td width="180"><a href="https://www.volcengine.com/activity/agentplan?utm_campaign=hw&utm_content=ccswitch&utm_medium=devrel_tool_web&utm_source=OWO&utm_term=ccswitch"><img src="assets/partners/logos/huoshan.png" alt="HuoShan" width="150"></a></td>
<td>感谢火山方舟Agent Plan 模型赞助了本项目!方舟Agent Plan 模型订阅套餐集成了包含Doubao-Seed、Doubao-Seedance、Doubao-Seedream等在内的字节跳动自研SOTA级模型,覆盖文本、代码、图像、视频等多模态任务。同时支持一站式接入DeepSeek V4、GLM 5.1等主流大模型。超全模态模型与 Harness 升级一步到位,深度支持 Agent 框架与 AI 编程工具。方舟 Agent Plan 为 CC Switch 的用户提供了专属福利:通过<a href="https://www.volcengine.com/activity/agentplan?utm_campaign=hw&utm_content=ccswitch&utm_medium=devrel_tool_web&utm_source=OWO&utm_term=ccswitch">此链接</a>订阅方舟AgentPlan,新客户首月40元起!</td>
<td>感谢火山方舟Agent Plan 模型赞助了本项目!方舟Agent Plan 模型订阅套餐集成了包含Doubao-Seed、Doubao-Seedance、Doubao-Seedream等在内的字节跳动自研SOTA级模型,覆盖文本、代码、图像、视频等多模态任务。同时支持一站式接入DeepSeek V4、GLM 5.1等主流大模型。超全模态模型与 Harness 升级一步到位,深度支持 Agent 框架与 AI 编程工具。方舟 Agent Plan 为 CC Switch 的用户提供了专属福利:通过<a href="https://www.volcengine.com/activity/agentplan?utm_campaign=hw&utm_content=ccswitch&utm_medium=devrel_tool_web&utm_source=OWO&utm_term=ccswitch">此链接</a>订阅方舟AgentPlan,新客户首月40元起!<a href="https://www.byteplus.com/en/product/modelark?utm_campaign=hw&utm_content=ccswitch&utm_medium=devrel_tool_web&utm_source=OWO&utm_term=ccswitch">>>For developers outside Mainland China, please click here</a></td>
</tr>
<tr>
@@ -87,11 +87,6 @@ Claude Code / Codex / Gemini 官方渠道低至 3.8 / 0.2 / 0.9 折,充值更
<td>感谢优云智算赞助了本项目!优云智算是UCloud旗下AI云平台,提供稳定、全面的国内外模型API,仅一个key即可调用。主打包月、按次的高性价比 国模Coding Plan套餐,同时提供官转稳定海外模型。支持接入 Claude Code、Codex 及 API 调用。支持企业高并发、7*24技术支持、自助开票。通过<a href="https://www.compshare.cn/coding-plan?ytag=GPU_YY_YX_git_cc-switch">此链接</a>注册的用户,可得免费5元平台体验金!</td>
</tr>
<tr>
<td width="180"><a href="https://aicoding.sh/i/CCSWITCH"><img src="assets/partners/logos/aicoding.jpg" alt="AICoding" width="150"></a></td>
<td>感谢 AICoding.sh 赞助了本项目!AICoding.sh —— 全球大模型 API 超值中转服务!Claude Code 1.9 折,GPT 0.1 折,已为数百家企业提供高性价比 AI 服务。支持 Claude Code、GPT、Gemini 及国内主流模型,企业级高并发、极速开票、7×24 专属技术支持,通过<a href="https://aicoding.sh/i/CCSWITCH">此链接</a> 注册的 CC Switch 用户,首充可享受九折优惠!</td>
</tr>
<tr>
<td width="180"><a href="https://crazyrouter.com/register?aff=OZcm&ref=cc-switch"><img src="assets/partners/logos/crazyrouter.png" alt="Crazyrouter" width="150"></a></td>
<td>感谢 Crazyrouter 赞助了本项目!Crazyrouter 是一个高性能 AI API 聚合平台——一个 API Key 即可访问 300+ 模型,包括 Claude Code、Codex、Gemini CLI 等。全部模型低至官方定价的 55%,支持自动故障转移、智能路由和无限并发。Crazyrouter 为 CC Switch 用户提供了专属优惠:通过<a href="https://crazyrouter.com/register?aff=OZcm&ref=cc-switch">此链接</a>注册后联系客服即可领取 <strong>$2 免费额度</strong>,首次充值时输入优惠码 `CCSWITCH` 还可获得额外 <strong>30% 奖励额度</strong></td>
@@ -117,23 +112,13 @@ Claude Code / Codex / Gemini 官方渠道低至 3.8 / 0.2 / 0.9 折,充值更
</tr>
<tr>
<td width="180"><a href="https://ctok.ai"><img src="assets/partners/logos/ctok.png" alt="CTok" width="150"></a></td>
<td>感谢 CTok.ai 赞助了本项目!CTok.ai 致力于打造一站式 AI 编程工具服务平台。我们提供 Claude Code 专业套餐及技术社群服务,同时支持 Google Gemini 和 OpenAI Codex。通过精心设计的套餐方案和专业的技术社群,为开发者提供稳定的服务保障和持续的技术支持,让 AI 辅助编程真正成为开发者的生产力工具。点击<a href="https://ctok.ai">这里</a>注册!</td>
<td width=180><a href=https://ctok.ai><img src=assets/partners/logos/ctok.png alt=CTok width=150></a></td>
<td>感谢 CTok.ai 赞助了本项目!CTok.ai 致力于打造一站式 AI 编程工具服务平台。我们提供 Claude Code 专业套餐及技术社群服务,同时支持 Google Gemini 和 OpenAI Codex。通过精心设计的套餐方案和专业的技术社群,为开发者提供稳定的服务保障和持续的技术支持,让 AI 辅助编程真正成为开发者的生产力工具。点击<a href=https://ctok.ai>这里</a>注册!</td>
</tr>
<tr>
<td width="180"><a href="https://vibecodingapi.ai"><img src="assets/partners/logos/lioncc.png" alt="LionCC" width="150"></a></td>
<td>感谢 LionCC 狮子API 赞助了本项目!LionCC 专为追求极致开发体验的”Vibe Coders”而生。我们提供稳定、低延迟、优惠价格的 Claude CodeCodex 及 OpenClaw 算力服务,可节约 50% 成本。注册后添加客服微信 HSQBJ088888888,发暗号 cc-switch 备注即可送 10 美金额度(1000 万 token 算力)。其他项目合作关注博客 @LionCC.ai,点击<a href=”https://vibecodingapi.ai”>这里</a>注册!</td>
</tr>
<tr>
<td width="180"><a href="https://console.claudeapi.com/register?aff=pCLD"><img src="assets/partners/logos/claudeapi.png" alt="ClaudeAPI" width="150"></a></td>
<td>本项目由 <a href="https://console.claudeapi.com/register?aff=pCLD">Claude API</a> 赞助。Claude API 直连,三分钟接入 Claude Code 与 Agent 应用 新用户可领取测试额度。基于 Anthropic 官方 Key + AWS Bedrock 官方渠道,非逆向、非降智,支持 Opus / Sonnet / Haiku 全系列模型,保留 Tool Use、1M 上下文等官方能力。适合 Claude Code 深度用户、Agent 工程师与企业技术团队,支持开票和团队对接。点击<a href="https://console.claudeapi.com/register?aff=pCLD">这里</a>注册!</td>
</tr>
<tr>
<td width="180"><a href="https://ddshub.short.gy/ccswitch"><img src="assets/partners/logos/dds.png" alt="DDS" width="150"></a></td>
<td>感谢 DDS 赞助本项目!呆呆兽是一家专注 Claude 的可靠高效 API 中转站,为个人和企业用户提供极具性价比的国内 Claude 直连加速服务。支持 Claude Haiku / Opus / Sonnet 等满血模型。充值满 1000 元即可开具发票,企业客户更可享受定制化分组和技术支持服务。CC Switch 用户专属福利:通过<a href="https://ddshub.short.gy/ccswitch">此链接</a>注册后,首单充值可额外赠送 10% 额度(充值后请联系群主领取)!</td>
<td width=180><a href=https://console.claudeapi.com/register?aff=pCLD”><img src=assets/partners/logos/claudeapi.png alt=”ClaudeAPI” width=150></a></td>
<td>本项目由 <a href=”https://console.claudeapi.com/register?aff=pCLD”>Claude API</a> 赞助。Claude API 直连,三分钟接入 Claude Code 与 Agent 应用 新用户可领取测试额度。基于 Anthropic 官方 Key + AWS Bedrock 官方渠道,非逆向、非降智,支持 Opus / Sonnet / Haiku 全系列模型,保留 Tool Use、1M 上下文等官方能力。适合 Claude Code 深度用户、Agent 工程师与企业技术团队,支持开票和团队对接。点击<a href=”https://console.claudeapi.com/register?aff=pCLD”>这里</a>注册!</td>
</tr>
<tr>
@@ -146,6 +131,21 @@ Claude Code / Codex / Gemini 官方渠道低至 3.8 / 0.2 / 0.9 折,充值更
<td>感谢 RunAPI 赞助本项目!RunAPI 是高效稳定的 AI 模型 API 中转平台,一个 API Key 即可访问 OpenAI、Claude、Gemini、DeepSeek、Grok 等 150+ 主流模型,低至 1 折,极其稳定,可以无缝兼容 Claude Code、OpenClaw 等工具。RunAPI为CC switch的用户提供了特别福利,注册后联系客服可以领取14元额度,点击<a href="https://runapi.co">此链接</a>注册!</td>
</tr>
<tr>
<td width="180"><a href="https://apikey.fun/register?aff=CCSwitch"><img src="assets/partners/logos/apikey_banner.png" alt="APIKEY.FUN" width="150"></a></td>
<td>感谢 APIKEY.FUN 赞助本项目!APIKEY.FUN 是一家专业的企业级 AI 中转站,致力于为企业和个人开发者提供稳定、高效、低成本的 AI 模型 API 接入服务。平台支持 Claude、OpenAI、Gemini 等主流热门模型,价格低至官方原价的 7%。通过本项目<a href="https://apikey.fun/register?aff=CCSwitch">专属链接</a>注册,还可享受最高 <strong>充值永久 95 折</strong> 专属优惠。</td>
</tr>
<tr>
<td width="180"><a href="https://apinebula.com/02rw5X"><img src="assets/partners/logos/apinebula_banner.png" alt="APINebula" width="150"></a></td>
<td>感谢 APINEBULA 赞助本项目!APINEBULA 是银河录像局旗下的企业级 AI 聚合平台,背靠大平台资源,面向开发者、团队与企业用户提供稳定、高性价比的大模型 API 接入服务。平台聚合 Claude、GPT、Gemini 等主流满血模型,一个接口,接入全球顶尖 AI 大模型,各大模型价格低至 1 折起,支持企业级高并发、正式合同、对公打款与开票服务,适合 AI 编程、Agent 开发、业务系统集成等多种场景!使用<a href="https://apinebula.com/02rw5X">此链接</a>注册并在充值时填写 <strong>"ccswitch"</strong> 优惠码可享<strong>九折优惠</strong></td>
</tr>
<tr>
<td width="180"><a href="https://www.atlascloud.ai/coding-plan?utm_source=github&utm_campaign=cc-switch"><img src="assets/partners/logos/atlascloud_banner.png" alt="Atlas Cloud" width="150"></a></td>
<td>Atlas Cloud 是一个全模态 AI 推理平台,通过单一 API 为开发者提供视频生成、图像生成及 LLM 接入。免去繁琐的多供应商对接,一次连接即可调用 300+ 款全模态精选模型。立即查看 Atlas Cloud 全新<a href="https://www.atlascloud.ai/coding-plan?utm_source=github&utm_campaign=cc-switch">“编程计划”</a>优惠,获取更具性价比的 API 接入!</td>
</tr>
</table>
</details>
@@ -172,7 +172,7 @@ Claude Code / Codex / Gemini 官方渠道低至 3.8 / 0.2 / 0.9 折,充值更
## 功能特性
[完整更新日志](CHANGELOG.md) | [发布说明](docs/release-notes/v3.12.3-zh.md)
[完整更新日志](CHANGELOG.md) | [发布说明](docs/release-notes/v3.15.0-zh.md)
### 供应商管理
@@ -304,7 +304,6 @@ CC Switch macOS 版本已通过 Apple 代码签名和公证,可直接下载安
**方式一:通过 Homebrew 安装(推荐)**
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

+527
View File
@@ -0,0 +1,527 @@
# CC Switch v3.15.0
> Claude Desktop becomes a first-class managed surface with third-party provider switching via proxy gateway, role-based model mapping, major reverse-proxy hardening, Codex OAuth live model discovery, and a filter-driven usage dashboard Hero card
**[中文版 →](v3.15.0-zh.md) | [日本語版 →](v3.15.0-ja.md)**
---
> [!WARNING]
>
> ## Only Official Channels (Please Read)
>
> CC Switch is a **fully free and open-source** desktop app, and we **do not charge users any fees**. Multiple imposter websites have recently been spotted impersonating CC Switch to solicit payments and harvest account credentials, with some users already reporting financial losses. Please only obtain the software through the official channels listed below:
>
> | Channel | Only Official |
> | ------------------ | ------------------------------------------------------------------------------ |
> | Website | **[ccswitch.io](https://ccswitch.io)** |
> | Source | **[github.com/farion1231/cc-switch](https://github.com/farion1231/cc-switch)** |
> | Downloads | **[GitHub Releases](https://github.com/farion1231/cc-switch/releases)** |
> | Author | **[@farion1231](https://github.com/farion1231)** |
> | Report an Imposter | **[GitHub Issues](https://github.com/farion1231/cc-switch/issues)** |
>
> **Any "CC Switch" website or client that asks you for payment, top-ups, or login credentials is fake.** If you have been tricked into paying, stop the transaction immediately and file a report through GitHub Issues so we can take down the imposter site as quickly as possible.
---
## Claude Desktop Guide
The headline feature in this release is the **first-class Claude Desktop management panel**. If you already have many providers configured for Claude Code, start here:
**[Use CC Switch to configure, manage, and switch Claude Desktop providers in one place](../user-manual/en/2-providers/2.6-claude-desktop.md)**
The guide walks through one-click import from Claude Code, adding Claude Desktop-specific providers, direct mode vs. model-mapping mode, showing the hidden local-routing toggle, and returning to Claude Desktop's official sign-in mode.
---
## Overview
CC Switch v3.15.0 is a major release following the v3.14.x line, centered on **promoting Claude Desktop to a first-class managed surface**. It ships third-party provider switching through the in-app proxy gateway, role-based model mapping (`sonnet` / `opus` / `haiku`) with a `supports1m` long-context flag, Copilot/Codex OAuth provider reuse, a redesigned Claude Code import flow, app-switcher differentiation between "Claude Code" and "Claude Desktop", and 44 provider presets translated from the Claude Code catalog into the new Claude Desktop surface.
Around proxy reliability, this release performs a systematic hardening pass: P0P3 patches across routing / lifecycle / retry / failover / rectifier paths; pooled HTTPS connection reuse for non-Anthropic backends to cut per-request latency; cache hit-rate improvements for Codex and OpenAI Responses (emit `prompt_cache_key` only when a real client-provided session identity exists, canonicalize JSON keys in outgoing request bodies plus `tool_call` arguments and `tool_result` content, and thread `session_id` into the usage logger); correct Anthropic ↔ OpenAI `tool_choice` mapping; Vertex AI full URLs are no longer truncated; Gemini request models are now extracted from the URI path; takeover detection is tightened; and IPv6 listen addresses are supported. ChatGPT Codex OAuth providers no longer depend on hardcoded model lists — CC Switch now fetches a live model list from the ChatGPT backend on demand.
Claude Code's model mapping is now role-based (`sonnet` / `opus` / `haiku`) with display names and a new `supports1m` boolean flag, replacing the legacy `[1M]` suffix and decoupling routing decisions from raw model IDs. The usage dashboard adds a **filter-driven Hero card** that exposes cache-normalized real total tokens and cache hit rate, updated live as the active date range / provider / model filters change; paired with a fix for cache-cost semantics and the noisy pricing warning storm that fired on every request. Robustness improvements in the OpenAI Responses API usage parsing path mean missing or malformed upstream `usage` no longer crashes the VSCode Claude Code extension with a `null` output.
The provider ecosystem expands further: new BytePlus, Volcengine Agentplan, ClaudeAPI, ClaudeCN, RunAPI, RelaxyCode, PatewayAI, and Baidu Qianfan Coding Plan partner presets; DouBao Seed is promoted to partner status; and provider cards now surface a "routing support" badge so users can tell at a glance which providers can be served through Local Routing. This release also fixes a long tail of issues across Codex sessions, OAuth, Claude Desktop forms, Linux segfaults, terminal fallbacks, and ships several GitHub Actions dependency bumps.
**Release date**: 2026-05-16
**Stats**: 127 commits | 211 files changed | +17,980 insertions | -2,748 deletions
---
## Highlights
- **Claude Desktop Becomes a First-Class Managed Surface**: Third-party provider switching through the in-app proxy gateway, role-based model mapping (`sonnet` / `opus` / `haiku`) with a `supports1m` long-context flag, Copilot/Codex OAuth provider reuse, and 44 provider presets translated from the Claude Code catalog. Note: 20 Claude Desktop presets now default to direct mode instead of proxy mode — verify connectivity after upgrade if you previously relied on proxy routing.
- **Major Reverse-Proxy Hardening**: P0P3 lifecycle / retry / failover / rectifier patches; pooled HTTPS reuse for non-Anthropic backends; Codex / Responses cache hit-rate improvements; correct Anthropic ↔ OpenAI `tool_choice` mapping; Vertex AI URL preservation; Gemini path-based model extraction; refined takeover detection; IPv6 listen address support.
- **Provider Ecosystem Expansion**: New BytePlus, Volcengine Agentplan, ClaudeAPI, ClaudeCN, RunAPI, RelaxyCode, PatewayAI, and Baidu Qianfan Coding Plan partner presets; DouBao Seed promoted to partner status; routing-support badges on provider cards.
- **Role-Based Model Mapping with 1M Flag**: Role-based `sonnet` / `opus` / `haiku` routing with display names and a `supports1m` flag replaces the legacy `[1M]` suffix.
- **Codex OAuth Live Model Discovery**: ChatGPT Codex providers fetch the live model list from the ChatGPT backend on demand.
- **Usage Dashboard Filter-Driven Hero**: Surfaces cache-normalized real total tokens and cache hit rate, updated live as date / provider / model filters change.
- **DeepSeek Tool Calls + Zero-Usage Final Delta**: DeepSeek tool calls now return `reasoning_content` alongside `tool_calls` (#2543, thanks @bling-yshs); the final `message_delta` always includes a usage block (even when zero) so strict Anthropic clients no longer crash on `null` (#2485, thanks @Myoontyee).
- **OpenAI Responses API Usage Parsing Robustness**: Missing or malformed upstream `usage` no longer crashes the VSCode Claude Code extension (#2422, thanks @magucas).
---
## Added
### Claude Desktop Third-Party Provider Switching via Proxy Gateway
CC Switch now treats **Claude Desktop** as a first-class managed surface alongside Claude Code / Codex / Gemini / OpenCode / OpenClaw / Hermes.
- New dedicated Claude Desktop panel that brokers third-party providers to Claude Desktop through CC Switch's in-app proxy gateway
- Routing-support badge on cards for providers that need Local Routing
- Role-based model route mapping locked to `sonnet` / `opus` / `haiku`
- Copilot / Codex OAuth providers can be reused in the Claude Desktop panel
- Redesigned Claude Code settings import flow
- App switcher visually distinguishes "Claude Code" from "Claude Desktop", and the app visibility settings use the "Claude Code" label
- 44 Claude Desktop provider presets translated from the Claude Code preset catalog
### Routing Support Badges on Provider Cards
Provider cards in both the Claude Code and Codex panels now show a routing-support badge so users can tell at a glance which providers can be served through Local Routing.
### Codex OAuth Live Model List
ChatGPT Codex providers no longer rely on a hardcoded model selection — CC Switch fetches a **live model list** from the ChatGPT backend on demand.
### Role-Based Model Mapping with 1M Flag
Claude Code model mapping is now role-based (`sonnet` / `opus` / `haiku`) with display names and a `supports1m` boolean flag, replacing the legacy `[1M]` suffix and decoupling routing from raw model IDs.
### Filter-Driven Usage Hero
The usage dashboard's Hero summary is now filter-driven, updating live as the active date range / provider / model filters change; it surfaces **cache-normalized real total tokens** and cache hit rate so the Hero figures line up with the detail list below.
### Provider Form "Save Anyway" Prompt
Softened provider form input validation by turning non-blocking input issues into a "save anyway" prompt, so a harmless field issue no longer blocks saving (#2307, thanks @allenxln).
### Universal Provider Duplicate Action
Added a "duplicate" button for universal providers from the provider list (#2416, thanks @hubutui).
### Persisted Tauri Window State
Window position and size now persist across launches (#2377, thanks @BillSaul).
### Tray Icon Tooltip
The system tray icon now surfaces a status tooltip on hover (#2417, thanks @Coconut-Fish).
### Warp Terminal Session Launch
Added support for launching Warp and executing a saved session inside it (#2466, thanks @tisonkun).
### DeepSeek `reasoning_content` for Tool Calls
DeepSeek tool-call responses now return `reasoning_content` and `tool_calls` together, so callers can render both (#2543, thanks @bling-yshs).
### Baidu Qianfan Coding Plan (Claude Code)
Added a Baidu Qianfan Coding Plan preset (#2322, thanks @jimmyzhuu).
### Compshare Coding Plan Preset (Cross-App)
The Compshare Coding Plan preset now lands across claude / codex / hermes / openclaw.
### Partner Provider Presets
Added **BytePlus**, **Volcengine Agentplan**, **ClaudeAPI**, **ClaudeCN**, **RunAPI**, **RelaxyCode**, and **PatewayAI** partner presets; promoted **DouBao Seed** to partner status (refreshed endpoint and links).
### 44 Claude Desktop Provider Presets
Translated 44 provider presets from the Claude Code preset catalog into the new Claude Desktop panel.
---
## Changed
### 20 Claude Desktop Presets Default to Direct Mode
20 Claude Desktop presets now ship in direct mode instead of routing through the proxy by default, reducing setup friction for users who don't need proxy-specific compatibility shims. If you previously relied on proxy routing for these presets, verify connectivity after upgrading.
### Claude Desktop Operational Notes
Switching a Claude Desktop provider writes CC Switch's managed 3P profile and **requires restarting Claude Desktop** to take effect; proxy-mode providers require CC Switch's Local Routing to stay running while in use.
### Failover / Local Routing Guardrails
Failover controls now require the target app's Local Routing takeover to be enabled before they can be turned on; stopping only the proxy service is blocked while any app still depends on takeover state, preventing the "proxy stopped but the app still thinks takeover is running" inconsistency.
### Usage Accounting Semantics Changed
Usage summaries now report **cache-normalized real total tokens** and **cache hit rate**. Historical token and cost figures may **shift** after deduplication and pricing recalculation — the new numbers are more accurate but will not equal the values reported in earlier versions.
### Provider Preset Rendering Order
Preset lists now render in the author-defined array order, with partners prioritized first, replacing the previous implicit sort.
### Model Mapping Hint Copy Simplified
`modelMappingOffHint` was rewritten as action-oriented copy across zh / en / ja.
### CC Switch Brand Surface Unified to ccswitch.io
All in-app and README "official website" references now point at ccswitch.io as the sole official site; the release notes template also surfaces ccswitch.io.
### Theme Switch Simplified
Removed the circular reveal animation during theme switches; theme changes are now an instant cross-fade.
### Claude Code App Switcher Differentiation
The app switcher visually distinguishes "Claude Code" from "Claude Desktop", and the app visibility settings use the "Claude Code" label.
### CI: Claude Review Upgraded to Opus 4.7
The Claude review GitHub Action is upgraded to Opus 4.7; the prompt is tuned to reduce nitpick noise; a new `@claude` review-only Code Action is added; PR head SHA is pinned for checkout; the `--max-turns 5` limit is removed.
### GitHub Actions Dependency Bumps
- `actions/checkout` 4 → 6 (#2517)
- `pnpm/action-setup` 5 → 6 (#2518)
- `softprops/action-gh-release` 2 → 3 (#2519)
- `actions/stale` 9 → 10 (#2520)
### DeepSeek Presets Switched to V4
DeepSeek presets now ship V4 (flash / pro) with refreshed pricing seeds.
### Codex 1M Context Toggle Hidden in Edit Form
The 1M context-window toggle is no longer surfaced in the Codex provider edit form, reducing the density of knobs that have no effect in current Codex deployments.
### OpenClaudeCode Migrated to MicuAPI Domain
The OpenClaudeCode preset is migrated to the MicuAPI domain; Micu API links are refreshed to `micuapi.ai`.
### CrazyRouter Endpoints Switched to `cn` Subdomain
CrazyRouter preset endpoints now use the `cn` subdomain.
### RelaxyCode Custom Icon
The RelaxyCode preset icon is switched to a custom `relaxcode.png` asset.
### Kimi For Coding Doc URL
The Kimi For Coding website URL is updated to the `/code/docs/` path.
### SiliconFlow International Site Shows USD
The SiliconFlow international site now correctly shows USD for balance display (it previously displayed CNY incorrectly).
---
## Fixed
### OpenAI Responses API Usage Parsing Robustness
Hardened `build_anthropic_usage_from_responses()` and the Responses → Anthropic SSE translator so a missing or malformed upstream `usage` no longer produces `"usage": null` in `message_delta`. This unblocks strict Anthropic clients (notably the VSCode Claude Code extension) that crashed with `Cannot read properties of null (reading 'output_tokens')` against providers such as Codex OAuth and DashScope's `compatible-mode/v1/responses` endpoint. Added OpenAI field-name fallbacks (`prompt_tokens` / `completion_tokens`), null / empty / partial object handling, and preserved cache token fields even when input/output tokens are missing (#2422, thanks @magucas).
### Proxy Reliability Patches (P0P3)
Multiple rounds of routing / lifecycle / retry / rectifier patches across the request-forwarder paths; extracted a shared `handle_rectifier_retry_failure` helper and a shared `auth_header_value` helper.
### Proxy: Pooled HTTPS Connection Reuse for Non-Anthropic Backends
Non-Anthropic backends now reuse pooled HTTPS connections instead of opening a fresh TLS session per request, materially reducing per-request latency.
### Proxy: Forward Client's Actual HTTP Method
The proxy no longer hard-codes `POST` — it forwards the client's actual HTTP method, so non-POST upstream endpoints (e.g. GET `/v1/models`) now work correctly.
### Proxy: Per-Attempt Counters and `max_retries` Wiring
Client-request counters are moved out of the per-attempt loop; `AppProxyConfig.max_retries` is now correctly wired into the request forwarder.
### Proxy: Failover Decision Refinements
Refined retryable vs. unretryable error classification in the request forwarder.
### Proxy: Takeover Detection Tightening
Takeover detection is tightened; disabling takeover uses fallback restore, so leftover state no longer strands a provider.
### Proxy: Anthropic ↔ OpenAI `tool_choice` Mapping
During format conversion, Anthropic's `tool_choice` is now correctly mapped to the OpenAI Chat nested form.
### Proxy: Gemini Request Model Extracted from URI Path
Gemini request models are now extracted from the URI path (instead of the body), so transformed traffic reports the right model name.
### Proxy: Auth Header Error Handling
`get_auth_headers` now returns `Result` instead of panicking on bad credentials.
### Proxy: IPv6 Listen Address Validation
The Proxy panel now accepts IPv6 listen addresses.
### Proxy: Codex / Responses Cache Hit Rate
Improved cache hit rate for Codex and OpenAI Responses requests by stabilizing cache key derivation: emit `prompt_cache_key` only when the client actually carries a session identity, so unrelated conversations no longer collapse onto a single key; canonicalize (sort) JSON keys in outgoing request bodies and in `tool_call` arguments / `tool_result` content for byte-identical prefix-cache reuse; thread `session_id` into the usage logger for request correlation.
### Proxy: JSON Schema Underscore Fields Preserved
Private-parameter filtering now preserves underscore-prefixed field names inside JSON Schema name maps (`properties`, `patternProperties`, `definitions`, `$defs`), so user-defined schema keys like `_id` and `_meta` pass through the filter intact.
### Proxy: Read Tool Empty Pages
Drop empty pages from `Read` tool inputs so providers no longer reject the request (#2472, thanks @Kwensiu).
### Proxy: Per-Request Hot-Path Trim
Trimmed per-request hot-path work and database wait time.
### Proxy: Real Provider Model Names Under Takeover
Under takeover, the Claude Code menu now exposes the real provider model names instead of a stale alias.
### Proxy: Zero Usage in Final `message_delta`
The final `message_delta` event now always includes a usage block (even when zero) so strict Anthropic clients no longer crash on `null` (#2485, thanks @Myoontyee).
### Proxy: Streaming `message_delta` Deduplication
Deduplicated `message_delta` events that some upstreams emit twice (#2366, thanks @codeasier).
### Proxy: Scoped `reasoning_content` Preserved for Tool Calls
Tool-call paths now correctly preserve the scoped `reasoning_content` field during transformation; Kimi / Moonshot's OpenAI Chat compatibility path keeps the field while generic OpenAI-compatible requests stay free of it (#2367, thanks @codeasier).
### Proxy: Vertex AI Full URL Preserved
Full Vertex AI URLs are no longer truncated during proxy forwarding (#2415, thanks @xpfo-go).
### Proxy: Leading Billing Header Stripped from System Content
Some upstreams prepend a billing-header chunk to the system message; this content is now stripped (#2350).
### Proxy: Claude Auth Strategy Derived from `ANTHROPIC_*` Env Var
The Claude auth strategy is now derived from the actual `ANTHROPIC_*` env variable name rather than an opaque heuristic.
### Third-Party Claude Providers: Disable Model Test
Model probing is disabled for third-party Claude gateways that don't implement `/v1/models` consistently.
### Model-Fetch: `/models` for Anthropic-Compatible Subpath Providers
`/models` discovery now works for Anthropic-compatible subpath providers.
### Copilot: Claude Model IDs Resolved Against Live `/models`
Copilot-backed providers now resolve Claude model IDs against the live `/models` list to avoid stale ID mismatches.
### Codex: Session Title No Longer Pulls in `environment_context`
Codex session title extraction no longer pulls in the `environment_context` noise (#2439, thanks @eclipsehx).
### Codex: Subagent Sessions Hidden
Codex subagent sessions are now hidden from the main session list (#2445, thanks @LanternCX).
### Codex Startup Live Import Duplication
Fixed a duplicate-import bug in the Codex startup live-import path (#2590, thanks @DhruvShankpal).
### Codex Provider Switch No Longer Disturbs History
Switching the active Codex provider no longer changes existing session history (#2349, thanks @SaladDay).
### Codex Usage Log Wording
Corrected a misleading log message for Codex session usage (#2473, thanks @tisonkun).
### Claude: Persist `max` Effort via Env
`max` effort now correctly persists across restart via the env variable (#2493, thanks @makoMakoGo).
### Claude Desktop: Model Route Matching Without `[1M]` Suffix
Route matching no longer requires the legacy `[1M]` suffix.
### Claude Desktop: Provider Form Input Focus Loss
Fixed an input in the Claude Desktop provider form that lost focus while being edited.
### Claude Desktop: Spurious Proxy-Stopped Status Alert
Removed an alert that fired spuriously when the proxy was intentionally stopped.
### Claude Desktop: Empty Toolbar Capsule Hidden
The empty toolbar capsule is now hidden when Claude Desktop is the active app.
### UI: Monitor Badge Icon Centering
Centered the Monitor badge icon in the app switcher.
### Linux: Theme Selection Segfault
Prevented a segfault triggered by selecting a theme on Linux (#2502, thanks @definfo).
### Terminal: iTerm Fallback on Cold Launch
Prevented iTerm from being selected as a fallback on cold launch when it isn't actually installed (#2448, thanks @hulkbig).
### Config: JSON Keys Sorted Alphabetically
Config writes now sort JSON keys alphabetically for deterministic output (#2469, thanks @fuleinist).
### "Import Existing" Made Side-Effect Free
The "import existing" action is now side-effect free (#2429, thanks @xwil1).
### Coding Plan: Zhipu Weekly Tier Named by Reset Time
Corrected the Zhipu weekly tier name to match the actual reset time (#2420, thanks @TuYv).
### DashScope: Usage Parsing Robustness
Hardened DashScope usage parsing so a malformed payload no longer crashes the VSCode Claude Code extension (#2425, thanks @magucas).
### Usage: Deduplicate Proxy and Session-Log Sources
Deduplicated usage records sourced from both the proxy and session logs.
### Usage: Cache Cost Semantics + Pricing Warn Storm
Corrected cache-cost semantics and silenced the noisy pricing warning that fired on every request.
### CI: Frontend Formatting + Linux Clippy Restored
Restored frontend formatting and Linux clippy checks in CI.
### Proxy Test Helper Clippy Warning
Fixed a clippy warning in the proxy test helper.
---
## Removed
### Hermes Agent Usage Tracking Integration
Removed the Hermes Agent usage tracking integration originally planned for this cycle — upstream behavior changes made the integration impractical to maintain. The integration was **never enabled in any released version**; the "zero-cost rendering" bug discovered during its development was fixed before the integration was rolled back.
### Theme Switch Circular Reveal Animation
Removed the circular reveal animation used during theme switches — it stuttered on slower compositors and added little visible value.
### DDSHub Partner Integration
Removed DDSHub as a partner preset and dropped the cross-link blurbs from the READMEs.
---
## Docs
### README Sponsor Refresh (zh / en / ja)
Added BytePlus, ClaudeCN, RunAPI, and PatewayAI sponsor entries; cross-linked BytePlus and Volcengine entries; refreshed the CrazyRouter $2 credit claim flow, the Compshare blurb, the Right Code blurb, and other sponsor logos and listings; flattened the LionCC logo onto a white background; switched the Chinese README's sponsor logo to the Volcengine artwork; added Hermes Agent to the README subtitles.
### Release Notes Template
The release notes template now surfaces `ccswitch.io`.
### Brand Surface
Documented `ccswitch.io` as the sole official website across READMEs and in-app references.
---
## ⚠️ Upgrade Notes
### 20 Claude Desktop Presets Default to Direct Mode
These 20 presets previously routed through the proxy by default and now default to direct mode. If you were using one of these presets pre-upgrade and depended on the proxy path for connectivity (for example because the proxy applies a special rectifier or transformation layer), verify connectivity after upgrading; you can manually switch them back to proxy mode from the CC Switch panel if needed.
### Claude Desktop Operational Constraints
Switching a Claude Desktop provider **requires restarting Claude Desktop** to take effect; proxy-mode providers require CC Switch's Local Routing to stay running while in use — quitting CC Switch or stopping Local Routing will cut off any proxy-mode Claude Desktop providers.
### Failover Requires Takeover Enabled
Before enabling Failover, make sure the target app's Local Routing takeover is enabled, otherwise the Failover control will refuse to start; stopping the proxy service while any app still depends on takeover state is blocked, so you need to disable takeover at the app layer first before stopping the proxy.
### Usage Figures May Diverge from History
Usage summaries now use cache-normalized real total tokens + cache hit rate. Historical token and cost figures may **shift** after deduplication and pricing recalculation — the new numbers are more accurate but will not equal what earlier versions reported.
---
## ⚠️ Risk Notice
This release inherits the risk notices originally introduced in v3.12.3 / v3.13.0 for reverse-proxy-style features.
**GitHub Copilot Reverse Proxy**: Using Copilot's reverse-proxy path may violate GitHub / Microsoft's terms of service. See the [v3.12.3 release notes](v3.12.3-en.md#-risk-notice) for details.
**Codex OAuth Reverse Proxy**: Using the Codex OAuth reverse proxy with a ChatGPT subscription may violate OpenAI's terms of service. See the [v3.13.0 release notes](v3.13.0-en.md#-risk-notice) for details.
**Claude Desktop Third-Party Provider Switching via Proxy Gateway**: Routing Claude Desktop traffic through CC Switch's in-app proxy gateway to a third-party provider exposes those requests to that provider's billing, compliance, and data-retention policies — read the target provider's terms of service before using.
By enabling these features, users **accept all associated risks**. CC Switch is not responsible for any account restrictions, warnings, or service suspensions that result from using these features.
---
## Download & Installation
Visit [Releases](https://github.com/farion1231/cc-switch/releases/latest) to download the appropriate version.
### System Requirements
| OS | Minimum Version | Architecture |
| ------- | ---------------------------- | ----------------------------------- |
| Windows | Windows 10 or later | x64 |
| macOS | macOS 12 (Monterey) or later | Intel (x64) / Apple Silicon (arm64) |
| Linux | See table below | x64 / ARM64 |
### Windows
| File | Description |
| ---------------------------------------- | ----------------------------------------------------- |
| `CC-Switch-v3.15.0-Windows.msi` | **Recommended** - MSI installer, supports auto-update |
| `CC-Switch-v3.15.0-Windows-Portable.zip` | Portable, extract and run, no registry writes |
### macOS
| File | Description |
| -------------------------------- | ------------------------------------------------------- |
| `CC-Switch-v3.15.0-macOS.dmg` | **Recommended** - DMG installer, drag into Applications |
| `CC-Switch-v3.15.0-macOS.zip` | Extract and drag into Applications, Universal Binary |
| `CC-Switch-v3.15.0-macOS.tar.gz` | For Homebrew installation and auto-update |
> macOS builds are Apple code-signed and notarized — install directly.
### Homebrew (macOS)
> 🎉 CC Switch is now available in the official Homebrew cask repository — no need to add a custom tap!
```bash
brew install --cask cc-switch
```
Update:
```bash
brew upgrade --cask cc-switch
```
### Linux
> Linux artifacts are published for both **x86_64** and **ARM64** (`aarch64`). The architecture is included in the asset filename — pick the one matching your machine's `uname -m` output:
>
> - `CC-Switch-v3.15.0-Linux-x86_64.AppImage` / `.deb` / `.rpm`
> - `CC-Switch-v3.15.0-Linux-arm64.AppImage` / `.deb` / `.rpm`
| Distribution | Recommended | Installation |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| Ubuntu / Debian / Linux Mint / Pop!\_OS | `.deb` | `sudo dpkg -i CC-Switch-*.deb` or `sudo apt install ./CC-Switch-*.deb` |
| Fedora / RHEL / CentOS / Rocky Linux | `.rpm` | `sudo rpm -i CC-Switch-*.rpm` or `sudo dnf install ./CC-Switch-*.rpm` |
| openSUSE | `.rpm` | `sudo zypper install ./CC-Switch-*.rpm` |
| Arch Linux / Manjaro | `.AppImage` | Add execute permission and run, or use AUR |
| Other distros / not sure | `.AppImage` | `chmod +x CC-Switch-*.AppImage && ./CC-Switch-*.AppImage` |
+527
View File
@@ -0,0 +1,527 @@
# CC Switch v3.15.0
> Claude Desktop が一等管理パネルに昇格(プロキシゲートウェイ経由のサードパーティプロバイダー切り替えを含む)、ロールベースのモデルマッピング、リバースプロキシの大幅強化、Codex OAuth ライブモデル検出、Usage ダッシュボードのフィルター駆動 Hero カード
**[English →](v3.15.0-en.md) | [中文 →](v3.15.0-zh.md)**
---
> [!WARNING]
>
> ## 唯一の公式チャネル(必ずお読みください)
>
> CC Switch は**完全に無料・オープンソース**のデスクトップアプリで、**ユーザーから料金を徴収することはありません**。最近、CC Switch の名を騙って課金を要求したり認証情報を収集する偽サイトが複数確認されており、一部のユーザーには既に金銭的被害が発生しています。本ソフトウェアは下記の公式チャネルからのみ入手してください:
>
> | チャネル | 唯一の公式 |
> | ------------ | ------------------------------------------------------------------------------ |
> | 公式サイト | **[ccswitch.io](https://ccswitch.io)** |
> | ソースコード | **[github.com/farion1231/cc-switch](https://github.com/farion1231/cc-switch)** |
> | ダウンロード | **[GitHub Releases](https://github.com/farion1231/cc-switch/releases)** |
> | 作者 | **[@farion1231](https://github.com/farion1231)** |
> | 偽サイト通報 | **[GitHub Issues](https://github.com/farion1231/cc-switch/issues)** |
>
> **料金請求・チャージ・認証情報の提供を求める「CC Switch」サイトやクライアントはすべて偽物です。** 支払いを誘導された場合は、直ちに取引を中止し、偽サイトを速やかに削除できるよう GitHub Issues からご報告ください。
---
## Claude Desktop 利用ガイド
本リリースの主役は **Claude Desktop の一等管理パネル**です。すでに Claude Code 側で多くのプロバイダーを設定している場合は、まずこのガイドをご覧ください:
**[CC Switch で Claude Desktop プロバイダーを一括設定・管理・切り替える](../user-manual/ja/2-providers/2.6-claude-desktop.md)**
このガイドでは、Claude Code から既存プロバイダーを一括インポートする方法、Claude Desktop 専用プロバイダーの追加、直結 / モデルマッピングの 2 モード、非表示のローカルルーティング切り替えを表示する設定、Claude Desktop 公式サインインモードへの復帰までを説明しています。
---
## 概要
CC Switch v3.15.0 は v3.14.x に続く大型バージョンアップで、コアの焦点は **Claude Desktop を一等管理パネルに昇格させること**にあります。これに合わせて、内蔵プロキシゲートウェイを介したサードパーティプロバイダーの切り替え、ロールベースのモデルマッピング(sonnet / opus / haiku+ `supports1m` ロングコンテキストフラグ、Copilot / Codex OAuth プロバイダーの再利用、再設計された Claude Code インポートフロー、App スイッチャーでの「Claude Code」と「Claude Desktop」の視覚的な区別、そして Claude Code プリセットディレクトリから翻訳された 44 個の Claude Desktop プリセットを提供します。
リバースプロキシの信頼性については、本リリースで系統的なハードニングを行いました: P0–P3 の複数回にわたるルーティング / ライフサイクル / リトライ / フェイルオーバー / 補正器の修正; 非 Anthropic バックエンドで HTTPS コネクションプールを再利用してリクエスト単位のレイテンシを低減; Codex と OpenAI Responses のキャッシュヒット率改善(`prompt_cache_key` は本物のクライアントセッション識別子がある場合のみ送信、外部リクエストボディと `tool_call` 引数 / `tool_result` 内容の JSON キーを正規化してソート、`session_id` を Usage ロガーに通す); Anthropic ↔ OpenAI `tool_choice` の正しい相互変換; Vertex AI の完全な URL を切り詰めない; Gemini は URI パスからモデル名を抽出するように変更; Local Routing のテイクオーバー検出をより精緻化; IPv6 リッスンアドレスのサポート。Codex OAuth 系の Claude プロバイダーはハードコードされたモデルリストに依存しなくなり、CC Switch が必要に応じて ChatGPT バックエンドからライブモデルリストを取得します。
Claude Code のモデルマッピングはロールベース(`sonnet` / `opus` / `haiku`+ 表示名に変更され、`supports1m` 真偽値フラグが導入されました。これは旧来の `[1M]` サフィックス記法に取って代わり、ルーティング判定と元のモデル ID を分離します。Usage ダッシュボードには**フィルター駆動 Hero カード**が追加され、キャッシュ正規化後の真の総トークン数とキャッシュヒット率を表示し、現在の日付範囲 / プロバイダー / モデルのフィルターに追従してリアルタイム更新します。あわせてキャッシュコストのセマンティクスエラーと、リクエストごとに発生していた pricing 警告ノイズを修正しました。OpenAI Responses API の usage 解析パスを堅牢化し、上流の欠損または不正な `usage` のせいで VSCode Claude Code プラグインが `null` 出力でクラッシュしないようにしました。
プロバイダーエコシステムはさらに拡張されました: BytePlus、Volcengine Agentplan、ClaudeAPI、ClaudeCN、RunAPI、RelaxyCode、PatewayAI、Baidu Qianfan Coding Plan のパートナープリセットを追加; Doubao Seed をパートナープリセットに昇格; プロバイダーカードに「Local Routing 対応」バッジを表示。本リリースでは、Codex セッション、OAuth、Claude Desktop フォーム、Linux segfault、ターミナルフォールバックなどに関する多くの細部の問題も修正し、複数の GitHub Actions 依存関係をアップグレードしました。
**リリース日**: 2026-05-16
**Stats**: 127 commits | 211 files changed | +17,980 insertions | -2,748 deletions
---
## ハイライト
- **Claude Desktop が一等管理パネルに**: 内蔵プロキシゲートウェイを介したサードパーティプロバイダーの切り替え、ロールベースのモデルマッピング(sonnet / opus / haiku+ `supports1m` ロングコンテキストフラグ、Copilot / Codex OAuth プロバイダーの再利用、Claude Code プリセットディレクトリから翻訳された 44 個のプリセットを提供。注意: 20 個の Claude Desktop プリセットがデフォルトでプロキシモードから直接接続モードに切り替わったため、アップグレード後にプロキシルーティングに依存している場合は接続性を検証してください
- **リバースプロキシの大幅強化**: P0–P3 のライフサイクル / リトライ / フェイルオーバー / 補正器の修正; 非 Anthropic バックエンドの HTTPS コネクションプール再利用; Codex / Responses キャッシュヒット率改善; Anthropic ↔ OpenAI `tool_choice` の正しいマッピング; Vertex AI URL の完全保持; Gemini パスベースのモデル抽出; テイクオーバー検出の精緻化; IPv6 リッスンアドレスのサポート
- **プロバイダーエコシステムの拡張**: BytePlus、Volcengine Agentplan、ClaudeAPI、ClaudeCN、RunAPI、RelaxyCode、PatewayAI、Baidu Qianfan Coding Plan のパートナープリセットを追加; Doubao Seed をパートナーに昇格; プロバイダーカードに「ルーティングプロキシ対応」バッジを表示
- **ロールベースのモデルマッピング + 1M フラグ**: ロールベースの sonnet / opus / haiku ルーティング + 表示名 + `supports1m` フラグ。旧来の `[1M]` サフィックスに取って代わる
- **Codex OAuth ライブモデル検出**: ChatGPT Codex 系プロバイダーは必要に応じて ChatGPT バックエンドからライブモデルリストを取得
- **Usage ダッシュボードのフィルター駆動 Hero**: キャッシュ正規化後の真の総トークン数とキャッシュヒット率を表示し、現在の日付 / プロバイダー / モデルフィルターに追従してリアルタイム更新
- **DeepSeek ツール呼び出し + ゼロ usage 最終 delta**: DeepSeek のツール呼び出しが `reasoning_content` も返却するように (#2543, 感謝 @bling-yshs); 最終 `message_delta` は常に usage ブロックを含む(すべてゼロでも)ため、厳格な Anthropic クライアントが `null` でクラッシュしなくなった (#2485, 感謝 @Myoontyee)
- **OpenAI Responses API usage 解析の堅牢化**: 上流の欠損または不正な usage によって VSCode Claude Code プラグインがクラッシュしないように (#2422, 感謝 @magucas)
---
## 追加機能
### Claude Desktop サードパーティプロバイダーのプロキシ切り替え
CC Switch は初めて **Claude Desktop** を一等管理対象パネルとして扱い、Claude Code / Codex / Gemini / OpenCode / OpenClaw / Hermes と並列に位置づけます。
- Claude Desktop 専用パネルを追加し、CC Switch 内蔵プロキシゲートウェイを介してサードパーティプロバイダーを Claude Desktop に代理転送
- ルーティングプロキシを必要とするプロバイダーには、カード上に「Local Routing 対応」バッジを表示
- ロールベースのモデルルーティングマッピングで `sonnet` / `opus` / `haiku` にロック
- Copilot / Codex OAuth プロバイダーを Claude Desktop パネルで再利用可能
- 再設計された Claude Code 設定インポートフロー
- App スイッチャーで「Claude Code」と「Claude Desktop」を視覚的に区別、アプリ可視性設定では「Claude Code」ラベルを使用
- Claude Code プリセットディレクトリから翻訳された 44 個の Claude Desktop プロバイダープリセット
### プロバイダーカード: ルーティングプロキシ対応バッジ
Claude Code と Codex パネルのプロバイダーカードに「ルーティングプロキシ対応」バッジを追加し、Local Routing 経由で提供可能なプロバイダーを一目で識別できるようにしました。
### Codex OAuth ライブモデルリスト
ChatGPT Codex 系プロバイダーはハードコードされたモデル選択に依存しなくなり、CC Switch が必要に応じて ChatGPT バックエンドから**ライブモデルリスト**を取得します。
### ロールベースのモデルマッピング + 1M フラグ
Claude Code のモデルマッピングはロールベース(`sonnet` / `opus` / `haiku`+ 表示名に変更され、`supports1m` 真偽値フラグが導入されました。これは旧来の `[1M]` サフィックス記法に取って代わり、ルーティング判定と元のモデル ID を分離します。
### Usage ダッシュボードのフィルター駆動 Hero
Usage ダッシュボードの Hero サマリーがフィルター駆動になり、現在の日付範囲 / プロバイダー / モデルフィルターに追従してリアルタイムに変化します。**キャッシュ正規化後の真の総トークン数**とキャッシュヒット率を表示することで、Hero の数値が下部の詳細リストと整合するようになります。
### プロバイダーフォームの「とりあえず保存」
プロバイダーフォームの入力検証を緩和し、非ブロッキングな入力上の問題を「とりあえず保存」型のヒントに変更しました。無害な軽微なフィールド問題が原因で保存が阻まれることがなくなります (#2307, 感謝 @allenxln)。
### Universal プロバイダーの複製アクション
プロバイダーリスト内の universal プロバイダーに「複製」ボタンを追加しました (#2416, 感謝 @hubutui)。
### Tauri ウィンドウ状態の永続化
ウィンドウの位置とサイズが再起動をまたいで保持されるようになりました (#2377, 感謝 @BillSaul)。
### トレイアイコンのホバーヒント
システムトレイアイコンにホバー時のステータスヒントを表示するようになりました (#2417, 感謝 @Coconut-Fish)。
### Warp ターミナルセッション起動
Warp ターミナルのサポートを追加し、保存されたセッションを Warp で実行できるようになりました (#2466, 感謝 @tisonkun)。
### DeepSeek ツール呼び出し `reasoning_content`
DeepSeek のツール呼び出しレスポンスが `reasoning_content``tool_calls` を同時に返却するようになり、呼び出し側が両方を一緒にレンダリングできるようになりました (#2543, 感謝 @bling-yshs)。
### Baidu Qianfan Coding PlanClaude Code
Baidu Qianfan Coding Plan プリセットを追加しました (#2322, 感謝 @jimmyzhuu)。
### Compshare Coding Plan プリセット(クロスアプリ)
Compshare Coding Plan プリセットを claude / codex / hermes / openclaw の全アプリに展開しました。
### パートナープロバイダープリセット
**BytePlus**、**Volcengine Agentplan**、**ClaudeAPI**、**ClaudeCN**、**RunAPI**、**RelaxyCode**、**PatewayAI** のパートナープリセットを追加; **Doubao Seed** をパートナープリセットに昇格(エンドポイントとリンクをリフレッシュ)。
### 44 個の Claude Desktop プロバイダープリセット
Claude Code プリセットディレクトリから 44 個のプロバイダープリセットを翻訳し、新しい Claude Desktop パネルに投入しました。
---
## 変更
### 20 個の Claude Desktop プリセットがデフォルトで直接接続モードに
20 個の Claude Desktop プリセットがデフォルトでプロキシモードから直接接続モードに切り替わり、プロキシ互換シムを必要としないユーザーの導入摩擦を低減しました。アップグレード前にこれらのプリセットのプロキシルーティング経由の接続性に依存していた場合は、アップグレード後に検証してください。
### Claude Desktop の操作制約
Claude Desktop のプロバイダーを切り替えると CC Switch 管理の 3P プロファイルが書き込まれます。**Claude Desktop の再起動**が必要です; プロキシモードのプロバイダーは、使用中 CC Switch の Local Routing が動作し続けている必要があります。
### Failover / Local Routing 連動検証
Failover コントロールは、ターゲットアプリの Local Routing テイクオーバーが有効になっていないと開けないように変更しました。プロキシサービスのみを止めてもテイクオーバー状態に依存するアプリがある場合はブロックされ、「プロキシは止めたがアプリはまだテイクオーバー中と認識している」という不整合を回避します。
### Usage 統計のセマンティクス変更
Usage サマリーは**キャッシュ正規化後の真の総トークン数**と**キャッシュヒット率**を報告するようになりました。データの重複排除と価格再計算により、過去のトークン数とコスト数値は**ずれる可能性があります** — 新しい数値の方が正確ですが、旧バージョンの数値とは一致しません。
### プロバイダープリセットのレンダリング順序
プリセットリストは作者が定義した配列順序でレンダリングされるようになり、パートナーが先頭に並びます。以前の暗黙的なソートを置き換えます。
### モデルマッピングヒント文面の簡素化
`modelMappingOffHint` を中 / 英 / 日でアクション指向の簡潔な文面に書き直しました。
### CC Switch ブランド公式サイトを ccswitch.io に統一
アプリ内および README 内のすべての「公式サイト」参照を、唯一の公式サイトとして ccswitch.io に統一しました; Release notes テンプレートにも ccswitch.io を反映。
### テーマ切り替えの簡素化
テーマ切り替え時の円形拡散アニメーションを削除し、即座にクロスフェードする方式に変更しました。
### Claude Code App スイッチャーの視覚的な区別
App スイッチャーで「Claude Code」と「Claude Desktop」を視覚的に区別し、アプリ可視性設定では「Claude Code」ラベルを使用するようにしました。
### CI: Claude Review を Opus 4.7 にアップグレード
Claude review GitHub Action を Opus 4.7 にアップグレード; nitpick ノイズを減らすためプロンプトを調整; `@claude` レビュー専用 Code Action を追加; PR head SHA を checkout 用にロック; `--max-turns 5` 制限を削除。
### GitHub Actions 依存関係のアップグレード
- `actions/checkout` 4 → 6 (#2517)
- `pnpm/action-setup` 5 → 6 (#2518)
- `softprops/action-gh-release` 2 → 3 (#2519)
- `actions/stale` 9 → 10 (#2520)
### DeepSeek プリセットを V4 に
DeepSeek プリセットが V4flash / pro)+ リフレッシュされた価格シードを出荷するようになりました。
### Codex 1M コンテキストトグルを編集フォームから隠す
Codex プロバイダー編集フォームでは 1M コンテキストトグルを表示しなくなり、現在の Codex デプロイメントには実効性のないノブの密度を低減しました。
### OpenClaudeCode を MicuAPI ドメインに移行
OpenClaudeCode プリセットを MicuAPI ドメインに移行; Micu API リンクを `micuapi.ai` にリフレッシュ。
### CrazyRouter エンドポイントを `cn` サブドメインに切り替え
CrazyRouter プリセットのエンドポイントを `cn` サブドメインに変更しました。
### RelaxyCode カスタムアイコン
RelaxyCode プリセットのアイコンをカスタム `relaxcode.png` アセットに変更しました。
### Kimi For Coding ドキュメント URL
Kimi For Coding のウェブサイト URL を `/code/docs/` パスに更新しました。
### SiliconFlow 国際版で USD 表示
SiliconFlow 国際版の残高を正しく USD で表示するように修正しました(以前は誤って CNY と表示)。
---
## 修正
### OpenAI Responses API usage 解析の堅牢化
`build_anthropic_usage_from_responses()` と Responses → Anthropic SSE トランスレーターを強化し、上流の欠損または不正な `usage``message_delta` 内で `"usage": null` を生成しないようにしました。これにより、厳格な Anthropic クライアント(典型例: VSCode Claude Code プラグイン)が一部のプロバイダー(Codex OAuth、DashScope の `compatible-mode/v1/responses` エンドポイント)で `Cannot read properties of null (reading 'output_tokens')` でクラッシュしていた問題が解消されます。OpenAI フィールド名のフォールバック(`prompt_tokens` / `completion_tokens`)、null / 空 / 部分オブジェクトの処理、input/output tokens が欠損していても cache token フィールドを保持する処理を追加しました (#2422, 感謝 @magucas)。
### プロキシ信頼性パッチ(P0–P3)
request-forwarder パス全体で複数回にわたるルーティング / ライフサイクル / リトライ / 補正器の修正を実施; 共有された `handle_rectifier_retry_failure` ヘルパーと `auth_header_value` ヘルパーを抽出。
### プロキシ: 非 Anthropic バックエンドの HTTPS コネクションプール再利用
非 Anthropic バックエンドはプールされた HTTPS コネクションを再利用し、リクエストごとに新しい TLS セッションを開かなくなりました。リクエスト単位のレイテンシが大幅に低減します。
### プロキシ: クライアントの実際の HTTP メソッドを転送
`POST` のハードコーディングをやめ、クライアントの実際の HTTP メソッドに従って転送するようになりました; 上流の非 POST エンドポイント(例: GET `/v1/models`)が正常に動作します。
### プロキシ: 試行ごとのカウンター + `max_retries` の接続
クライアントリクエストカウンターを試行ごとのループから外に移動; `AppProxyConfig.max_retries` がリクエストフォワーダーに正しく接続されるようになりました。
### プロキシ: フェイルオーバー判定の精緻化
リクエストフォワーダー内でのリトライ可能 / 不可能エラーの分類がより正確になりました。
### プロキシ: テイクオーバー検出の精緻化
テイクオーバー検出をより厳密にしました; テイクオーバー OFF 時はフォールバック復旧パスを通り、残留状態によってプロバイダーが固まらないようにします。
### プロキシ: Anthropic ↔ OpenAI `tool_choice` の相互変換
フォーマット変換時に Anthropic の `tool_choice` を OpenAI Chat のネスト形式に正しくマッピングするようになりました。
### プロキシ: Gemini リクエストのモデルを URI パスから抽出
Gemini リクエストのモデルを URI パスから抽出するようになりました(body からは取らない)。変換後のトラフィックが正しいモデル名を報告します。
### プロキシ: 認証ヘッダーのエラー処理
`get_auth_headers``Result` を返すようになり、認証情報に問題がある場合にパニックしなくなりました。
### プロキシ: IPv6 リッスンアドレスの検証
プロキシパネルが IPv6 リッスンアドレスを受け付けるようになりました。
### プロキシ: Codex / Responses キャッシュヒット率の改善
安定したキャッシュキー導出によって Codex と OpenAI Responses リクエストのキャッシュヒット率を改善: クライアントが本当にセッション識別子を持参してきた場合にのみ `prompt_cache_key` を送信し、無関係な会話が同じキーに潰されないようにする; 外部リクエストボディと `tool_call` 引数 / `tool_result` 内容内の JSON キーを正規化してソートし、プレフィックスキャッシュがバイト単位でマッチできるようにする; `session_id` を usage ロガーに通してリクエストを関連付けする。
### プロキシ: JSON Schema のアンダースコアフィールド保持
プライベートパラメータフィルタリングが JSON Schema name map`properties``patternProperties``definitions``$defs`)内のアンダースコア接頭辞のフィールド名を保持するようになりました。ユーザー定義 schema キー(`_id``_meta` など)がフィルターを正常に通り抜けられます。
### プロキシ: Read ツールの空白ページ除去
`Read` ツールの入力から空白ページを除去し、プロバイダーがリクエストを拒否しないようにしました (#2472, 感謝 @Kwensiu)。
### プロキシ: リクエスト単位のホットパス軽量化
リクエストごとのホットパスのオーバーヘッドとデータベース待ち時間を削減しました。
### プロキシ: テイクオーバー下で真のプロバイダーモデル名を表示
テイクオーバー実行時に、Claude Code メニューが古いエイリアスではなく真のプロバイダーモデル名を露出するようになりました。
### プロキシ: 最終 `message_delta` は常に usage を含む
最終 `message_delta` イベントには常に usage ブロックが含まれるようになりました(すべてゼロでも)。厳格な Anthropic クライアントが `null` でクラッシュしなくなります (#2485, 感謝 @Myoontyee)。
### プロキシ: ストリーミング `message_delta` の重複排除
一部の上流が二重に送信する `message_delta` イベントの重複排除を行います (#2366, 感謝 @codeasier)。
### プロキシ: ツール呼び出しパスでの `reasoning_content` 保持
ツール呼び出しパスの変換時に scoped `reasoning_content` フィールドを正しく保持するようにしました; Kimi / Moonshot の OpenAI Chat 互換パスではこのフィールドを保持し、汎用 OpenAI 互換リクエストでは引き続き付加しません (#2367, 感謝 @codeasier)。
### プロキシ: Vertex AI の完全 URL 保持
Vertex AI の完全 URL がプロキシ転送時に切り詰められないようにしました (#2415, 感謝 @xpfo-go)。
### プロキシ: system content 先頭の課金ヘッダーを除去
一部の上流が system message の先頭に挿入する課金ヘッダー内容を除去するようにしました (#2350)。
### プロキシ: Claude 認証ストラテジーを `ANTHROPIC_*` 環境変数名から導出
不透明なヒューリスティックに依存するのをやめ、認証ストラテジーを実際の `ANTHROPIC_*` 環境変数名から導出するようにしました。
### サードパーティ Claude プロバイダー: モデルテストの無効化
`/v1/models` を一貫して実装していないサードパーティ Claude ゲートウェイに対して、モデルプローブを無効化しました。
### Model-Fetch: Anthropic 互換サブパスプロバイダーの `/models`
`/models` ディスカバリーが Anthropic 互換のサブパスプロバイダーに対しても動作するようになりました。
### Copilot: Claude モデル ID をライブ `/models` と照合
Copilot バックエンドのプロバイダーはライブ `/models` リストを使って Claude モデル ID を照合し、古い ID の不整合を回避するようになりました。
### Codex: セッションタイトルが `environment_context` を取り込まないように
Codex のセッションタイトル抽出が `environment_context` のノイズを引き込まなくなりました (#2439, 感謝 @eclipsehx)。
### Codex: subagent セッションを非表示
Codex の subagent セッションをメインセッションリストから非表示にしました (#2445, 感謝 @LanternCX)。
### Codex 起動時の live import 重複排除
Codex 起動時の live import パスにおける重複インポートのバグを修正しました (#2590, 感謝 @DhruvShankpal)。
### Codex プロバイダー切り替えで履歴を擾乱しないように
アクティブな Codex プロバイダーの切り替えが既存のセッション履歴を変更しなくなりました (#2349, 感謝 @SaladDay)。
### Codex usage ログの文言修正
Codex セッション usage の誤解を招くログを 1 件修正しました (#2473, 感謝 @tisonkun)。
### Claude: `max` effort を env 経由で永続化
`max` effort が再起動をまたいで env 変数経由で正しく永続化されるようになりました (#2493, 感謝 @makoMakoGo)。
### Claude Desktop: モデルルーティングで `[1M]` サフィックスを要求しないように
ルーティングマッチングがレガシーな `[1M]` サフィックスを要求しなくなりました。
### Claude Desktop: プロバイダーフォームの入力フォーカス消失
Claude Desktop プロバイダーフォームで入力ボックス編集中にフォーカスを失う問題を修正しました。
### Claude Desktop: 偽の「プロキシ停止」ステータス通知
プロキシが能動的に停止された際に誤って発火するヒントを削除しました。
### Claude Desktop: 空のツールバーカプセル非表示
Claude Desktop がアクティブアプリの場合、空のツールバーカプセルを非表示にします。
### UI: Monitor バッジアイコンのセンタリング
App スイッチャー内の Monitor バッジアイコンをセンタリングしました。
### Linux: テーマ選択で segfault
Linux でテーマを選択した際の segfault を防止しました (#2502, 感謝 @definfo)。
### ターミナル: コールドスタート時の iTerm fallback
コールドスタート時に存在しない iTerm をフォールバックに選んでしまうのを防止しました (#2448, 感謝 @hulkbig)。
### 設定: JSON キーを辞書順でソート
設定の書き込みが JSON キーを辞書順にソートするようになり、出力が決定的になりました (#2469, 感謝 @fuleinist)。
### 「既存をインポート」を副作用なしに
「既存をインポート」操作を副作用なしに変更しました (#2429, 感謝 @xwil1)。
### Coding Plan: Zhipu の週次ウィンドウをリセット時刻で命名
Zhipu の週次ウィンドウのティア名を実際のリセット時刻に合うように修正しました (#2420, 感謝 @TuYv)。
### DashScope: usage 解析の堅牢化
DashScope の usage 解析を強化し、不正なペイロードが VSCode Claude Code プラグインをクラッシュさせないようにしました (#2425, 感謝 @magucas)。
### Usage: プロキシとセッションログの重複排除
プロキシとセッションログという 2 つのソースをまたいで usage レコードの重複排除を行います。
### Usage: キャッシュコストのセマンティクス + pricing 警告の嵐
キャッシュコストのセマンティクスを修正し、リクエストごとに発生していたノイズの多い pricing 警告を解消しました。
### CI: フロントエンドフォーマット + Linux clippy の復活
CI のフロントエンドフォーマットと Linux clippy の実行を復活させました。
### プロキシテストヘルパー clippy 警告
プロキシテストヘルパーの clippy 警告を 1 件修正しました。
---
## 削除
### Hermes Agent usage トラッキング統合
本サイクルでオンラインにする予定だった Hermes Agent usage トラッキング統合を削除しました — 上流の動作変更によって、この統合のメンテナンスが現実的でなくなりました。この統合は**いかなるリリース版でも有効化されたことはなく**; 開発過程で発見された「ゼロコストレンダリング」バグは統合をロールバックする前に修正済みです。
### テーマ切り替えの円形拡散アニメーション
テーマ切り替え時の円形拡散アニメーションを削除しました — 性能の弱いコンポジターでカクつき、視覚的なメリットが限定的でした。
### DDSHub パートナー統合
DDSHub をパートナープリセットから削除し、各 README 内の相互リンクセクションも削除しました。
---
## ドキュメント
### README スポンサー更新(中 / 英 / 日)
BytePlus、ClaudeCN、RunAPI、PatewayAI のスポンサーエントリを追加; BytePlus と Volcengine のエントリを相互リンク; CrazyRouter の $2 クレジット受領フロー、Compshare の説明、Right Code の説明、その他スポンサーのロゴおよびリストアイテムをリフレッシュ; LionCC のロゴを白背景にフラット化; 中国語 README のスポンサーロゴを Volcengine 画像に切り替え; README のサブタイトルに Hermes Agent を追加。
### Release notes テンプレート
Release notes テンプレート内に `ccswitch.io` を反映しました。
### ブランド公式サイト
各 README およびアプリ内参照で `ccswitch.io` を唯一の公式サイトとしてドキュメント化しました。
---
## ⚠️ アップグレード時の注意
### 20 個の Claude Desktop プリセットがデフォルトで直接接続モードに
これら 20 個のプリセットは以前はデフォルトでプロキシ経由でルーティングされていましたが、現在はデフォルトで直接接続です。アップグレード前にこのうちのいずれかを使用しており、かつプロキシルーティングの接続性に依存していた場合(例: プロキシに特殊な補正器や変換層がある場合)、接続性を検証してください; 必要に応じて、CC Switch パネル内で手動でプロキシモードに戻すことができます。
### Claude Desktop の操作制約
Claude Desktop プロバイダーの切り替えには、**Claude Desktop の再起動**が必要です; プロキシモードのプロバイダーは、使用中 CC Switch の Local Routing が動作し続けている必要があります — CC Switch を終了させたり Local Routing を停止させたりすると、プロキシモードの Claude Desktop プロバイダーへの接続が切断されます。
### Failover にはテイクオーバーの有効化が必要
Failover を有効化する前に、ターゲットアプリの Local Routing テイクオーバーが有効になっていることを確認してください。さもないと Failover コントロールは起動を拒否します; プロキシサービスを止めたいがテイクオーバーに依存するアプリがある場合はブロックされるため、アプリ層で先にテイクオーバーを止めてからプロキシを停止する必要があります。
### Usage 統計の数値が過去と一致しない可能性
Usage サマリーはキャッシュ正規化後の真の総トークン数 + キャッシュヒット率を使用するようになりました。データの重複排除と価格再計算により、過去のトークン数とコスト数値は**ずれる可能性があります** — 新しい数値の方が正確ですが、旧バージョンの数値とは一致しません。
---
## ⚠️ リスク通知
本リリースは、リバースプロキシ系機能について v3.12.3 / v3.13.0 で提起されたリスク通知を継承します。
**GitHub Copilot リバースプロキシ**: Copilot のリバースプロキシパスを使用すると、GitHub / Microsoft の利用規約に違反する可能性があります。詳細は [v3.12.3 リリースノート](v3.12.3-ja.md#-リスクに関する注意事項) を参照してください。
**Codex OAuth リバースプロキシ**: ChatGPT サブスクリプションを使用した Codex OAuth リバースプロキシは、OpenAI の利用規約に違反する可能性があります。詳細は [v3.13.0 リリースノート](v3.13.0-ja.md#-リスクに関する注意事項) を参照してください。
**Claude Desktop サードパーティプロバイダーのプロキシ切り替え**: CC Switch 内蔵プロキシゲートウェイ経由で Claude Desktop のリクエストをサードパーティプロバイダーに転送する際、サードパーティプロバイダーの課金、コンプライアンス、データ保持に関する制約はそれぞれ異なります。利用前にターゲットプロバイダーの利用規約をお読みください。
ユーザーが上記機能を有効化することで、**すべてのリスクを自己責任で**受諾したものとみなされます。CC Switch は、これらの機能の使用に起因するアカウントの制限、警告、サービス停止について一切の責任を負いません。
---
## ダウンロード・インストール
[Releases](https://github.com/farion1231/cc-switch/releases/latest) から対応バージョンをダウンロードしてください。
### システム要件
| OS | 最小バージョン | アーキテクチャ |
| ------- | ------------------------ | ----------------------------------- |
| Windows | Windows 10 以降 | x64 |
| macOS | macOS 12 (Monterey) 以降 | Intel (x64) / Apple Silicon (arm64) |
| Linux | 下表参照 | x64 / ARM64 |
### Windows
| ファイル | 説明 |
| ---------------------------------------- | ------------------------------------------- |
| `CC-Switch-v3.15.0-Windows.msi` | **推奨** - MSI インストーラー、自動更新対応 |
| `CC-Switch-v3.15.0-Windows-Portable.zip` | ポータブル版、解凍して実行、レジストリ不要 |
### macOS
| ファイル | 説明 |
| -------------------------------- | ------------------------------------------------------ |
| `CC-Switch-v3.15.0-macOS.dmg` | **推奨** - DMG インストーラー、Applications にドラッグ |
| `CC-Switch-v3.15.0-macOS.zip` | 解凍して Applications にドラッグ、Universal Binary |
| `CC-Switch-v3.15.0-macOS.tar.gz` | Homebrew インストールと自動更新用 |
> macOS 版は Apple のコード署名および公証済みで、直接インストールして使用できます。
### HomebrewmacOS
> 🎉 CC Switch は Homebrew 公式 cask リポジトリに収録されました。カスタム tap の追加は不要です!
```bash
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
> Linux 向けの成果物は **x86_64** と **ARM64**`aarch64`)の両方が提供されます。ファイル名にアーキテクチャ識別子が含まれているため、`uname -m` の出力に応じて選択してください:
>
> - `CC-Switch-v3.15.0-Linux-x86_64.AppImage` / `.deb` / `.rpm`
> - `CC-Switch-v3.15.0-Linux-arm64.AppImage` / `.deb` / `.rpm`
| ディストリビューション | 推奨形式 | インストール方法 |
| --------------------------------------- | ----------- | -------------------------------------------------------------------------- |
| Ubuntu / Debian / Linux Mint / Pop!\_OS | `.deb` | `sudo dpkg -i CC-Switch-*.deb` または `sudo apt install ./CC-Switch-*.deb` |
| Fedora / RHEL / CentOS / Rocky Linux | `.rpm` | `sudo rpm -i CC-Switch-*.rpm` または `sudo dnf install ./CC-Switch-*.rpm` |
| openSUSE | `.rpm` | `sudo zypper install ./CC-Switch-*.rpm` |
| Arch Linux / Manjaro | `.AppImage` | 実行権限を付与して実行、または AUR を使用 |
| その他のディストリビューション / 不明 | `.AppImage` | `chmod +x CC-Switch-*.AppImage && ./CC-Switch-*.AppImage` |
+527
View File
@@ -0,0 +1,527 @@
# CC Switch v3.15.0
> Claude Desktop 升级为一等管理面板(含第三方供应商代理切换)、按角色的模型映射、反向代理大幅强化、Codex OAuth 实时模型发现、用量看板筛选驱动 Hero 卡
**[English →](v3.15.0-en.md) | [日本語版 →](v3.15.0-ja.md)**
---
> [!WARNING]
>
> ## 唯一官方渠道声明(请务必阅读)
>
> CC Switch 是**完全免费、开源**的桌面应用,**不会向用户收取任何费用**。最近发现多个山寨网站冒用 CC Switch 名义诱导用户付费、收集账号信息,部分已造成实际经济损失。请仅通过下列官方渠道获取本软件:
>
> | 类别 | 唯一官方 |
> | -------- | ------------------------------------------------------------------------------ |
> | 官网 | **[ccswitch.io](https://ccswitch.io)** |
> | 源码 | **[github.com/farion1231/cc-switch](https://github.com/farion1231/cc-switch)** |
> | 下载 | **[GitHub Releases](https://github.com/farion1231/cc-switch/releases)** |
> | 作者 | **[@farion1231](https://github.com/farion1231)** |
> | 举报山寨 | **[GitHub Issues](https://github.com/farion1231/cc-switch/issues)** |
>
> **任何向你收费、要求充值、或索取登录凭据的"CC Switch"网站或客户端均为假冒**。如果你被诱导支付了费用,请立即停止操作并通过 GitHub Issues 反馈,让我们能尽快下线相关山寨站点。
---
## Claude Desktop 使用攻略
本版本最主打的能力是 **Claude Desktop 一等管理面板**。如果你已经在 Claude Code 里配置了很多供应商,建议先阅读这篇攻略:
**[使用 CC Switch,一键配置、管理和切换 Claude Desktop 供应商](../user-manual/zh/2-providers/2.6-claude-desktop.md)**
攻略覆盖从 Claude Code 一键导入已有供应商、添加 Claude Desktop 专属供应商、直连 / 模型映射两种模式、本地路由开关显示设置,到恢复 Claude Desktop 官方登录模式的完整流程。
---
## 概览
CC Switch v3.15.0 是 v3.14.x 之后的一次大版本更新,核心聚焦在**把 Claude Desktop 升级为一等管理面板**,并配套提供第三方供应商通过内置代理网关进行切换、按角色的模型映射(sonnet / opus / haiku+ `supports1m` 长上下文标志、Copilot/Codex OAuth 供应商复用、重新设计的 Claude Code 导入流程、App 切换器对"Claude Code"和"Claude Desktop"的可视化区分,以及 44 个从 Claude Code 预设目录翻译而来的 Claude Desktop 预设。
围绕反向代理的可靠性,本版本进行了一次系统性硬化:P0–P3 多轮针对路由 / 生命周期 / 重试 / 故障转移 / 补正器的修补;非 Anthropic 后端启用 HTTPS 连接池复用以降低单请求延迟;Codex 与 OpenAI Responses 缓存命中率提升(`prompt_cache_key` 仅在有真实客户端会话标识时发送、对外请求体与 `tool_call` 参数 / `tool_result` 内容的 JSON key 规范化排序、`session_id` 串入用量记录器);Anthropic ↔ OpenAI `tool_choice` 正确互转;Vertex AI 完整 URL 不再被截断;Gemini 改为从 URI 路径提取模型名;Local Routing 接管检测更精细;可监听 IPv6 地址。Codex OAuth 类 Claude 供应商不再依赖硬编码的模型列表,CC Switch 会按需从 ChatGPT 后端拉取实时模型列表。
Claude Code 的模型映射改为基于角色(`sonnet` / `opus` / `haiku`+ 显示名,并引入 `supports1m` 布尔标志,替代旧版的 `[1M]` 后缀写法,把路由决策与原始模型 ID 解耦。用量看板新增**筛选驱动的 Hero 卡**,展示缓存归一化后的真实总 token 与缓存命中率,并跟随当前日期范围 / 供应商 / 模型筛选实时更新;配套修复了缓存成本语义错误以及每个请求都触发的定价警告噪声。在 OpenAI Responses API usage 解析路径上做了鲁棒化处理,让上游缺失或畸形的 `usage` 不再让 VSCode Claude Code 插件因 `null` 输出崩溃。
供应商生态进一步扩张:新增 BytePlus、火山 Agentplan、ClaudeAPI、ClaudeCN、RunAPI、RelaxyCode、PatewayAI、百度千帆 Coding Plan 合作伙伴预设;豆包 Seed 升级为合作伙伴预设;供应商卡片现在会显示"是否支持 Local Routing"的徽章。本版本还修复了大量 Codex 会话、OAuth、Claude Desktop 表单、Linux 段错误、终端 fallback 等场景下的细节问题,并完成了多项 GitHub Actions 依赖升级。
**发布日期**2026-05-16
**更新规模**127 commits | 211 files changed | +17,980 / -2,748 lines
---
## 重点内容
- **Claude Desktop 成为一等管理面板**:通过内置代理网关提供第三方供应商切换、按角色的模型映射(sonnet / opus / haiku+ `supports1m` 长上下文标志、Copilot/Codex OAuth 供应商复用、44 个从 Claude Code 预设目录翻译过来的预设。注意:20 个 Claude Desktop 预设默认从代理模式切到直连模式,升级后如依赖代理路由请验证连通性
- **反向代理大幅强化**:P0–P3 生命周期 / 重试 / 故障转移 / 补正器修补;非 Anthropic 后端 HTTPS 连接池复用;Codex/Responses 缓存命中率提升;Anthropic ↔ OpenAI `tool_choice` 正确映射;Vertex AI URL 完整保留;Gemini 路径式模型提取;接管检测细化;支持 IPv6 监听地址
- **供应商生态扩张**:新增 BytePlus、火山 Agentplan、ClaudeAPI、ClaudeCN、RunAPI、RelaxyCode、PatewayAI、百度千帆 Coding Plan 合作伙伴预设;豆包 Seed 升级合作伙伴;供应商卡片显示"路由代理支持"徽章
- **按角色的模型映射 + 1M 标志**:基于角色的 sonnet / opus / haiku 路由 + 显示名 + `supports1m` 标志,替代旧的 `[1M]` 后缀
- **Codex OAuth 实时模型发现**ChatGPT Codex 类供应商按需从 ChatGPT 后端拉取实时模型列表
- **用量看板筛选驱动 Hero**:展示缓存归一化的真实总 token 和缓存命中率,跟随当前日期 / 供应商 / 模型筛选实时更新
- **DeepSeek 工具调用 + 零 usage 最终 delta**DeepSeek 工具调用一并返回 `reasoning_content` (#2543, 感谢 @bling-yshs);最终 `message_delta` 总是带 usage 块(即便全为 0),严格 Anthropic 客户端不再因 `null` 崩溃 (#2485, 感谢 @Myoontyee)
- **OpenAI Responses API usage 解析鲁棒化**:让上游缺失或畸形 usage 不再让 VSCode Claude Code 插件崩溃 (#2422, 感谢 @magucas)
---
## 新功能
### Claude Desktop 第三方供应商代理切换
CC Switch 第一次把 **Claude Desktop** 作为一等受管面板对待,与 Claude Code / Codex / Gemini / OpenCode / OpenClaw / Hermes 并列。
- 新增 Claude Desktop 专属面板,通过 CC Switch 内置代理网关把第三方供应商代理给 Claude Desktop
- 为需要路由代理的供应商在卡片上呈现"是否支持 Local Routing"的徽章
- 按角色的模型路由映射,锁定到 `sonnet` / `opus` / `haiku`
- Copilot / Codex OAuth 供应商在 Claude Desktop 面板中可复用
- 重新设计的 Claude Code 设置导入流程
- App 切换器视觉区分"Claude Code"与"Claude Desktop",应用可见性设置中使用"Claude Code"标签
- 44 个从 Claude Code 预设目录翻译过来的 Claude Desktop 供应商预设
### 供应商卡片:路由代理支持徽章
Claude Code 与 Codex 面板中的供应商卡片新增"路由代理支持"徽章,方便一眼识别哪些供应商可以通过 Local Routing 提供服务。
### Codex OAuth 实时模型列表
ChatGPT Codex 类供应商不再依赖硬编码的模型选择,CC Switch 会按需从 ChatGPT 后端拉取**实时模型列表**。
### 按角色的模型映射 + 1M 标志
Claude Code 模型映射改为基于角色(`sonnet` / `opus` / `haiku`+ 显示名,并引入 `supports1m` 布尔标志,替代旧版 `[1M]` 后缀,把路由决策与原始模型 ID 解耦。
### 用量看板筛选驱动 Hero
用量看板的 Hero 摘要现在是筛选驱动的,跟随当前日期范围 / 供应商 / 模型筛选实时变化;展示**缓存归一化后的真实总 token**与缓存命中率,让 Hero 数字与下方明细列表对齐。
### 供应商表单"先存上再说"
软化供应商表单的输入校验,把非阻塞性的输入问题改为"先存上再说"的提示,不会因为一个无伤大雅的字段问题阻止保存 (#2307, 感谢 @allenxln)。
### Universal 供应商复制动作
为 universal 供应商在供应商列表中新增"复制"按钮 (#2416, 感谢 @hubutui)。
### 持久化 Tauri 窗口状态
窗口位置和尺寸现在跨重启保留 (#2377, 感谢 @BillSaul)。
### 托盘图标 hover 提示
系统托盘图标现在悬浮显示状态提示 (#2417, 感谢 @Coconut-Fish)。
### Warp 终端会话启动
新增对 Warp 终端的支持,可在 Warp 中执行保存的会话 (#2466, 感谢 @tisonkun)。
### DeepSeek 工具调用 `reasoning_content`
DeepSeek 工具调用响应现在同时返回 `reasoning_content``tool_calls`,调用方可以两者一并渲染 (#2543, 感谢 @bling-yshs)。
### 百度千帆 Coding PlanClaude Code
新增百度千帆 Coding Plan 预设 (#2322, 感谢 @jimmyzhuu)。
### Compshare Coding Plan 预设(跨应用)
Compshare Coding Plan 预设跨 claude / codex / hermes / openclaw 全应用就位。
### 合作伙伴供应商预设
新增 **BytePlus**、**火山 Agentplan**、**ClaudeAPI**、**ClaudeCN**、**RunAPI**、**RelaxyCode**、**PatewayAI** 合作伙伴预设;**豆包 Seed** 升级合作伙伴预设(端点和链接刷新)。
### 44 个 Claude Desktop 供应商预设
从 Claude Code 预设目录翻译 44 个供应商预设进入新的 Claude Desktop 面板。
---
## 变更
### 20 个 Claude Desktop 预设默认切到直连模式
20 个 Claude Desktop 预设默认从代理模式切到直连模式,降低对不需要代理兼容垫片的用户的上手摩擦。如果你升级前依赖代理路由这些预设的连通性,请升级后验证。
### Claude Desktop 操作约束
切换 Claude Desktop 供应商会写入 CC Switch 管理的 3P profile**需要重启 Claude Desktop** 才能生效;代理模式的供应商在使用期间需要 CC Switch 的 Local Routing 保持运行。
### Failover / Local Routing 联动校验
Failover 控件现在要求目标应用的 Local Routing 接管已启用才能开启;只关代理服务但仍有应用依赖接管状态的情况会被拦下,避免出现"代理关了但应用仍以为接管在跑"的不一致。
### 用量统计语义变化
用量摘要现在报告**缓存归一化后的真实总 token**和**缓存命中率**。历史 token 与成本数字在数据去重 + 价格重算后**可能会有偏移**——新数字更准,但不会等于旧版给出的数字。
### 供应商预设渲染顺序
预设列表现在按作者定义的数组顺序渲染,合作伙伴排前面,替代之前的隐式排序。
### 模型映射提示文案简化
`modelMappingOffHint` 跨中 / 英 / 日重写为动作导向的简洁文案。
### CC Switch 品牌官网统一到 ccswitch.io
应用内和 README 中所有"官网"引用都统一到 ccswitch.io 作为唯一官方网站;Release notes 模板也呈现 ccswitch.io。
### 主题切换简化
移除主题切换时的圆形扩散动画,改为即时交叉淡入。
### Claude Code App 切换器视觉区分
App 切换器视觉上区分"Claude Code"和"Claude Desktop",应用可见性设置中使用"Claude Code"标签。
### CIClaude Review 升级到 Opus 4.7
Claude review GitHub Action 升级到 Opus 4.7;调整 prompt 降低 nitpick 噪声;新增 `@claude` 仅 review 的 Code Action;锁定 PR head SHA 用于 checkout;移除 `--max-turns 5` 限制。
### GitHub Actions 依赖升级
- `actions/checkout` 4 → 6 (#2517)
- `pnpm/action-setup` 5 → 6 (#2518)
- `softprops/action-gh-release` 2 → 3 (#2519)
- `actions/stale` 9 → 10 (#2520)
### DeepSeek 预设切到 V4
DeepSeek 预设现在出货 V4flash / pro)+ 刷新定价种子。
### Codex 1M 上下文开关在编辑表单隐藏
Codex 供应商编辑表单中不再呈现 1M 上下文开关,降低对当前 Codex 部署无实际效果的旋钮密度。
### OpenClaudeCode 迁移到 MicuAPI 域名
OpenClaudeCode 预设迁移到 MicuAPI 域名;Micu API 链接刷新到 `micuapi.ai`
### CrazyRouter 端点切到 `cn` 子域
CrazyRouter 预设端点改用 `cn` 子域。
### RelaxyCode 自定义图标
RelaxyCode 预设图标改用自定义 `relaxcode.png` 资源。
### Kimi For Coding 文档 URL
Kimi For Coding 网站 URL 更新到 `/code/docs/` 路径。
### SiliconFlow 国际站显示 USD
SiliconFlow 国际站的余额显示正确为 USD(之前错显 CNY)。
---
## 修复
### OpenAI Responses API usage 解析鲁棒化
强化 `build_anthropic_usage_from_responses()` 与 Responses → Anthropic SSE 翻译器,让上游缺失或畸形的 `usage` 不再在 `message_delta` 中产出 `"usage": null`。这解决了严格 Anthropic 客户端(典型如 VSCode Claude Code 插件)在某些供应商(Codex OAuth、DashScope 的 `compatible-mode/v1/responses` 端点)下崩在 `Cannot read properties of null (reading 'output_tokens')` 的问题。增加 OpenAI 字段名回退(`prompt_tokens` / `completion_tokens`)、null / 空 / 部分对象处理、即使 input/output tokens 缺失也保留缓存 token 字段 (#2422, 感谢 @magucas)。
### 代理可靠性补丁(P0P3
跨 request-forwarder 路径多轮路由 / 生命周期 / 重试 / 补正器修补;抽取共享的 `handle_rectifier_retry_failure` helper 与 `auth_header_value` helper。
### 代理:非 Anthropic 后端 HTTPS 连接池复用
非 Anthropic 后端复用池化的 HTTPS 连接,不再每个请求开新 TLS session,显著降低单请求延迟。
### 代理:转发客户端真实 HTTP 方法
不再硬编码 `POST`,按客户端实际的 HTTP 方法转发;上游的非 POST 端点(如 GET `/v1/models`)现在能正常工作。
### 代理:每次尝试计数器 + `max_retries` 接线
客户端请求计数器移出每次尝试的循环;`AppProxyConfig.max_retries` 现在正确接到请求转发器。
### 代理:故障转移判定细化
请求转发器中重试 / 不可重试错误的分类更准确。
### 代理:接管检测细化
接管检测更紧;关接管时走 fallback 恢复,避免遗留状态把供应商卡住。
### 代理:Anthropic ↔ OpenAI `tool_choice` 互转
格式转换时把 Anthropic 的 `tool_choice` 正确映射到 OpenAI Chat 的嵌套形式。
### 代理:Gemini 请求模型从 URI 路径提取
Gemini 请求模型从 URI 路径提取(不再从 body 取),转换后的流量上报正确的模型名。
### 代理:认证 header 错误处理
`get_auth_headers` 现在返回 `Result`,凭据有问题时不再 panic。
### 代理:IPv6 监听地址校验
代理面板现在接受 IPv6 监听地址。
### 代理:Codex / Responses 缓存命中率提升
通过稳定缓存键派生提高 Codex 与 OpenAI Responses 请求的缓存命中率;只在客户端确实带了会话标识时才发 `prompt_cache_key`,避免不相关对话被坍缩到同一个 key 上;对外请求体与 `tool_call` 参数 / `tool_result` 内容里的 JSON key 做规范化排序以便前缀缓存能字节级匹配;把 `session_id` 串到 usage 日志记录器做请求关联。
### 代理:JSON Schema 下划线字段保留
私参过滤现在保留 JSON Schema name map`properties``patternProperties``definitions``$defs`)内的下划线前缀字段名,用户自定义 schema key(如 `_id``_meta`)能正常穿过过滤。
### 代理:Read 工具空白页剔除
`Read` 工具输入中剔除空白页,避免供应商拒绝请求 (#2472, 感谢 @Kwensiu)。
### 代理:单请求热路径瘦身
缩减每个请求的热路径开销和数据库等待时间。
### 代理:接管下展示真实供应商模型名
接管运行时,Claude Code 菜单现在暴露真实供应商模型名,不是陈旧的 alias。
### 代理:最终 `message_delta` 总是带 usage
最终 `message_delta` 事件现在总是包含 usage 块(即使全为 0),严格 Anthropic 客户端不再因为 `null` 崩溃 (#2485, 感谢 @Myoontyee)。
### 代理:流式 `message_delta` 去重
对某些上游会发两次的 `message_delta` 事件做去重 (#2366, 感谢 @codeasier)。
### 代理:工具调用路径的 `reasoning_content` 保留
工具调用路径转换时正确保留 scoped `reasoning_content` 字段;Kimi / Moonshot 的 OpenAI Chat 兼容路径保留该字段,通用 OpenAI 兼容请求保持不带 (#2367, 感谢 @codeasier)。
### 代理:Vertex AI 完整 URL 保留
Vertex AI 的完整 URL 在代理转发时不再被截断 (#2415, 感谢 @xpfo-go)。
### 代理:剥离 system content 开头的计费 header
某些上游会在 system message 开头插一段计费 header 内容,现在被剥离 (#2350)。
### 代理:Claude 鉴权策略从 `ANTHROPIC_*` 环境变量名派生
不再依赖不透明的启发式,鉴权策略从实际的 `ANTHROPIC_*` 环境变量名派生。
### 第三方 Claude 供应商:禁用模型测试
对那些不一致实现 `/v1/models` 的第三方 Claude 网关,关闭模型探测。
### Model-FetchAnthropic 兼容子路径供应商的 `/models`
`/models` 发现现在对 Anthropic 兼容的子路径供应商生效。
### CopilotClaude 模型 ID 对比实时 `/models`
Copilot 后端的供应商现在用实时 `/models` 列表来比对 Claude 模型 ID,避免陈旧 ID 不一致。
### Codex:会话标题不再吸入 `environment_context`
Codex 会话标题提取不再把 `environment_context` 的噪声拉进来 (#2439, 感谢 @eclipsehx)。
### Codex:隐藏 subagent 会话
Codex subagent 会话从主会话列表隐藏 (#2445, 感谢 @LanternCX)。
### Codex 启动期 live import 去重
修复 Codex 启动期 live import 路径里的重复导入 bug (#2590, 感谢 @DhruvShankpal)。
### Codex 供应商切换不再扰动历史
切换激活 Codex 供应商不再改动现有会话历史 (#2349, 感谢 @SaladDay)。
### Codex 用量日志措辞修正
修正一条 Codex 会话用量的误导性日志 (#2473, 感谢 @tisonkun)。
### Claude`max` effort 通过 env 持久化
`max` effort 现在能跨重启正确通过 env 变量持久化 (#2493, 感谢 @makoMakoGo)。
### Claude Desktop:模型路由不再要求 `[1M]` 后缀
路由匹配不再要求遗留的 `[1M]` 后缀。
### Claude Desktop:供应商表单输入失焦
修复 Claude Desktop 供应商表单中输入框编辑时丢失焦点的问题。
### Claude Desktop:假的"代理停止"状态提示
移除代理主动停止时假触发的提示。
### Claude Desktop:空工具栏胶囊隐藏
当 Claude Desktop 是激活应用时,空的工具栏胶囊会被隐藏。
### UIMonitor 徽章图标居中
在 App 切换器里居中 Monitor 徽章图标。
### Linux:选择主题触发 segfault
防止在 Linux 上选择主题触发 segfault (#2502, 感谢 @definfo)。
### 终端:冷启动时 iTerm fallback
防止冷启动时把不存在的 iTerm 选为 fallback (#2448, 感谢 @hulkbig)。
### 配置:JSON key 字母序排序
配置写入现在按字母序排 JSON key,输出确定 (#2469, 感谢 @fuleinist)。
### "导入已有"无副作用化
"导入已有"操作改为无副作用 (#2429, 感谢 @xwil1)。
### Coding Plan:智谱周窗口按重置时间命名
修正智谱周窗口的等级名以匹配实际重置时间 (#2420, 感谢 @TuYv)。
### DashScopeusage 解析鲁棒化
强化 DashScope usage 解析,畸形 payload 不会再让 VSCode Claude Code 插件崩 (#2425, 感谢 @magucas)。
### 用量:代理和会话日志去重
跨代理和会话日志两个来源的用量记录去重。
### 用量:缓存成本语义 + 定价警告风暴
修正缓存成本语义,并消除每个请求都触发的噪声定价警告。
### CI:前端格式化 + Linux clippy 恢复
恢复前端格式化与 Linux clippy 在 CI 中的运行。
### 代理测试 helper clippy 警告
修复代理测试 helper 中的一个 clippy 警告。
---
## 移除
### Hermes Agent 用量追踪集成
移除原本计划在本周期上线的 Hermes Agent 用量追踪集成——上游行为变化让维护这个集成变得不切实际。该集成**从未在任何已发布版本中启用**;开发过程中发现的"零成本渲染" bug 在回滚集成前已经修复。
### 主题切换圆形扩散动画
移除主题切换时的圆形扩散动画——在性能较弱的合成器上会卡顿,视觉收益有限。
### DDSHub 合作伙伴整合
移除 DDSHub 作为合作伙伴预设,并删除各 README 中的交叉链接段落。
---
## 文档
### README 赞助商刷新(中 / 英 / 日)
新增 BytePlus、ClaudeCN、RunAPI、PatewayAI 赞助商条目;交叉链接 BytePlus 与火山条目;刷新 CrazyRouter 的 $2 额度领取流程、Compshare 描述、Right Code 描述、其他赞助商的 logo 与列表项;把 LionCC logo 抹平到白底;中文 README 的赞助商 logo 切到火山图;在 README 副标题中加入 Hermes Agent。
### Release notes 模板
Release notes 模板中呈现 `ccswitch.io`
### 品牌官网
在各 README 与应用内引用中把 `ccswitch.io` 文档化为唯一官方网站。
---
## ⚠️ 升级提醒
### 20 个 Claude Desktop 预设默认切到直连模式
这 20 个预设之前默认通过代理路由,现在默认直连。如果你升级前正好用着其中某个、又依赖代理路由的连通性(比如代理里有特殊补正器或转换层),请验证一下连通性;如有需要,可在 CC Switch 面板里手动切回代理模式。
### Claude Desktop 操作约束
切换 Claude Desktop 供应商需要**重启 Claude Desktop** 才能生效;代理模式的供应商在使用期间需要 CC Switch 的 Local Routing 保持运行——退出 CC Switch 或停止 Local Routing 会让代理模式的 Claude Desktop 供应商断流。
### Failover 需要接管启用
启用 Failover 前请先确认目标应用的 Local Routing 接管已开启,否则 Failover 控件会拒绝启动;想关代理服务但仍有应用依赖接管的情况会被拦下,需要先在应用层关掉接管再停代理。
### 用量统计数字可能与历史不一致
用量摘要现在用缓存归一化的真实总 token + 缓存命中率。历史 token 与成本数字在数据去重 + 价格重算后**可能会有偏移**——新数字更准,但不会等于旧版给出的数字。
---
## ⚠️ 风险提示
本版本在涉及反向代理类功能上沿用 v3.12.3 / v3.13.0 提出的风险提示。
**GitHub Copilot 反向代理**:使用 Copilot 的反代路径可能违反 GitHub / Microsoft 服务条款。详情见 [v3.12.3 release notes](v3.12.3-zh.md#-风险提示)。
**Codex OAuth 反向代理**:使用 ChatGPT 订阅的 Codex OAuth 反代可能违反 OpenAI 服务条款,详情见 [v3.13.0 release notes](v3.13.0-zh.md#-风险提示)。
**Claude Desktop 第三方供应商代理切换**:通过 CC Switch 内置代理网关把 Claude Desktop 的请求转到第三方供应商时,第三方供应商对计费、合规与数据留存的约束各不相同,请在使用前阅读目标供应商的服务条款。
用户启用上述功能即表示**自行承担所有风险**。CC Switch 不对因使用这些功能而导致的任何账号限制、警告或服务暂停承担责任。
---
## 下载与安装
访问 [Releases](https://github.com/farion1231/cc-switch/releases/latest) 下载对应版本。
### 系统要求
| 系统 | 最低版本 | 架构 |
| ------- | -------------------------- | ----------------------------------- |
| Windows | Windows 10 及以上 | x64 |
| macOS | macOS 12 (Monterey) 及以上 | Intel (x64) / Apple Silicon (arm64) |
| Linux | 见下表 | x64 / ARM64 |
### Windows
| 文件 | 说明 |
| ---------------------------------------- | ----------------------------------- |
| `CC-Switch-v3.15.0-Windows.msi` | **推荐** - MSI 安装包,支持自动更新 |
| `CC-Switch-v3.15.0-Windows-Portable.zip` | 便携版,解压即用,不写入注册表 |
### macOS
| 文件 | 说明 |
| -------------------------------- | --------------------------------------------- |
| `CC-Switch-v3.15.0-macOS.dmg` | **推荐** - DMG 安装包,拖入 Applications 即可 |
| `CC-Switch-v3.15.0-macOS.zip` | 解压后拖入 ApplicationsUniversal Binary |
| `CC-Switch-v3.15.0-macOS.tar.gz` | 用于 Homebrew 安装和自动更新 |
> macOS 版本已通过 Apple 代码签名和公证,可直接安装使用。
### HomebrewmacOS
> 🎉 CC Switch 现已收录至 Homebrew 官方 cask 仓库,无需添加第三方 tap!
```bash
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
> Linux 资产同时提供 **x86_64** 和 **ARM64**`aarch64`)两种架构。资产文件名中包含架构标识,请按你机器的 `uname -m` 输出选择对应版本:
>
> - `CC-Switch-v3.15.0-Linux-x86_64.AppImage` / `.deb` / `.rpm`
> - `CC-Switch-v3.15.0-Linux-arm64.AppImage` / `.deb` / `.rpm`
| 发行版 | 推荐格式 | 安装方式 |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| Ubuntu / Debian / Linux Mint / Pop!\_OS | `.deb` | `sudo dpkg -i CC-Switch-*.deb``sudo apt install ./CC-Switch-*.deb` |
| Fedora / RHEL / CentOS / Rocky Linux | `.rpm` | `sudo rpm -i CC-Switch-*.rpm``sudo dnf install ./CC-Switch-*.rpm` |
| openSUSE | `.rpm` | `sudo zypper install ./CC-Switch-*.rpm` |
| Arch Linux / Manjaro | `.AppImage` | 添加执行权限后直接运行,或使用 AUR |
| 其他发行版 / 不确定 | `.AppImage` | `chmod +x CC-Switch-*.AppImage && ./CC-Switch-*.AppImage` |
+433
View File
@@ -0,0 +1,433 @@
# CC Switch v3.16.0
> Chat Completions → Responses format conversion for Codex (you can now use DeepSeek, Kimi, GLM in Codex!), unified Codex provider identity and history, an all-around upgraded app management surface, partner preset expansion, default model / pricing matrix upgraded to GPT-5.5 and Claude Opus 4.8, and proxy / format-conversion robustness hardening
**[中文版 →](v3.16.0-zh.md) | [日本語版 →](v3.16.0-ja.md)**
---
> [!WARNING]
>
> ## Only Official Channels (Please Read)
>
> CC Switch is a **fully free and open-source** desktop app, and we **do not charge users any fees**. Multiple imposter websites have recently been spotted impersonating CC Switch to solicit payments and harvest account credentials, with some users already reporting financial losses. Please only obtain the software through the official channels listed below:
>
> | Channel | Only Official |
> | ------------------ | ------------------------------------------------------------------------------ |
> | Website | **[ccswitch.io](https://ccswitch.io)** |
> | Source | **[github.com/farion1231/cc-switch](https://github.com/farion1231/cc-switch)** |
> | Downloads | **[GitHub Releases](https://github.com/farion1231/cc-switch/releases)** |
> | Author | **[@farion1231](https://github.com/farion1231)** |
> | Report an Imposter | **[GitHub Issues](https://github.com/farion1231/cc-switch/issues)** |
>
> **Any "CC Switch" website or client that asks you for payment, top-ups, or login credentials is fake.** If you have been tricked into paying, stop the transaction immediately and file a report through GitHub Issues so we can take down the imposter site as quickly as possible.
---
## Usage Guide
The two headline capabilities in this release are **Codex third-party provider Chat Completions routing** and **in-app managed CLI tool management**. If you want providers that only speak the OpenAI Chat protocol (DeepSeek, Kimi, MiniMax, etc.) to work directly in Codex, or want to install / upgrade CLI tools from one place inside the app, start with these two:
- **[Add a Codex provider: Chat Completions routing and model mapping](../user-manual/en/2-providers/2.1-add.md)** — covers the "Needs Local Routing" toggle, the model mapping table, and reasoning (thinking) auto-detection.
- **[Settings → About: managed CLI tool management](../user-manual/en/1-getting-started/1.5-settings.md)** — covers version detection, per-tool / update-all upgrades, conflict diagnostics, and source-anchored upgrade commands.
---
## Overview
CC Switch v3.16.0's development since v3.15.0 centers on **promoting third-party Codex providers to first-class citizens through Chat Completions routing**. Codex natively only speaks the OpenAI Responses API and GPT-family models; this release lets CC Switch's local proxy convert Codex's outgoing Responses requests into Chat Completions and rebuild the JSON and SSE streaming responses back into Responses shape, preserving `reasoning_content` / inline `<think>` blocks / streamed reasoning summaries / tool calls / `previous_response_id` follow-ups along the way, normalizing error envelopes, and probing Chat-format providers correctly in Stream Check. It ships 22 Chat-routing presets with explicit model catalogs (DeepSeek, Zhipu GLM, Kimi, MiniMax, StepFun, Baidu Qianfan, Bailian, ModelScope, Longcat, BaiLing, Xiaomi MiMo, Volcengine Agentplan, BytePlus, DouBao Seed, SiliconFlow, Novita AI, Nvidia, and more).
Codex third-party providers' **identity and history** are unified and hardened this release: all third-party providers now normalize to the stable `custom` model-provider bucket, with a one-shot device migration that rewrites historical JSONL sessions and the `state_5.sqlite` threads table (originals backed up under `~/.cc-switch/backups/`), preventing past sessions from appearing to vanish when provider ids change. It also fixes OAuth login state, user-selected catalog models, and user-authored provider ids being overwritten during live reads / switches.
This release also adds an **in-app managed CLI tool lifecycle**: the Settings / About tab becomes a tool management panel for Claude / Codex / Gemini / OpenCode / OpenClaw / Hermes, with silent install / update, update-all, conflict diagnostics, source-aware anchored upgrades, WSL handling, and visible "installed but not runnable" states.
The provider ecosystem and model matrix are refreshed in tandem: added APIKEY.FUN, APINebula, AtlasCloud, SudoCode, Xiaomi MiMo Token Plan, and Claude Desktop Official presets; refreshed partner links and default models / pricing across apps; upgraded the default Claude Opus line to **4.8** and GPT defaults to **5.5** where applicable. Plus extensive polish and fixes across usage observability, Traditional Chinese localization, docs, and proxy / format-conversion robustness.
**Release date**: 2026-05-29
**Stats**: 101 commits | 221 files changed | +27,063 insertions | -3,052 deletions
---
## Highlights
- **Codex Chat Completions routing**: Codex providers can now be served by OpenAI-compatible Chat Completions upstreams. CC Switch converts Codex Responses requests into Chat Completions, rebuilds JSON and SSE responses back into Responses shape, preserves reasoning / `<think>` / tool-call state, normalizes error envelopes, and probes Chat-format providers correctly in Stream Check.
- **Codex third-party provider state is unified and safer**: third-party Codex providers now share the stable `custom` model-provider bucket, with a one-shot migration for historical JSONL sessions and `state_5.sqlite` threads, plus fixes that preserve OAuth login state, user-selected catalog models, and user-authored provider ids during live reads / switches.
- **Managed CLI tool management**: the About page is now a tool management panel for Claude, Codex, Gemini, OpenCode, OpenClaw, and Hermes, with install / update actions, update-all, conflict diagnostics, source-aware anchored upgrades, WSL handling, and visible "installed but not runnable" states.
- **Provider ecosystem and model matrix refresh**: added APIKEY.FUN, APINebula, AtlasCloud, SudoCode, Xiaomi MiMo Token Plan, and Claude Desktop Official presets; refreshed partner links and default models / pricing across apps; upgraded the default Claude Opus model line to 4.8 and GPT defaults to 5.5 where applicable.
- **Usage and docs polish**: Usage Dashboard updates now react immediately when logs are written, custom usage-script summaries and subagent session-log accounting were fixed, Traditional Chinese UI localization landed, and a German README plus expanded Claude Desktop / Codex Chat / tool-management manuals were added.
- **Proxy and conversion hardening**: fixed Codex Chat reasoning / cache / usage edge cases, DeepSeek Anthropic tool-thinking history, Claude-compatible empty `tool_calls` streams, managed-account takeover auth, MiMo reasoning output, Gemini Native tool-call replay, and several panic-prone proxy paths.
---
## Added
### Codex Chat Completions Routing
Codex providers can now be served by upstreams that only speak the OpenAI Chat Completions API. CC Switch's local proxy converts Codex's outgoing Responses requests into Chat Completions and rebuilds the Chat response (both JSON and SSE) back into Responses shape, preserving `reasoning_content`, inline `<think>` blocks, streamed reasoning summaries, tool calls, and `previous_response_id` follow-ups. A bounded Codex Chat history cache restores tool calls before their tool outputs.
> 💡 Special thanks to [@EldenPdx](https://github.com/EldenPdx) for PR [#2804](https://github.com/farion1231/cc-switch/pull/2804): this feature's Chat ↔ Responses format conversion references the implementation in his PR.
### 22 Codex Third-Party Provider Presets with Chat Routing
Enabled Chat Completions routing with explicit model catalogs for major Chinese/Asian providers — DeepSeek, Zhipu GLM (+ en), Kimi, MiniMax (+ en), StepFun (+ en), Baidu Qianfan Coding Plan, Bailian, ModelScope, Longcat, BaiLing, Xiaomi MiMo (+ Token Plan), Volcengine Agentplan, BytePlus, DouBao Seed, SiliconFlow (+ en), Novita AI, and Nvidia. Each preset declares its context window so the UI can size the model-mapping rows.
### Codex Model Mapping Table
Codex provider forms now expose a model catalog (model + display name + context window per row) that is the single source of truth for the upstream model list, projected to `~/.codex/cc-switch-model-catalog.json`.
### Codex Chat Providers in Stream Check
Stream Check now probes Chat-format Codex providers against `/chat/completions` with a Chat-shaped body instead of `/v1/responses`, and aligns its URL fallback order with the production `CodexAdapter` (origin-only base URLs hit `/v1/<endpoint>` first) so a non-404 error on the bare path no longer flags a working provider as down.
### Codex Chat Reasoning Auto-Detection
When a Codex provider is served through Chat Completions routing, CC Switch now auto-detects the upstream's reasoning interface from its name, base URL, and model — injecting the correct thinking parameter (`thinking:{type}`, `enable_thinking`, `reasoning_split`, top-level `reasoning_effort`, or OpenRouter's native `reasoning:{effort}` object) with no manual setup. Aggregator/hosting platforms (OpenRouter, SiliconFlow) are matched platform-first, since the same model can expose different reasoning controls on different platforms. Providers that only expose a thinking on/off switch (Kimi, GLM, Qwen, MiniMax, MiMo, SiliconFlow) drop the effort _level_ instead of forwarding an unsupported field — so changing Codex's reasoning effort has no effect for them — while providers with real effort tiers (DeepSeek, OpenRouter, and StepFun's `step-3.5-flash-2603` only) pass the level through. OpenRouter specifically uses the native `reasoning:{effort}` object, clamps `max` to `xhigh` (its enum has no `max`), and forwards an explicit `effort:"none"` so reasoning can be turned off.
### Codex Goal Mode and Remote Compaction Controls
Codex config editing now exposes a Goal Mode toggle and a Remote Compaction toggle for third-party providers; new Codex templates default to `disable_response_storage = true` while still allowing explicit goal support.
### Xiaomi MiMo Token Plan Presets
Added Xiaomi MiMo Token Plan presets with specs aligned to the official documentation (#2803, thanks @BlueOcean223).
### Claude Desktop Official Preset
Added a Claude Desktop Official preset that restores the native Claude Desktop login, plus a localized Claude Desktop user guide (en / zh / ja).
### Managed CLI Tool Lifecycle
Added silent install / update commands for managed CLI tools, latest-version checks, per-tool and batch actions, update-all, and diagnostics for multiple installations across PATH, Homebrew, npm, pnpm, bun, volta, fnm, nvm, scoop, WinGet, Windows native paths, and WSL.
### Source-Aware Tool Diagnostics
The Settings / About surface can now diagnose conflicting tool installations, show the concrete install source and version for each path, and generate backend-planned upgrade commands anchored to the actual installation source.
### Real-Time Usage Refresh
The backend now emits `usage-log-recorded` when proxy logs, session-log syncs, or rollups write usage data; Usage Dashboard listens for that event and invalidates its queries immediately instead of waiting for the next polling interval (#3027, thanks @in30mn1a).
### Traditional Chinese Localization
Added `zh-TW` UI localization and a settings language option (#3093, thanks @LaiYueTing).
### German README
Added `README_DE.md` and linked it from the existing README language switchers (#2994, thanks @flitzrrr).
### New Partner Presets
Added APIKEY.FUN, APINebula, AtlasCloud, and SudoCode partner presets across the supported app surfaces, with partner copy, icons, and README entries.
---
## Changed
### Codex Third-Party Providers Unified into a "custom" History Bucket
Codex filters resume history by `model_provider`, so switching between provider-specific ids made past sessions appear to vanish. All third-party providers now normalize to a single stable `custom` bucket (reserved built-in ids like `openai` / `ollama` are preserved), with a one-shot device migration that rewrites historical JSONL sessions and the `state_5.sqlite` threads table and backs up originals under `~/.cc-switch/backups/codex-history-provider-migration-v1/`.
### Codex Provider Form Simplified
Removed the API Format selector from the Codex form (`wire_api` is always `responses`, so the selector misleadingly implied a protocol change); the model mapping table is now the only source of truth with no hidden default entries, and the form notes that a Codex restart is required after catalog changes since `model_catalog_json` is loaded at startup. Only the "Needs Local Routing" toggle remains.
### Codex Local Routing Toggle Hints Rewritten
Reframed the OFF / ON hints as action guidance (when to enable) rather than scenario descriptions, synced across zh / en / ja.
### Codex Live Config Preservation
Live Codex config reads no longer force-rewrite a user's `model_provider` field, and provider-scoped `experimental_bearer_token` handling now preserves OAuth login state when switching between third-party providers.
### Tool Install / Upgrade Strategy
Managed tool installation now prefers official native installers where available, falls back to package managers when appropriate, runs self-update first for compatible tools, anchors upgrades to the detected install source, and locks duplicate batch actions while work is in flight.
### About Page Becomes Tool Management
The About settings page now presents installed / latest versions, install and update actions, conflict diagnostics, WSL shell preferences, and clearer status for broken or unrunnable tools.
### Default Models and Pricing Refreshed
Upgraded the default Claude Opus model to 4.8, moved GPT-based presets and templates to GPT-5.5 where applicable, refreshed pricing seeds, aligned Claude Desktop model mapping with Claude Code's three-role tiers, and renamed the OpenCode Go preset to drop a stale model suffix.
### Partner Links Refreshed
Updated ShengSuanYun referral links, Atlas Cloud UTM links, and partner copy across README locales and provider metadata.
### Homebrew Official Cask Installation
Installation simplified to `brew install --cask cc-switch` now that CC Switch is in the official Homebrew repository; the personal-tap requirement was removed from all READMEs.
### Shared Frontend Utilities
Replaced JSON stringify / parse deep-copy patterns with a shared `deepClone` helper and extracted a shared `useTauriEvent` hook (#3140, thanks @ChongBiaoZhang).
---
## Fixed
### Codex Chat Error Responses Converted to Responses Envelope
The Codex Chat-to-Responses bridge previously passed upstream error bodies through untouched, leaving Codex clients unable to recognize MiniMax `base_resp`, raw OpenAI Chat errors, or plain-text / HTML error pages. Errors are now regularized into the standard `{error: {message, type, code, param}}` envelope with the original HTTP status preserved; non-JSON bodies are wrapped and truncated to 1KB at a UTF-8 char boundary. Also fixed a pre-existing append-vs-insert bug that emitted a duplicate `Content-Type` header on rewritten JSON bodies.
### Codex Mid-Stream System Messages Collapsed
MiniMax's OpenAI-compatible endpoint strict-rejects any non-leading `system` message (error 2013). All `system` fragments are now collapsed into a single leading message (joined in original order), losslessly for permissive backends too.
### Codex Model Catalog Wiped After Restart
Editing the active Codex provider triggered a live read that omitted `modelCatalog`, so a subsequent save silently destroyed user-configured model mappings. Live reads now reverse-parse the on-disk catalog projection to round-trip the same shape the save path writes.
### Codex Model Catalog Infinite Render Loop
Broke a bidirectional sync cycle between the catalog table and its parent state that caused severe UI jittering when adding or editing entries.
### Codex Chat Preserves User-Selected Catalog Model
A model the client selects from the catalog (e.g. via `/model`) is no longer overwritten by `config.toml`'s default model.
### Codex Chat Reasoning and Cache Stability
Restored a unique call-id fallback when Codex omits or rewrites `previous_response_id`, stopped deriving cache identity from `previous_response_id`, and canonicalized parseable JSON string payloads in tool conversions for stable prefix-cache reuse.
### Codex Chat Streaming Usage Recovered
The Responses-to-Chat conversion now injects `stream_options.include_usage` (merging into any client-provided `stream_options`) when a request is streaming, so OpenAI-compatible upstreams like Kimi and MiniMax emit the trailing usage chunk again. Previously their streamed token / cost / cache stats were recorded as zero on the Codex Chat path.
### Codex Chat Tool-Call Reasoning Backfill
Thinking models like Kimi/Moonshot and DeepSeek reject an assistant message that carries `tool_calls` without a non-empty `reasoning_content`. When cross-turn history recovery misses (proxy restart, ambiguous `call_id`, or a turn with no upstream reasoning), a placeholder `reasoning_content` is now backfilled in a final pass — genuine trailing reasoning still attaches first — so the request no longer fails with `reasoning_content is missing in assistant tool call message`.
### Managed-Account Claude Takeover Auth
Managed-account providers (GitHub Copilot / Codex OAuth) now drop token env keys and write only the `ANTHROPIC_API_KEY` placeholder when taking over Claude Live config, with an outbound guard that refuses to send the `PROXY_MANAGED` placeholder upstream.
### Claude Desktop Profile Sync During Takeover
Claude Desktop profile data is now synced during proxy takeover, model routes align with the Claude Code three-role tiers, and the Cowork egress profile has been corrected (#3157, #3172, thanks @MelorTang, @JGSphaela).
### Managed-Account Takeover Model Fields
Local Routing now sources takeover model fields from the target provider on managed accounts instead of carrying stale model values.
### DeepSeek Anthropic Tool Thinking History
Normalized DeepSeek Anthropic-compatible tool-thinking history so later turns can replay reasoning / tool-call context without malformed messages (#3203, thanks @Q3yp).
### Claude-Compatible Empty Tool Calls in Streams
Fixed a Claude-compatible streaming edge case where an empty `tool_calls` array reset block state and broke streamed responses (#2915, thanks @zhizhuowq).
### MiMo Reasoning for Claude Code Proxy
Added MiMo `reasoning_content` support on the Claude Code proxy path (#2990, thanks @zhangyapu1).
### Gemini Native Tool-Call Robustness
Fixed `functionResponse.name` resolution (422) and `thought_signature` replay (400) for synthesized tool-call IDs in long multi-turn sessions (#2814, thanks @Tiancrimson).
### Session Log Subagent Token Accounting
`collect_jsonl_files()` now scans subagent JSONL logs that were previously missed, so subagent token usage is counted in session cost (session-log mode only) (#2821, thanks @LaoYueHanNi).
### Usage Dashboard / Sync Stability
Fixed a Codex usage-sync panic on non-ASCII model names, custom usage-script summaries, and missing real-time refresh after usage rollups (#3027, #3129, thanks @in30mn1a, @hanhan3344).
### ZhiPu Coding-Plan Quota Tier Ordering
When the 5-hour bucket is at 0% utilization, ZhiPu's API omits `nextResetTime`; the old `i64::MAX` sentinel sorted those entries last, letting the weekly bucket incorrectly claim the five-hour slot. Tiers now sort so a missing `nextResetTime` maps to the five-hour bucket, so tray and usage quota display stays correct for ZhiPu coding plans.
### Skills Install by Key
Installing from skills.sh search results now uses the unique key instead of the directory name, so skills that share a directory name install the correct one (#2784, thanks @zhaomoran); also fixed a skill sync copy fallback (#2791, thanks @rogerdigital).
### Usage Price Input Precision
Reduced the price input step to 0.0001 so sub-cent costs like DeepSeek cache reads can be entered (#2793, closes #2503, thanks @rogerdigital).
### Ghostty Clean Window Launch
Ghostty now opens a single clean window instead of cloning existing tabs, and other terminals open a new window via `open -na` (#2801, closes #2798, thanks @luw2007).
### Tool Version and Update Reliability
Version probing no longer masks unrunnable installs, prerelease tools are handled correctly in version checks, batch updates run per tool, install / update buttons stay locked during preflight, anchored upgrade branches enforce absolute paths, and WSL installer paths use native Unix installers when needed.
### Codex mise Detection
Fixed Codex mise environment detection (#2822, thanks @iambinlin).
### Codex Archived Sessions
Codex archived sessions are now included in session discovery (#2861, thanks @nanmen2).
### Codex Chat Empty Tool Arguments
Empty tool-call argument payloads are coerced to `{}` during Codex Chat conversion so upstreams and clients receive valid JSON.
### Claude Provider Deeplink Imports
Importing Claude providers through deeplinks now preserves custom environment fields (#2928, thanks @doutuifei).
### OMO Recommended Models
Synced OMO recommended models with upstream defaults and improved Fill Recommended feedback.
### ShengSuanYun Model IDs Prefixed for Routing
ShengSuanYun (胜算云) presets now carry the vendor prefixes the upstream gateway requires — `anthropic/…`, `google/…`, and `openai/…` (e.g. `anthropic/claude-sonnet-4.6`, `google/gemini-3.1-pro-preview`) — across the Claude Code, Claude Desktop, Codex, Gemini, OpenCode, and OpenClaw presets, including the Claude Code routing env (`ANTHROPIC_MODEL` / `ANTHROPIC_DEFAULT_{HAIKU,SONNET,OPUS}_MODEL`), so they resolve to valid upstream models instead of failing to route.
### ClaudeAPI Model Test Re-Enabled
Reclassified the ClaudeAPI preset (Claude Code and Claude Desktop) from `third_party` to `aggregator` so its model test button is no longer disabled by the third-party Claude gate; the partner star is unaffected since it is driven by `isPartner`, not category.
### About Version Check
Version checks now handle prerelease tool versions without misclassifying update state.
### App Switcher Text Clipping
Removed a fixed width constraint that clipped app-switcher text (#3161, thanks @loocor).
### useEffect Race Condition
Added an active-flag pattern to App.tsx effects to prevent listener leaks on unmount, and guarded against storing `undefined` language in localStorage (#2827, thanks @Zylo206).
---
## Removed
### LionCC Sponsor and Presets
Removed the LionCC sponsor entry and LionCCAPI presets across READMEs, provider configs, and locales (icon asset retained).
### AICoding Partner Entry
Removed the AICoding partner from README sponsor listings, provider presets, and i18n metadata.
### Kimi For Coding Codex Preset
Removed the Kimi For Coding preset from the Codex preset catalog.
### CLI Uninstall Command Hints
Dropped generated CLI uninstall command hints from the tool-management UI while keeping conflict diagnostics visible.
---
## Docs
### Codex Chat Provider Support
Documented Chat Completions routing, provider support, reasoning auto-detection, and Local Routing guidance in the changelog and user manual.
### Settings Manual Refresh
Updated settings documentation for the new managed tool lifecycle and Hermes installer behavior.
### Claude Desktop Guide
Added localized Claude Desktop guide pages and screenshots for provider setup, import, model mapping, and Local Routing context.
### Installation Docs
Updated installation docs and READMEs to recommend the official Homebrew cask and refreshed the v3.15.0 release-note imposter-site warning wording across locales.
---
## ⚠️ Upgrade Notes
### One-Shot Codex History Migration
The first launch after upgrading runs a one-shot migration of Codex history: third-party providers are normalized into the `custom` bucket and historical JSONL sessions plus the `state_5.sqlite` threads table are rewritten. Originals are backed up under `~/.cc-switch/backups/codex-history-provider-migration-v1/`. This step fixes the "past sessions vanish after switching provider" problem — history resumes correctly after the migration.
### Codex Catalog Changes Require a Restart
Codex loads `model_catalog_json` at startup, so after editing the model mapping table in CC Switch you must **restart Codex** for the new catalog to take effect.
### Reasoning Effort May Have No Effect for Chat-Routing Providers
For providers that only expose a thinking on/off switch (Kimi, GLM, Qwen, MiniMax, MiMo, SiliconFlow), changing the reasoning effort in Codex (`model_reasoning_effort`: low / medium / high) **has no effect** — CC Switch will not forward an unsupported effort field to them. Only providers with real effort tiers (DeepSeek, OpenRouter, and StepFun's `step-3.5-flash-2603` only) actually honor the level.
### Default Models Upgraded to Opus 4.8 / GPT-5.5
The default Claude Opus model line is upgraded to 4.8 and GPT defaults to 5.5 where applicable. If you rely on a pinned older default model, check the model fields of the relevant presets / templates after upgrading.
---
## ⚠️ Risk Notice
This release inherits the risk notices originally introduced in v3.12.3 / v3.13.0 / v3.15.0 for reverse-proxy-style features.
**GitHub Copilot Reverse Proxy**: Using Copilot's reverse-proxy path may violate GitHub / Microsoft's terms of service. See the [v3.12.3 release notes](v3.12.3-en.md#-risk-notice) for details.
**Codex OAuth Reverse Proxy**: Using the Codex OAuth reverse proxy with a ChatGPT subscription may violate OpenAI's terms of service. See the [v3.13.0 release notes](v3.13.0-en.md#-risk-notice) for details.
**Codex Third-Party Provider Chat Routing**: Converting and forwarding Codex requests through CC Switch's local proxy to a third-party provider exposes those requests to that provider's billing, compliance, and data-retention policies — read the target provider's terms of service before using.
**Claude Desktop Third-Party Provider Switching via Proxy Gateway**: Routing Claude Desktop traffic through CC Switch's in-app proxy gateway to a third-party provider exposes those requests to that provider's billing, compliance, and data-retention policies — read the target provider's terms of service before using.
By enabling these features, users **accept all associated risks**. CC Switch is not responsible for any account restrictions, warnings, or service suspensions that result from using these features.
---
## Download & Installation
Visit [Releases](https://github.com/farion1231/cc-switch/releases/latest) to download the appropriate version.
### System Requirements
| OS | Minimum Version | Architecture |
| ------- | ---------------------------- | ----------------------------------- |
| Windows | Windows 10 or later | x64 |
| macOS | macOS 12 (Monterey) or later | Intel (x64) / Apple Silicon (arm64) |
| Linux | See table below | x64 / ARM64 |
### Windows
| File | Description |
| ---------------------------------------- | ----------------------------------------------------- |
| `CC-Switch-v3.16.0-Windows.msi` | **Recommended** - MSI installer, supports auto-update |
| `CC-Switch-v3.16.0-Windows-Portable.zip` | Portable, extract and run, no registry writes |
### macOS
| File | Description |
| -------------------------------- | ------------------------------------------------------- |
| `CC-Switch-v3.16.0-macOS.dmg` | **Recommended** - DMG installer, drag into Applications |
| `CC-Switch-v3.16.0-macOS.zip` | Extract and drag into Applications, Universal Binary |
| `CC-Switch-v3.16.0-macOS.tar.gz` | For Homebrew installation and auto-update |
> macOS builds are Apple code-signed and notarized — install directly.
### Homebrew (macOS)
> 🎉 CC Switch is now available in the official Homebrew cask repository — no need to add a custom tap!
```bash
brew install --cask cc-switch
```
Update:
```bash
brew upgrade --cask cc-switch
```
### Linux
> Linux artifacts are published for both **x86_64** and **ARM64** (`aarch64`). The architecture is included in the asset filename — pick the one matching your machine's `uname -m` output:
>
> - `CC-Switch-v3.16.0-Linux-x86_64.AppImage` / `.deb` / `.rpm`
> - `CC-Switch-v3.16.0-Linux-arm64.AppImage` / `.deb` / `.rpm`
| Distribution | Recommended | Installation |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| Ubuntu / Debian / Linux Mint / Pop!\_OS | `.deb` | `sudo dpkg -i CC-Switch-*.deb` or `sudo apt install ./CC-Switch-*.deb` |
| Fedora / RHEL / CentOS / Rocky Linux | `.rpm` | `sudo rpm -i CC-Switch-*.rpm` or `sudo dnf install ./CC-Switch-*.rpm` |
| openSUSE | `.rpm` | `sudo zypper install ./CC-Switch-*.rpm` |
| Arch Linux / Manjaro | `.AppImage` | Add execute permission and run, or use AUR |
| Other distros / not sure | `.AppImage` | `chmod +x CC-Switch-*.AppImage && ./CC-Switch-*.AppImage` |
+433
View File
@@ -0,0 +1,433 @@
# CC Switch v3.16.0
> Codex 向けに Chat Completions → Responses フォーマット変換を追加(Codex で DeepSeek・Kimi・GLM が使えるようになりました!)、Codex プロバイダーの身元と履歴を統一、アプリ管理パネルの全方位強化、パートナープリセットの拡張、デフォルトモデル / 価格マトリクスを GPT-5.5 と Claude Opus 4.8 にアップグレード、プロキシ / フォーマット変換のロバスト性強化
**[English →](v3.16.0-en.md) | [中文 →](v3.16.0-zh.md)**
---
> [!WARNING]
>
> ## 唯一の公式チャネル(必ずお読みください)
>
> CC Switch は**完全に無料・オープンソース**のデスクトップアプリで、**ユーザーから料金を徴収することはありません**。最近、CC Switch の名を騙って課金を要求したり認証情報を収集する偽サイトが複数確認されており、一部のユーザーには既に金銭的被害が発生しています。本ソフトウェアは下記の公式チャネルからのみ入手してください:
>
> | チャネル | 唯一の公式 |
> | ------------ | ------------------------------------------------------------------------------ |
> | 公式サイト | **[ccswitch.io](https://ccswitch.io)** |
> | ソースコード | **[github.com/farion1231/cc-switch](https://github.com/farion1231/cc-switch)** |
> | ダウンロード | **[GitHub Releases](https://github.com/farion1231/cc-switch/releases)** |
> | 作者 | **[@farion1231](https://github.com/farion1231)** |
> | 偽サイト通報 | **[GitHub Issues](https://github.com/farion1231/cc-switch/issues)** |
>
> **料金請求・チャージ・認証情報の提供を求める「CC Switch」サイトやクライアントはすべて偽物です。** 支払いを誘導された場合は、直ちに取引を中止し、偽サイトを速やかに削除できるよう GitHub Issues からご報告ください。
---
## 利用ガイド
本リリースの主役となる 2 つの機能は、**Codex サードパーティプロバイダーの Chat Completions ルーティング**と**アプリ内蔵の受託 CLI ツール管理**です。OpenAI Chat プロトコルにしか対応していないプロバイダー(DeepSeek、Kimi、MiniMax など)を Codex で直接使いたい場合、またはアプリ内で CLI ツールの一括インストール / アップグレードをしたい場合は、まずこの 2 つをご覧ください:
- **[Codex プロバイダーの追加: Chat Completions ルーティングとモデルマッピング](../user-manual/ja/2-providers/2.1-add.md)** —— 「ローカルルーティングが必要」トグル、モデルマッピングテーブル、思考能力(reasoning)の自動判別までの一連の流れを説明しています。
- **[設定 → バージョン情報: 受託 CLI ツール管理](../user-manual/ja/1-getting-started/1.5-settings.md)** —— バージョン検出、個別アップグレード / 全体アップグレード、競合診断、インストール元にアンカーされたアップグレードコマンドを説明しています。
---
## 概要
CC Switch v3.16.0 の v3.15.0 以降の開発のコアは、**サードパーティ Codex プロバイダーを Chat Completions ルーティングによって一等市民へ昇格させること**です。Codex はネイティブには OpenAI Responses API と GPT 系モデルしか認識しませんが、本リリースでは CC Switch のローカルプロキシが Codex の送出する Responses リクエストを Chat Completions に変換し、JSON と SSE のストリーミングレスポンスを Responses 形態へ再構築します。その道中で `reasoning_content` / インライン `<think>` ブロック / ストリーミング推論サマリー / ツール呼び出し / `previous_response_id` の継続を保持し、エラーエンベロープを正規化し、Stream Check で Chat 形式プロバイダーを正しくプローブします。あわせて明示的なモデルカタログ付きの 22 個の Chat ルーティングプリセット(DeepSeek、Zhipu GLM、Kimi、MiniMax、StepFun、Baidu Qianfan、Bailian、ModelScope、Longcat、BaiLing、Xiaomi MiMo、Volcengine Agentplan、BytePlus、DouBao Seed、SiliconFlow、Novita AI、Nvidia など)を出荷します。
Codex サードパーティプロバイダーの**身元と履歴**は、本リリースで統一・堅牢化されました: すべてのサードパーティプロバイダーが安定した `custom` model-provider バケットに正規化され、過去の JSONL セッションと `state_5.sqlite` のスレッドテーブルを書き換える一回限りのデバイスマイグレーション(オリジナルは `~/.cc-switch/backups/` 配下にバックアップ)を提供することで、プロバイダー id の変更によって過去のセッションが消えたように見える問題を防ぎます。あわせて、live 読み取り / 切り替えの際に OAuth ログイン状態、ユーザーが選択したカタログモデル、ユーザー定義のプロバイダー id が上書きされる問題も修正しました。
本リリースではさらに、**アプリ内蔵の受託 CLI ツールライフサイクル**を追加しました: 設定の「バージョン情報」タブが Claude / Codex / Gemini / OpenCode / OpenClaw / Hermes のツール管理パネルに昇格し、サイレントインストール / 更新、全体アップグレード、競合診断、インストール元を考慮したアンカー型アップグレード、WSL の取り扱い、「インストール済みだが実行できない」状態の可視化に対応します。
プロバイダーエコシステムとモデルマトリクスも並行してリフレッシュされました: APIKEY.FUN、APINebula、AtlasCloud、SudoCode、Xiaomi MiMo Token Plan、Claude Desktop 公式プリセットを追加; 各アプリのパートナーリンクとデフォルトモデル / 価格をリフレッシュ; デフォルトの Claude Opus ラインを **4.8** に、該当箇所の GPT デフォルトを **5.5** にアップグレード。さらに、Usage の可観測性、繁体字中国語ローカライズ、ドキュメント、プロキシ / フォーマット変換のロバスト性についても多くの改善と修正を行いました。
**リリース日**: 2026-05-29
**Stats**: 101 commits | 221 files changed | +27,063 insertions | -3,052 deletions
---
## ハイライト
- **Codex Chat Completions ルーティング**: Codex プロバイダーを OpenAI 互換の Chat Completions 上流で提供できるようになりました。CC Switch は Codex の Responses リクエストを Chat Completions に変換し、JSON と SSE レスポンスを Responses 形態へ再構築し、reasoning / `<think>` / ツール呼び出し状態を保持し、エラーエンベロープを正規化し、Stream Check で Chat 形式プロバイダーを正しくプローブします
- **Codex サードパーティプロバイダーの状態を統一しより安全に**: サードパーティ Codex プロバイダーは安定した `custom` model-provider バケットを共有するようになり、過去の JSONL セッションと `state_5.sqlite` スレッドの一回限りのマイグレーションに加え、live 読み取り / 切り替え時に OAuth ログイン状態、ユーザー選択のカタログモデル、ユーザー定義のプロバイダー id を保持する修正を実施
- **受託 CLI ツール管理**: 「バージョン情報」ページが Claude / Codex / Gemini / OpenCode / OpenClaw / Hermes のツール管理パネルに昇格し、インストール / 更新アクション、全体アップグレード、競合診断、インストール元にアンカーしたアップグレード、WSL の取り扱い、「インストール済みだが実行できない」状態の可視化を搭載
- **プロバイダーエコシステムとモデルマトリクスのリフレッシュ**: APIKEY.FUN、APINebula、AtlasCloud、SudoCode、Xiaomi MiMo Token Plan、Claude Desktop 公式プリセットを追加; 各アプリのパートナーリンクとデフォルトモデル / 価格をリフレッシュ; デフォルトの Claude Opus を 4.8 に、該当箇所の GPT デフォルトを 5.5 にアップグレード
- **Usage とドキュメントの磨き込み**: Usage ダッシュボードがログ書き込み時に即座に反応して更新、カスタム usage スクリプトのサマリーと subagent セッションログの計上を修正、繁体字中国語 UI ローカライズが着地、ドイツ語 README と拡充された Claude Desktop / Codex Chat / ツール管理マニュアルを追加
- **プロキシと変換のハードニング**: Codex Chat の推論 / キャッシュ / usage のエッジケース、DeepSeek Anthropic ツール思考履歴、Claude 互換の空 `tool_calls` ストリーム、受託アカウントのテイクオーバー認証、MiMo 推論出力、Gemini Native ツール呼び出しの再生、いくつかのパニックしやすいプロキシパスを修正
---
## 追加機能
### Codex Chat Completions ルーティング
Codex プロバイダーを、OpenAI Chat Completions API しか話せない上流で提供できるようになりました。CC Switch のローカルプロキシは Codex の送出する Responses リクエストを Chat Completions に変換し、Chat レスポンス(JSON と SSE の両方)を Responses 形態へ再構築します。その際、`reasoning_content`、インライン `<think>` ブロック、ストリーミング推論サマリー、ツール呼び出し、`previous_response_id` の継続を保持します。有界の Codex Chat 履歴キャッシュが、ツール出力の前に対応するツール呼び出しを復元します。
> 💡 [@EldenPdx](https://github.com/EldenPdx) の PR [#2804](https://github.com/farion1231/cc-switch/pull/2804) に特別な感謝を: 本機能の Chat ↔ Responses フォーマット変換の実装は、彼の PR の実装を参考にしています。
### Chat ルーティング対応の 22 個の Codex サードパーティプロバイダープリセット
主要な中国 / アジア系プロバイダー向けに、明示的なモデルカタログ付きで Chat Completions ルーティングを有効化しました —— DeepSeek、Zhipu GLM+ 英語版)、Kimi、MiniMax+ 英語版)、StepFun+ 英語版)、Baidu Qianfan Coding Plan、Bailian、ModelScope、Longcat、BaiLing、Xiaomi MiMo+ Token Plan)、Volcengine Agentplan、BytePlus、DouBao Seed、SiliconFlow+ 英語版)、Novita AI、Nvidia。各プリセットは自身のコンテキストウィンドウを宣言するため、UI がモデルマッピング行のサイズを決定できます。
### Codex モデルマッピングテーブル
Codex プロバイダーフォームがモデルカタログ(行ごとに モデル + 表示名 + コンテキストウィンドウ)を公開するようになりました。これは上流モデルリストの唯一の信頼できる情報源であり、`~/.codex/cc-switch-model-catalog.json` に投影されます。
### Stream Check の Codex Chat プロバイダー対応
Stream Check は Chat 形式の Codex プロバイダーに対して、`/v1/responses` ではなく Chat 形態のボディで `/chat/completions` をプローブするようになりました。また URL のフォールバック順序を本番の `CodexAdapter` と揃え(origin のみの base URL はまず `/v1/<endpoint>` を叩く)、裸のパスでの 404 以外のエラーが、正常に動作しているプロバイダーをダウンと誤判定しなくなりました。
### Codex Chat 思考能力(Reasoning)の自動判別
Codex プロバイダーが Chat Completions ルーティング経由で提供される場合、CC Switch は上流の推論インターフェースを名前、base URL、モデル名から**自動判別**し、正しい思考パラメータ(`thinking:{type}``enable_thinking``reasoning_split`、トップレベルの `reasoning_effort`、または OpenRouter のネイティブ `reasoning:{effort}` オブジェクト)を手動設定なしで注入します。アグリゲーター / ホスティングプラットフォーム(OpenRouter、SiliconFlow)は**プラットフォーム優先**でマッチします。同じモデルでもプラットフォームによって異なる推論コントロールを公開する場合があるためです。思考の オン / オフ スイッチしか公開しないプロバイダー(Kimi、GLM、Qwen、MiniMax、MiMo、SiliconFlow)は、未対応のフィールドを転送する代わりに effort の*レベル*を破棄します —— そのため Codex の推論 effort を変更してもこれらには効果がありません —— 一方、本物の effort 階層を持つプロバイダー(DeepSeek、OpenRouter、および StepFun の `step-3.5-flash-2603` のみ)はレベルを透過させます。OpenRouter は特にネイティブ `reasoning:{effort}` オブジェクトを使用し、`max``xhigh` にクランプし(その enum に `max` はない)、推論をオフにできるよう明示的に `effort:"none"` を転送します。
### Codex Goal Mode とリモートコンパクション制御
Codex の設定編集で、サードパーティプロバイダー向けに Goal Mode トグルとリモートコンパクション(Remote Compaction)トグルを公開するようになりました; 新規 Codex テンプレートはデフォルトで `disable_response_storage = true` としつつ、明示的な goal サポートも許可します。
### Xiaomi MiMo Token Plan プリセット
公式ドキュメントに準拠した仕様で Xiaomi MiMo Token Plan プリセットを追加しました (#2803, 感謝 @BlueOcean223)。
### Claude Desktop 公式プリセット
ネイティブの Claude Desktop ログインを復元する Claude Desktop 公式プリセットと、ローカライズされた Claude Desktop ユーザーガイド(en / zh / ja)を追加しました。
### 受託 CLI ツールライフサイクル
受託 CLI ツール向けに、サイレントインストール / 更新コマンド、最新バージョンチェック、ツール単位およびバッチアクション、全体アップグレード、そして PATH、Homebrew、npm、pnpm、bun、volta、fnm、nvm、scoop、WinGet、Windows ネイティブパス、WSL をまたいだ複数インストールの診断を追加しました。
### インストール元を考慮したツール診断
設定 / バージョン情報の画面で、競合するツールインストールを診断し、各パスの具体的なインストール元とバージョンを表示し、実際のインストール元にアンカーされたバックエンド計画のアップグレードコマンドを生成できるようになりました。
### リアルタイム Usage 更新
バックエンドは、プロキシログ、セッションログ同期、ロールアップが usage データを書き込んだ際に `usage-log-recorded` を発行するようになりました; Usage ダッシュボードはそのイベントを購読し、次のポーリング間隔を待たずに即座にクエリを無効化します (#3027, 感謝 @in30mn1a)。
### 繁体字中国語ローカライズ
`zh-TW` の UI ローカライズと設定の言語オプションを追加しました (#3093, 感謝 @LaiYueTing)。
### ドイツ語 README
`README_DE.md` を追加し、既存の README 言語スイッチャーからリンクしました (#2994, 感謝 @flitzrrr)。
### 新しいパートナープリセット
対応する各アプリ面に APIKEY.FUN、APINebula、AtlasCloud、SudoCode のパートナープリセットを、パートナー文面、アイコン、README エントリとともに追加しました。
---
## 変更
### Codex サードパーティプロバイダーを "custom" 履歴バケットに統一
Codex は復元履歴を `model_provider` でフィルタリングするため、プロバイダー固有の id 間を切り替えると過去のセッションが消えたように見えていました。すべてのサードパーティプロバイダーは単一の安定した `custom` バケットに正規化されるようになり(`openai` / `ollama` のような予約済みの組み込み id は保持)、過去の JSONL セッションと `state_5.sqlite` のスレッドテーブルを書き換え、オリジナルを `~/.cc-switch/backups/codex-history-provider-migration-v1/` 配下にバックアップする一回限りのデバイスマイグレーションを伴います。
### Codex プロバイダーフォームの簡素化
Codex フォームから API Format セレクターを削除しました(`wire_api` は常に `responses` であり、セレクターはプロトコルを変更できるかのように誤解を招くため); モデルマッピングテーブルが唯一の信頼できる情報源となり、隠れたデフォルトエントリはなくなりました。`model_catalog_json` は起動時に読み込まれるため、カタログ変更後は Codex の再起動が必要である旨をフォームに明記しています。残るのは「ローカルルーティングが必要」トグルのみです。
### Codex ローカルルーティングトグルのヒント書き直し
OFF / ON のヒントを、シナリオの説明ではなくアクションのガイダンス(いつ有効化すべきか)として再構成し、zh / en / ja で同期しました。
### Codex Live 設定の保持
Codex の live 設定読み取りがユーザーの `model_provider` フィールドを強制的に書き換えなくなり、プロバイダースコープの `experimental_bearer_token` 処理がサードパーティプロバイダー間の切り替え時に OAuth ログイン状態を保持するようになりました。
### ツールのインストール / アップグレード戦略
受託ツールのインストールは、可能な場合は公式のネイティブインストーラーを優先し、適切な場合はパッケージマネージャーにフォールバックし、互換性のあるツールではまず self-update を実行し、アップグレードを検出されたインストール元にアンカーし、作業中は重複するバッチアクションをロックするようになりました。
### 「バージョン情報」ページがツール管理に
「バージョン情報」設定ページが、インストール済み / 最新バージョン、インストールおよび更新アクション、競合診断、WSL シェル設定、壊れている / 実行できないツールのより明確なステータスを表示するようになりました。
### デフォルトモデルと価格のリフレッシュ
デフォルトの Claude Opus モデルを 4.8 にアップグレードし、該当箇所の GPT ベースのプリセットとテンプレートを GPT-5.5 に移行し、価格シードをリフレッシュし、Claude Desktop のモデルマッピングを Claude Code の三ロール階層に揃え、OpenCode の Go プリセットを古いモデルサフィックスを落とすようリネームしました。
### パートナーリンクのリフレッシュ
ShengSuanYun の紹介リンク、Atlas Cloud の UTM リンク、各 README ロケールおよびプロバイダーメタデータのパートナー文面を更新しました。
### Homebrew 公式 Cask インストール
CC Switch が公式 Homebrew リポジトリに収録されたため、インストールを `brew install --cask cc-switch` に簡素化しました; 個人 tap の要件はすべての README から削除しました。
### 共有フロントエンドユーティリティ
JSON stringify / parse によるディープコピーのパターンを共有の `deepClone` ヘルパーに置き換え、共有の `useTauriEvent` フックを抽出しました (#3140, 感謝 @ChongBiaoZhang)。
---
## 修正
### Codex Chat エラーレスポンスを Responses エンベロープに変換
Codex Chat → Responses ブリッジは以前、上流のエラーボディをそのまま透過させていたため、Codex クライアントが MiniMax の `base_resp`、生の OpenAI Chat エラー、プレーンテキスト / HTML のエラーページを認識できませんでした。エラーは標準の `{error: {message, type, code, param}}` エンベロープに整形され、元の HTTP ステータスが保持されるようになりました; 非 JSON ボディはラップされ、UTF-8 文字境界で 1KB に切り詰められます。また、書き換え後の JSON ボディに重複する `Content-Type` ヘッダーを出力していた既存の append-vs-insert バグも修正しました。
### Codex のストリーム中間の system メッセージを折りたたみ
MiniMax の OpenAI 互換エンドポイントは、先頭以外の `system` メッセージを厳格に拒否します(エラー 2013)。すべての `system` 断片は単一の先頭メッセージに折りたたまれるようになりました(元の順序で結合)。寛容なバックエンドに対しても損失なく行われます。
### 再起動後に Codex モデルカタログが消える問題
アクティブな Codex プロバイダーを編集すると `modelCatalog` を省略した live 読み取りがトリガーされ、その後の保存がユーザー設定のモデルマッピングを無言で破壊していました。live 読み取りはディスク上のカタログ投影を逆解析し、保存パスが書き込むのと同じ形態をラウンドトリップするようになりました。
### Codex モデルカタログの無限レンダリングループ
カタログテーブルとその親 state の間の双方向同期サイクルを断ち切りました。これはエントリの追加や編集時に深刻な UI のジッターを引き起こしていました。
### Codex Chat がユーザー選択のカタログモデルを保持
クライアントがカタログから選択したモデル(例: `/model` 経由)が、`config.toml` のデフォルトモデルによって上書きされなくなりました。
### Codex Chat の推論とキャッシュの安定性
Codex が `previous_response_id` を省略または書き換える際の一意な call-id フォールバックを復元し、`previous_response_id` からキャッシュの同一性を導出するのをやめ、ツール変換でパース可能な JSON 文字列ペイロードを正規化して安定したプレフィックスキャッシュ再利用を実現しました。
### Codex Chat のストリーミング usage を復旧
Responses → Chat 変換が、リクエストがストリーミングの場合に `stream_options.include_usage` を注入する(クライアント提供の `stream_options` にマージ)ようになり、Kimi や MiniMax のような OpenAI 互換上流が末尾の usage チャンクを再び発行するようになりました。以前は、これらのストリーミングのトークン / コスト / キャッシュ統計が Codex Chat パスでゼロとして記録されていました。
### Codex Chat ツール呼び出しの推論バックフィル
Kimi/Moonshot や DeepSeek のような思考モデルは、空でない `reasoning_content` を伴わない `tool_calls` を持つ assistant メッセージを拒否します。ターンをまたいだ履歴復元が失敗した場合(プロキシ再起動、曖昧な `call_id`、または上流の推論がないターン)、最終パスでプレースホルダーの `reasoning_content` をバックフィルするようになりました —— 本物の末尾推論が先に付加されます —— そのためリクエストが `reasoning_content is missing in assistant tool call message` で失敗しなくなりました。
### 受託アカウントの Claude テイクオーバー認証
受託アカウントのプロバイダー(GitHub Copilot / Codex OAuth)は、Claude Live 設定をテイクオーバーする際にトークン環境変数キーを破棄し、`ANTHROPIC_API_KEY` プレースホルダーのみを書き込むようになりました。さらに、`PROXY_MANAGED` プレースホルダーを上流に送信するのを拒否するアウトバウンドガードを備えます。
### テイクオーバー中の Claude Desktop プロファイル同期
プロキシテイクオーバー中に Claude Desktop プロファイルデータが同期されるようになり、モデルルートが Claude Code の三ロール階層に揃い、Cowork egress プロファイルが修正されました (#3157, #3172, 感謝 @MelorTang, @JGSphaela)。
### 受託アカウントのテイクオーバーモデルフィールド
ローカルルーティングは、受託アカウントにおいて、古いモデル値を持ち回るのではなく、ターゲットプロバイダーからテイクオーバーモデルフィールドを取得するようになりました。
### DeepSeek Anthropic ツール思考履歴
DeepSeek Anthropic 互換のツール思考履歴を正規化し、後続のターンが不正なメッセージなしで推論 / ツール呼び出しコンテキストを再生できるようにしました (#3203, 感謝 @Q3yp)。
### Claude 互換のストリーム内の空ツール呼び出し
空の `tool_calls` 配列がブロック状態をリセットしてストリーミングレスポンスを壊す、Claude 互換のストリーミングエッジケースを修正しました (#2915, 感謝 @zhizhuowq)。
### Claude Code プロキシ向けの MiMo 推論
Claude Code プロキシパスで MiMo の `reasoning_content` サポートを追加しました (#2990, 感謝 @zhangyapu1)。
### Gemini Native ツール呼び出しのロバスト性
長いマルチターンセッションにおける合成ツール呼び出し ID の `functionResponse.name` 解決(422)と `thought_signature` 再生(400)を修正しました (#2814, 感謝 @Tiancrimson)。
### セッションログの subagent トークン計上
`collect_jsonl_files()` がこれまで見落とされていた subagent の JSONL ログをスキャンするようになり、subagent のトークン使用量がセッションコストに計上されるようになりました(セッションログモードのみ)(#2821, 感謝 @LaoYueHanNi)。
### Usage ダッシュボード / 同期の安定性
非 ASCII モデル名による Codex usage 同期パニック、カスタム usage スクリプトのサマリー、usage ロールアップ後のリアルタイム更新の欠落を修正しました (#3027, #3129, 感謝 @in30mn1a, @hanhan3344)。
### ZhiPu Coding-Plan のクォータ階層の並び順
5 時間バケットの使用率が 0% の場合、ZhiPu の API は `nextResetTime` を省略します; 古い `i64::MAX` センチネルはこれらのエントリを最後にソートしていたため、週次バケットが五時間スロットを誤って占有していました。階層は、`nextResetTime` の欠落が五時間バケットにマップされるようにソートされるようになり、ZhiPu の coding plan でトレイと usage クォータの表示が正しく保たれます。
### スキルを key でインストール
skills.sh の検索結果からインストールする際に、ディレクトリ名ではなく一意の key を使用するようになり、ディレクトリ名を共有するスキルでも正しいものがインストールされます (#2784, 感謝 @zhaomoran); スキル同期のコピーフォールバックも修正しました (#2791, 感謝 @rogerdigital)。
### Usage 価格入力の精度
価格入力のステップを 0.0001 に下げ、DeepSeek のキャッシュ読み取りのような 1 セント未満のコストも入力できるようにしました (#2793, #2503 をクローズ, 感謝 @rogerdigital)。
### Ghostty のクリーンウィンドウ起動
Ghostty は既存タブを複製する代わりに単一のクリーンウィンドウを開くようになり、他のターミナルは `open -na` 経由で新しいウィンドウを開きます (#2801, #2798 をクローズ, 感謝 @luw2007)。
### ツールバージョンと更新の信頼性
バージョンプローブが実行できないインストールを覆い隠さなくなり、プレリリースツールがバージョンチェックで正しく扱われ、バッチ更新がツール単位で実行され、インストール / 更新ボタンがプリフライト中ロックされ続け、アンカー型アップグレードブランチが絶対パスを強制し、WSL のインストーラーパスが必要に応じてネイティブ Unix インストーラーを使用するようになりました。
### Codex の mise 検出
Codex の mise 環境検出を修正しました (#2822, 感謝 @iambinlin)。
### Codex のアーカイブ済みセッション
Codex のアーカイブ済みセッションがセッション検出に含まれるようになりました (#2861, 感謝 @nanmen2)。
### Codex Chat の空ツール引数
空のツール呼び出し引数ペイロードが Codex Chat 変換時に `{}` に強制変換され、上流とクライアントが有効な JSON を受け取るようになりました。
### Claude プロバイダーの deeplink インポート
deeplink 経由で Claude プロバイダーをインポートする際に、カスタム環境フィールドが保持されるようになりました (#2928, 感謝 @doutuifei)。
### OMO 推奨モデル
OMO の推奨モデルを上流のデフォルトと同期し、「推奨を入力」のフィードバックを改善しました。
### ShengSuanYun のモデル ID にルーティング用プレフィックスを付与
ShengSuanYun(胜算云)プリセットが、上流ゲートウェイが要求するベンダープレフィックス —— `anthropic/…``google/…``openai/…`(例: `anthropic/claude-sonnet-4.6``google/gemini-3.1-pro-preview`)—— を、Claude Code、Claude Desktop、Codex、Gemini、OpenCode、OpenClaw の各プリセットにわたって持つようになりました。Claude Code のルーティング環境変数(`ANTHROPIC_MODEL` / `ANTHROPIC_DEFAULT_{HAIKU,SONNET,OPUS}_MODEL`)も含まれるため、ルーティングに失敗するのではなく有効な上流モデルに解決されます。
### ClaudeAPI モデルテストの再有効化
ClaudeAPI プリセット(Claude Code と Claude Desktop)を `third_party` から `aggregator` に再分類し、サードパーティ Claude ゲートによってモデルテストボタンが無効化されないようにしました; パートナースターは `isPartner` によって駆動され、category には依存しないため影響を受けません。
### バージョン情報のバージョンチェック
バージョンチェックがプレリリースのツールバージョンを、更新状態を誤分類することなく扱えるようになりました。
### App スイッチャーのテキスト切れ
App スイッチャーのテキストを切り取っていた固定幅の制約を削除しました (#3161, 感謝 @loocor)。
### useEffect の競合状態
App.tsx の effects に active フラグのパターンを追加してアンマウント時のリスナーリークを防止し、localStorage に `undefined` の言語を保存しないようガードしました (#2827, 感謝 @Zylo206)。
---
## 削除
### LionCC スポンサーとプリセット
LionCC スポンサーエントリと LionCCAPI プリセットを、各 README、プロバイダー設定、ロケールにわたって削除しました(アイコンアセットは保持)。
### AICoding パートナーエントリ
AICoding パートナーを README スポンサー一覧、プロバイダープリセット、i18n メタデータから削除しました。
### Kimi For Coding の Codex プリセット
Kimi For Coding プリセットを Codex プリセットカタログから削除しました。
### CLI アンインストールコマンドのヒント
ツール管理 UI から生成された CLI アンインストールコマンドのヒントを削除しつつ、競合診断は引き続き表示します。
---
## ドキュメント
### Codex Chat プロバイダーサポート
Chat Completions ルーティング、プロバイダーサポート、推論の自動判別、ローカルルーティングのガイダンスを changelog とユーザーマニュアルにドキュメント化しました。
### 設定マニュアルのリフレッシュ
新しい受託ツールライフサイクルと Hermes インストーラーの挙動について、設定ドキュメントを更新しました。
### Claude Desktop ガイド
プロバイダー設定、インポート、モデルマッピング、ローカルルーティングのコンテキストについて、ローカライズされた Claude Desktop ガイドページとスクリーンショットを追加しました。
### インストールドキュメント
公式 Homebrew cask を推奨するようインストールドキュメントと README を更新し、v3.15.0 リリースノートの偽サイト警告の文言を各ロケールでリフレッシュしました。
---
## ⚠️ アップグレード時の注意
### Codex 履歴の一回限りのマイグレーション
アップグレード後の初回起動で、Codex 履歴の一回限りのマイグレーションが実行されます: サードパーティプロバイダーが `custom` バケットに正規化され、過去の JSONL セッションと `state_5.sqlite` スレッドテーブルが書き換えられます。オリジナルは `~/.cc-switch/backups/codex-history-provider-migration-v1/` 配下にバックアップされます。このステップは「プロバイダー切り替え後に過去のセッションが消える」問題を修正するもので、マイグレーション後は履歴が正しく復元されます。
### Codex のカタログ変更には再起動が必要
Codex は `model_catalog_json` を起動時に読み込むため、CC Switch でモデルマッピングテーブルを編集した後は、新しいカタログを反映させるために **Codex を再起動**する必要があります。
### Chat ルーティングのプロバイダーでは推論 effort が効かない場合がある
思考の オン / オフ スイッチしか公開しないプロバイダー(Kimi、GLM、Qwen、MiniMax、MiMo、SiliconFlow)では、Codex で推論 effort`model_reasoning_effort`: low / medium / high)を変更しても**効果がありません** —— CC Switch は未対応の effort フィールドをこれらに転送しません。本物の effort 階層を持つプロバイダー(DeepSeek、OpenRouter、および StepFun の `step-3.5-flash-2603` のみ)でのみ、レベルが実際に反映されます。
### デフォルトモデルが Opus 4.8 / GPT-5.5 にアップグレード
デフォルトの Claude Opus モデルラインが 4.8 に、該当箇所の GPT デフォルトが 5.5 にアップグレードされました。固定した古いデフォルトモデルに依存している場合は、アップグレード後に該当プリセット / テンプレートのモデルフィールドを確認してください。
---
## ⚠️ リスク通知
本リリースは、リバースプロキシ系機能について v3.12.3 / v3.13.0 / v3.15.0 で提起されたリスク通知を継承します。
**GitHub Copilot リバースプロキシ**: Copilot のリバースプロキシパスを使用すると、GitHub / Microsoft の利用規約に違反する可能性があります。詳細は [v3.12.3 リリースノート](v3.12.3-ja.md#-リスクに関する注意事項) を参照してください。
**Codex OAuth リバースプロキシ**: ChatGPT サブスクリプションを使用した Codex OAuth リバースプロキシは、OpenAI の利用規約に違反する可能性があります。詳細は [v3.13.0 リリースノート](v3.13.0-ja.md#-リスクに関する注意事項) を参照してください。
**Codex サードパーティプロバイダー Chat ルーティング**: CC Switch のローカルプロキシ経由で Codex のリクエストを変換し、サードパーティプロバイダーに転送する際、各プロバイダーの課金、コンプライアンス、データ保持に関する制約はそれぞれ異なります。利用前にターゲットプロバイダーの利用規約をお読みください。
**Claude Desktop サードパーティプロバイダーのプロキシ切り替え**: CC Switch 内蔵プロキシゲートウェイ経由で Claude Desktop のリクエストをサードパーティプロバイダーに転送する際、サードパーティプロバイダーの課金、コンプライアンス、データ保持に関する制約はそれぞれ異なります。利用前にターゲットプロバイダーの利用規約をお読みください。
ユーザーが上記機能を有効化することで、**すべてのリスクを自己責任で**受諾したものとみなされます。CC Switch は、これらの機能の使用に起因するアカウントの制限、警告、サービス停止について一切の責任を負いません。
---
## ダウンロード・インストール
[Releases](https://github.com/farion1231/cc-switch/releases/latest) から対応バージョンをダウンロードしてください。
### システム要件
| OS | 最小バージョン | アーキテクチャ |
| ------- | ------------------------ | ----------------------------------- |
| Windows | Windows 10 以降 | x64 |
| macOS | macOS 12 (Monterey) 以降 | Intel (x64) / Apple Silicon (arm64) |
| Linux | 下表参照 | x64 / ARM64 |
### Windows
| ファイル | 説明 |
| ---------------------------------------- | ------------------------------------------- |
| `CC-Switch-v3.16.0-Windows.msi` | **推奨** - MSI インストーラー、自動更新対応 |
| `CC-Switch-v3.16.0-Windows-Portable.zip` | ポータブル版、解凍して実行、レジストリ不要 |
### macOS
| ファイル | 説明 |
| -------------------------------- | ------------------------------------------------------ |
| `CC-Switch-v3.16.0-macOS.dmg` | **推奨** - DMG インストーラー、Applications にドラッグ |
| `CC-Switch-v3.16.0-macOS.zip` | 解凍して Applications にドラッグ、Universal Binary |
| `CC-Switch-v3.16.0-macOS.tar.gz` | Homebrew インストールと自動更新用 |
> macOS 版は Apple のコード署名および公証済みで、直接インストールして使用できます。
### HomebrewmacOS
> 🎉 CC Switch は Homebrew 公式 cask リポジトリに収録されました。カスタム tap の追加は不要です!
```bash
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
> Linux 向けの成果物は **x86_64** と **ARM64**`aarch64`)の両方が提供されます。ファイル名にアーキテクチャ識別子が含まれているため、`uname -m` の出力に応じて選択してください:
>
> - `CC-Switch-v3.16.0-Linux-x86_64.AppImage` / `.deb` / `.rpm`
> - `CC-Switch-v3.16.0-Linux-arm64.AppImage` / `.deb` / `.rpm`
| ディストリビューション | 推奨形式 | インストール方法 |
| --------------------------------------- | ----------- | -------------------------------------------------------------------------- |
| Ubuntu / Debian / Linux Mint / Pop!\_OS | `.deb` | `sudo dpkg -i CC-Switch-*.deb` または `sudo apt install ./CC-Switch-*.deb` |
| Fedora / RHEL / CentOS / Rocky Linux | `.rpm` | `sudo rpm -i CC-Switch-*.rpm` または `sudo dnf install ./CC-Switch-*.rpm` |
| openSUSE | `.rpm` | `sudo zypper install ./CC-Switch-*.rpm` |
| Arch Linux / Manjaro | `.AppImage` | 実行権限を付与して実行、または AUR を使用 |
| その他のディストリビューション / 不明 | `.AppImage` | `chmod +x CC-Switch-*.AppImage && ./CC-Switch-*.AppImage` |
+433
View File
@@ -0,0 +1,433 @@
# CC Switch v3.16.0
> 为 Codex 增加 Chat Completions -> Response 格式转换(你可以在 Codex 里使用 DeepSeek, Kimi, GLM 了!)、Codex 供应商身份与历史统一、应用管理面板全方位增强、合作伙伴预设扩张、默认模型 / 定价矩阵升级到 GPT-5.5 与 Claude Opus 4.8、代理与格式转换鲁棒性强化
**[English →](v3.16.0-en.md) | [日本語版 →](v3.16.0-ja.md)**
---
> [!WARNING]
>
> ## 唯一官方渠道声明(请务必阅读)
>
> CC Switch 是**完全免费、开源**的桌面应用,**不会向用户收取任何费用**。最近发现多个山寨网站冒用 CC Switch 名义诱导用户付费、收集账号信息,部分已造成实际经济损失。请仅通过下列官方渠道获取本软件:
>
> | 类别 | 唯一官方 |
> | -------- | ------------------------------------------------------------------------------ |
> | 官网 | **[ccswitch.io](https://ccswitch.io)** |
> | 源码 | **[github.com/farion1231/cc-switch](https://github.com/farion1231/cc-switch)** |
> | 下载 | **[GitHub Releases](https://github.com/farion1231/cc-switch/releases)** |
> | 作者 | **[@farion1231](https://github.com/farion1231)** |
> | 举报山寨 | **[GitHub Issues](https://github.com/farion1231/cc-switch/issues)** |
>
> **任何向你收费、要求充值、或索取登录凭据的"CC Switch"网站或客户端均为假冒**。如果你被诱导支付了费用,请立即停止操作并通过 GitHub Issues 反馈,让我们能尽快下线相关山寨站点。
---
## 使用攻略
本版本最主打的两块能力是 **Codex 第三方供应商 Chat Completions 路由**与**应用内受管 CLI 工具管理**。如果你想让 DeepSeek、Kimi、MiniMax 这类只支持 OpenAI Chat 协议的供应商在 Codex 里直接可用,或者想在应用内一站式安装 / 升级 CLI 工具,建议先读这两篇:
- **[添加 Codex 供应商:Chat Completions 路由与模型映射](../user-manual/zh/2-providers/2.1-add.md)** —— 覆盖「需要本地路由映射」开关、模型映射表、思考能力(reasoning)自适应识别的完整流程。
- **[设置 → 关于:受管 CLI 工具管理](../user-manual/zh/1-getting-started/1.5-settings.md)** —— 覆盖版本检测、单独升级 / 全部升级、冲突诊断、按安装来源锚定的升级命令。
---
## 概览
CC Switch v3.16.0 自 v3.15.0 以来的开发核心,是把**第三方 Codex 供应商通过 Chat Completions 路由升级为一等公民**。Codex 原生只认 OpenAI Responses API 与 GPT 系列模型,本版本让 CC Switch 的本地代理把 Codex 发出的 Responses 请求转换为上游的 Chat Completions,再把 JSON 与 SSE 流式响应重建回 Responses 形态,沿途保留 `reasoning_content` / 内联 `<think>` 块 / 流式推理摘要 / 工具调用 / `previous_response_id` 续接状态,并把错误信封规范化、在 Stream Check 中正确探测 Chat 格式供应商。配套上货 22 个带显式模型目录的 Chat 路由预设(DeepSeek、智谱 GLM、Kimi、MiniMax、StepFun、百度千帆、百炼、ModelScope、Longcat、百灵、小米 MiMo、火山 Agentplan、BytePlus、豆包 Seed、SiliconFlow、Novita AI、Nvidia 等)。
Codex 第三方供应商的**身份与历史**这一版被统一并加固:所有第三方供应商现在归并到稳定的 `custom` model-provider 桶,并提供一次性设备迁移来改写历史 JSONL 会话与 `state_5.sqlite` 线程表(原文件备份在 `~/.cc-switch/backups/` 下),避免因供应商 id 变化导致过往会话"凭空消失";同时修复了 live 读取 / 切换过程中 OAuth 登录态、用户选中的目录模型、用户自定义 provider id 被覆盖的问题。
本版本还新增了**应用内受管 CLI 工具生命周期**:设置页的「关于」Tab 升级为 Claude / Codex / Gemini / OpenCode / OpenClaw / Hermes 的工具管理面板,支持静默安装 / 更新、全部升级、冲突诊断、按安装来源锚定的升级,以及对 WSL 的处理和"已安装但跑不起来"状态的可见化。
供应商生态与模型矩阵同步刷新:新增 APIKEY.FUN、APINebula、AtlasCloud、SudoCode、小米 MiMo Token Plan、Claude Desktop 官方预设;跨应用刷新合作伙伴链接与默认模型 / 定价;默认 Claude Opus 模型线升级到 **4.8**,适用处的 GPT 默认升级到 **5.5**。此外还在用量可观测性、繁体中文本地化、文档、以及代理 / 格式转换的鲁棒性上做了大量打磨与修复。
**发布日期**2026-05-29
**更新规模**101 commits | 221 files changed | +27,063 / -3,052 lines
---
## 重点内容
- **Codex Chat Completions 路由**Codex 供应商现在可以由仅支持 OpenAI Chat Completions 的上游提供服务。CC Switch 把 Codex 的 Responses 请求转成 Chat Completions、把 JSON 与 SSE 响应重建回 Responses 形态、保留 reasoning / `<think>` / 工具调用状态、规范化错误信封,并在 Stream Check 中正确探测 Chat 格式供应商
- **Codex 第三方供应商身份与历史统一并更安全**:第三方 Codex 供应商现在共用稳定的 `custom` model-provider 桶,配一次性迁移改写历史 JSONL 会话与 `state_5.sqlite` 线程,并修复 live 读取 / 切换时 OAuth 登录态、用户选中的目录模型、用户自定义 provider id 的保留
- **受管 CLI 工具管理**:「关于」页升级为 Claude / Codex / Gemini / OpenCode / OpenClaw / Hermes 的工具管理面板,含安装 / 更新动作、全部升级、冲突诊断、按来源锚定的升级、WSL 处理,以及"已安装但跑不起来"状态可见化
- **供应商生态与模型矩阵刷新**:新增 APIKEY.FUN、APINebula、AtlasCloud、SudoCode、小米 MiMo Token Plan、Claude Desktop 官方预设;跨应用刷新合作伙伴链接与默认模型 / 定价;默认 Claude Opus 升级到 4.8、适用处 GPT 默认升级到 5.5
- **用量与文档打磨**:用量看板在日志写入时即时响应更新,修复自定义用量脚本摘要与 subagent 会话日志计费,繁体中文 UI 本地化落地,新增德文 README 与扩充后的 Claude Desktop / Codex Chat / 工具管理手册
- **代理与转换硬化**:修复 Codex Chat 推理 / 缓存 / usage 边角情况、DeepSeek Anthropic 工具思考历史、Claude 兼容的空 `tool_calls` 流、受管账号接管鉴权、MiMo 推理输出、Gemini Native 工具调用重放,以及多条易 panic 的代理路径
---
## 新功能
### Codex Chat Completions 路由
Codex 供应商现在可以由只会说 OpenAI Chat Completions API 的上游提供服务。CC Switch 的本地代理把 Codex 发出的 Responses 请求转换为 Chat Completions,并把 Chat 响应(JSON 与 SSE 两种)重建回 Responses 形态,沿途保留 `reasoning_content`、内联 `<think>` 块、流式推理摘要、工具调用,以及 `previous_response_id` 续接。一个有界的 Codex Chat 历史缓存会在工具输出之前恢复对应的工具调用。
> 💡 特别感谢 [@EldenPdx](https://github.com/EldenPdx) 的 PR [#2804](https://github.com/farion1231/cc-switch/pull/2804):本功能的 Chat ↔ Responses 格式转换实现参考了他在该 PR 中的实现。
### 22 个带 Chat 路由的 Codex 第三方供应商预设
为主流中国开源模型启用了 Chat Completions 路由并带显式模型目录——DeepSeek、智谱 GLM+ 英文站)、Kimi、MiniMax+ 英文站)、StepFun+ 英文站)、百度千帆 Coding Plan、百炼(Bailian)、ModelScope、Longcat、百灵(BaiLing)、小米 MiMo+ Token Plan)、火山 Agentplan、BytePlus、豆包 Seed、SiliconFlow+ 英文站)、Novita AI、Nvidia。每个预设都声明了自己的上下文窗口,便于 UI 给模型映射行确定尺寸。
### Codex 模型映射表
Codex 供应商表单现在提供模型目录(每行:模型 + 显示名 + 上下文窗口),它是上游模型列表的唯一真相来源,并投影到 `~/.codex/cc-switch-model-catalog.json`
### Stream Check 支持 Codex Chat 供应商
Stream Check 现在对 Chat 格式的 Codex 供应商改用 Chat 形态的请求体打 `/chat/completions`,而不是 `/v1/responses`;并把 URL 回退顺序与生产环境的 `CodexAdapter` 对齐(仅 origin 的 base URL 先打 `/v1/<endpoint>`),这样裸路径上的非 404 错误不会再把一个正常工作的供应商误判为不可用。
### Codex Chat 思考能力(Reasoning)自适应
当 Codex 供应商走 Chat Completions 路由时,CC Switch 现在会**自动识别**上游的推理接口——依据是供应商的名称、base URL 和模型名——并注入正确的思考参数(`thinking:{type}``enable_thinking``reasoning_split`、顶层 `reasoning_effort`,或 OpenRouter 的原生 `reasoning:{effort}` 对象),无需手动配置。聚合 / 托管平台(OpenRouter、SiliconFlow)按**平台优先**匹配,因为同一个模型在不同平台上可能暴露不同的推理控制。只暴露"思考开 / 关"开关的供应商(Kimi、GLM、Qwen、MiniMax、MiMo、SiliconFlow)会**丢弃 effort 等级**而不是透传一个不支持的字段——因此在 Codex 里调节这类供应商的思考等级不会有任何效果——而有真实 effort 档位的供应商(DeepSeek、OpenRouter,以及 StepFun 仅 `step-3.5-flash-2603`)则会把等级透传上去。OpenRouter 特别使用原生 `reasoning:{effort}` 对象,把 `max` 钳到 `xhigh`(它的枚举里没有 `max`),并显式转发 `effort:"none"` 以便关闭推理。
### Codex Goal Mode 与远程压缩控制
Codex 配置编辑现在为第三方供应商暴露一个 Goal Mode 开关和一个远程压缩(Remote Compaction)开关;新建的 Codex 模板默认 `disable_response_storage = true`,同时仍允许显式开启 goal 支持。
### 小米 MiMo Token Plan 预设
新增小米 MiMo Token Plan 预设,规格与官方文档对齐(#2803,感谢 @BlueOcean223)。
### Claude Desktop 官方预设
新增一个 Claude Desktop 官方预设,用于恢复原生 Claude Desktop 登录,并附带本地化的 Claude Desktop 使用指南(中 / 英 / 日)。
### 受管 CLI 工具生命周期
为受管 CLI 工具新增静默安装 / 更新命令、最新版本检查、单工具与批量动作、全部升级,以及跨 PATH、Homebrew、npm、pnpm、bun、volta、fnm、nvm、scoop、WinGet、Windows 原生路径和 WSL 的多安装诊断。
### 按来源感知的工具诊断
设置 / 关于 页面现在可以诊断冲突的工具安装、为每条路径展示具体的安装来源与版本,并生成由后端规划、锚定到真实安装来源的升级命令。
### 实时用量刷新
后端现在在代理日志、会话日志同步或汇总写入用量数据时发出 `usage-log-recorded` 事件;用量看板监听该事件并立即让查询失效,而不是等到下一个轮询周期(#3027,感谢 @in30mn1a)。
### 繁体中文本地化
新增 `zh-TW` UI 本地化与一个设置语言选项(#3093,感谢 @LaiYueTing)。
### 德文 README
新增 `README_DE.md` 并从现有 README 的语言切换器中链接到它(#2994,感谢 @flitzrrr)。
### 新合作伙伴预设
跨各受支持的应用面新增 APIKEY.FUN、APINebula、AtlasCloud、SudoCode 合作伙伴预设,含合作伙伴文案、图标与 README 条目。
---
## 变更
### Codex 第三方供应商统一进 "custom" 历史桶
Codex 按 `model_provider` 过滤可恢复历史,因此在供应商专属 id 之间切换会让过去的会话看起来"消失"了。所有第三方供应商现在归并到单一稳定的 `custom` 桶(保留 `openai` / `ollama` 这类预留的内置 id),并配一次性设备迁移:改写历史 JSONL 会话与 `state_5.sqlite` 线程表,原文件备份到 `~/.cc-switch/backups/codex-history-provider-migration-v1/`
### Codex 供应商表单简化
从 Codex 表单中移除了 API Format 选择器(`wire_api` 永远是 `responses`,该选择器会误导用户以为能改协议);模型映射表现在是唯一真相来源,不再有隐藏的默认条目;表单注明改动目录后需要重启 Codex,因为 `model_catalog_json` 在启动时加载。表单只保留「需要本地路由映射」开关。
### Codex 本地路由开关提示重写
把「关 / 开」两段提示从"场景描述"改写为"动作指引"(什么时候该开),并在中 / 英 / 日三语同步。
### Codex Live 配置保留
Codex live 配置读取不再强制改写用户的 `model_provider` 字段;供应商作用域的 `experimental_bearer_token` 处理现在会在第三方供应商之间切换时保留 OAuth 登录态。
### 工具安装 / 升级策略
受管工具安装现在优先使用官方原生安装器(在有的情况下),适当时回退到包管理器,对兼容工具先跑 self-update,把升级锚定到检测到的安装来源,并在工作进行中锁定重复的批量动作。
### 「关于」页升级为工具管理
设置的「关于」页现在呈现已安装 / 最新版本、安装与更新动作、冲突诊断、WSL shell 偏好,以及对损坏或跑不起来工具更清晰的状态。
### 默认模型与定价刷新
默认 Claude Opus 模型升级到 4.8,适用处把基于 GPT 的预设与模板迁到 GPT-5.5,刷新定价种子,把 Claude Desktop 模型映射与 Claude Code 的三角色档位对齐,并重命名 OpenCode 的 Go 预设以去掉一个陈旧的模型后缀。
### 合作伙伴链接刷新
更新了胜算云推荐链接、Atlas Cloud 的 UTM 链接,以及跨各 README 语言版本与供应商元数据中的合作伙伴文案。
### Homebrew 官方 Cask 安装
由于 CC Switch 已进入 Homebrew 官方仓库,安装简化为 `brew install --cask cc-switch`;各 README 中移除了对私有 tap 的要求。
### 共享前端工具
用一个共享的 `deepClone` helper 替换 JSON stringify / parse 的深拷贝写法,并抽取了一个共享的 `useTauriEvent` hook#3140,感谢 @ChongBiaoZhang)。
---
## 修复
### Codex Chat 错误响应转换为 Responses 信封
Codex Chat → Responses 桥接此前会原样透传上游错误体,导致 Codex 客户端无法识别 MiniMax 的 `base_resp`、裸 OpenAI Chat 错误,或纯文本 / HTML 错误页。现在错误会被规整为标准的 `{error: {message, type, code, param}}` 信封并保留原始 HTTP 状态码;非 JSON 体会被包裹并在 UTF-8 字符边界截断到 1KB。同时修复了一个既存的 append-vs-insert bug,它会在重写后的 JSON 体上产生重复的 `Content-Type` 头。
### Codex 流中段 system 消息折叠
MiniMax 的 OpenAI 兼容端点会严格拒绝任何非首位的 `system` 消息(错误 2013)。现在所有 `system` 片段会被折叠为单条首位消息(按原顺序拼接),对宽松后端也是无损的。
### Codex 模型目录重启后被清空
编辑当前激活的 Codex 供应商会触发一次省略了 `modelCatalog` 的 live 读取,于是随后的保存会静默销毁用户配置的模型映射。Live 读取现在会反向解析磁盘上的目录投影,往返出与保存路径写入的相同形状。
### Codex 模型目录无限渲染循环
打断了目录表格与其父状态之间的双向同步环路——它在添加或编辑条目时会导致 UI 严重抖动。
### Codex Chat 保留用户选中的目录模型
客户端从目录里选中的模型(例如通过 `/model`)不再被 `config.toml` 的默认模型覆盖。
### Codex Chat 推理与缓存稳定性
在 Codex 省略或改写 `previous_response_id` 时恢复一个唯一的 call-id 回退;停止从 `previous_response_id` 派生缓存身份;并在工具转换中对可解析的 JSON 字符串载荷做规范化,以便前缀缓存稳定复用。
### Codex Chat 流式 usage 恢复
Responses → Chat 转换现在会在请求为流式时注入 `stream_options.include_usage`(并入客户端提供的任何 `stream_options`),这样 Kimi、MiniMax 这类 OpenAI 兼容上游会重新吐出尾部的 usage 块。此前它们在 Codex Chat 路径上的流式 token / 成本 / 缓存统计都被记成了零。
### Codex Chat 工具调用推理回填
Kimi / Moonshot、DeepSeek 这类思考模型会拒绝携带 `tool_calls``reasoning_content` 为空的 assistant 消息。当跨轮历史恢复未命中时(代理重启、`call_id` 含糊,或某轮上游没有推理),现在会在最后一遍补回一个占位 `reasoning_content`——真实的尾部推理仍会优先附上——这样请求不再因 `reasoning_content is missing in assistant tool call message` 而失败。
### 受管账号 Claude 接管鉴权
受管账号供应商(GitHub Copilot / Codex OAuth)在接管 Claude live 配置时,现在会丢弃 token 环境变量键、只写入 `ANTHROPIC_API_KEY` 占位符,并带一个出站守卫拒绝把 `PROXY_MANAGED` 占位符发往上游。
### 接管期间的 Claude Desktop profile 同步
代理接管时现在会同步 Claude Desktop 的 profile 数据,模型路由与 Claude Code 的三角色档位对齐,并修正了 Cowork egress profile#3157#3172,感谢 @MelorTang@JGSphaela)。
### 受管账号接管的模型字段
本地路由现在在受管账号上从目标供应商取接管模型字段,而不是携带陈旧的模型值。
### DeepSeek Anthropic 工具思考历史
规范化了 DeepSeek Anthropic 兼容的工具思考历史,让后续轮次能够重放推理 / 工具调用上下文而不产生畸形消息(#3203,感谢 @Q3yp)。
### Claude 兼容流中的空工具调用
修复了一个 Claude 兼容流式边角情况:空的 `tool_calls` 数组会重置块状态并破坏流式响应(#2915,感谢 @zhizhuowq)。
### Claude Code 代理路径的 MiMo 推理
在 Claude Code 代理路径上新增 MiMo 的 `reasoning_content` 支持(#2990,感谢 @zhangyapu1)。
### Gemini Native 工具调用鲁棒性
修复了长多轮会话中合成工具调用 ID 的 `functionResponse.name` 解析(422)与 `thought_signature` 重放(400)问题(#2814,感谢 @Tiancrimson)。
### 会话日志 subagent token 计费
`collect_jsonl_files()` 现在会扫描此前被漏掉的 subagent JSONL 日志,使 subagent 的 token 用量被计入会话成本(仅会话日志模式)(#2821,感谢 @LaoYueHanNi)。
### 用量看板 / 同步稳定性
修复了非 ASCII 模型名导致的 Codex 用量同步 panic、自定义用量脚本摘要,以及用量汇总后缺失实时刷新的问题(#3027#3129,感谢 @in30mn1a@hanhan3344)。
### 智谱 Coding Plan 配额档位排序
当 5 小时桶利用率为 0% 时,智谱 API 会省略 `nextResetTime`;旧的 `i64::MAX` 哨兵会把这类条目排到最后,导致周窗口错误地占用五小时槽位。现在档位排序会让缺失的 `nextResetTime` 映射到五小时桶,使智谱 Coding Plan 的托盘与用量配额显示保持正确。
### 技能按 key 安装
从 skills.sh 搜索结果安装时现在使用唯一 key 而不是目录名,使共享目录名的技能能安装到正确的那个(#2784,感谢 @zhaomoran);同时修复了一处技能同步的复制回退(#2791,感谢 @rogerdigital)。
### 用量价格输入精度
把价格输入步长降到 0.0001,使 DeepSeek 缓存读取这类不足一分的成本也能录入(#2793,关闭 #2503,感谢 @rogerdigital)。
### Ghostty 干净窗口启动
Ghostty 现在打开单个干净窗口,而不是克隆已有标签页;其他终端则通过 `open -na` 打开新窗口(#2801,关闭 #2798,感谢 @luw2007)。
### 工具版本与更新可靠性
版本探测不再掩盖跑不起来的安装;预发布工具在版本检查中被正确处理;批量更新逐工具执行;安装 / 更新按钮在预检期间保持锁定;锚定升级分支强制使用绝对路径;WSL 安装器路径在需要时使用原生 Unix 安装器。
### Codex mise 检测
修复了 Codex 的 mise 环境检测(#2822,感谢 @iambinlin)。
### Codex 归档会话
Codex 的归档会话现在会被纳入会话发现(#2861,感谢 @nanmen2)。
### Codex Chat 空工具参数
在 Codex Chat 转换中,空的工具调用参数载荷会被强制为 `{}`,使上游与客户端收到合法 JSON。
### Claude 供应商 deeplink 导入
通过 deeplink 导入 Claude 供应商时现在会保留自定义环境字段(#2928,感谢 @doutuifei)。
### OMO 推荐模型
把 OMO 推荐模型与上游默认值同步,并改进了「填入推荐」的反馈。
### 胜算云模型 ID 加前缀以正确路由
胜算云(ShengSuanYun)预设现在带上了上游网关要求的厂商前缀——`anthropic/…``google/…``openai/…`(如 `anthropic/claude-sonnet-4.6``google/gemini-3.1-pro-preview`)——覆盖 Claude Code、Claude Desktop、Codex、Gemini、OpenCode、OpenClaw 各预设,含 Claude Code 路由环境变量(`ANTHROPIC_MODEL` / `ANTHROPIC_DEFAULT_{HAIKU,SONNET,OPUS}_MODEL`),使它们解析到合法的上游模型而不是路由失败。
### ClaudeAPI 重新启用模型测试
把 ClaudeAPI 预设(Claude Code 与 Claude Desktop)从 `third_party` 重新归类为 `aggregator`,使其模型测试按钮不再被第三方 Claude 门禁禁用;合作伙伴金星不受影响,因为它由 `isPartner` 而非 category 驱动。
### 关于页版本检查
版本检查现在能处理预发布工具版本,不会再误判更新状态。
### App 切换器文本裁切
移除了一个会裁切 App 切换器文本的固定宽度约束(#3161,感谢 @loocor)。
### useEffect 竞态条件
`App.tsx` 的 effects 加了 active-flag 模式以防卸载时的监听器泄漏,并守卫了把 `undefined` 语言存进 localStorage 的情况(#2827,感谢 @Zylo206)。
---
## 移除
### LionCC 赞助商与预设
跨各 README、供应商配置与 locale 移除了 LionCC 赞助商条目与 LionCCAPI 预设(图标资源保留)。
### AICoding 合作伙伴条目
从 README 赞助商列表、供应商预设与 i18n 元数据中移除了 AICoding 合作伙伴。
### Kimi For Coding 的 Codex 预设
从 Codex 预设目录中移除了 Kimi For Coding 预设。
### CLI 卸载命令提示
从工具管理 UI 中去掉了生成的 CLI 卸载命令提示,同时保留冲突诊断的可见性。
---
## 文档
### Codex Chat 供应商支持
在 changelog 与用户手册中记录了 Chat Completions 路由、供应商支持、推理自适应识别,以及本地路由指引。
### 设置手册刷新
更新了设置文档,覆盖新的受管工具生命周期与 Hermes 安装器行为。
### Claude Desktop 指南
新增了本地化的 Claude Desktop 指南页与截图,覆盖供应商设置、导入、模型映射,以及本地路由上下文。
### 安装文档
更新了安装文档与 README,推荐官方 Homebrew cask,并跨各语言刷新了 v3.15.0 发布说明里关于山寨站点的警告措辞。
---
## ⚠️ 升级提醒
### Codex 第三方供应商历史一次性迁移
升级后首次启动会对 Codex 历史执行一次性迁移:把第三方供应商归并到 `custom` 桶,并改写历史 JSONL 会话与 `state_5.sqlite` 线程表。原文件会备份到 `~/.cc-switch/backups/codex-history-provider-migration-v1/`。这一步是为了修复"切换供应商后过往会话消失"的问题——迁移后历史能正常恢复。
### Codex 改动模型目录需重启
Codex 在启动时加载 `model_catalog_json`,因此在 CC Switch 里改动模型映射表后,需要**重启 Codex** 才能让新目录生效。
### Chat 路由供应商的思考等级可能无效
对只暴露"思考开 / 关"开关的供应商(Kimi、GLM、Qwen、MiniMax、MiMo、SiliconFlow),在 Codex 里调节思考等级(`model_reasoning_effort` 的 low / medium / high**不会有任何效果**——CC Switch 不会把不被支持的 effort 字段透传给它们。只有具备真实 effort 档位的供应商(DeepSeek、OpenRouter,以及 StepFun 仅 `step-3.5-flash-2603`)调节等级才真正生效。
### 默认模型升级到 Opus 4.8 / GPT-5.5
默认 Claude Opus 模型线升级到 4.8,适用处的 GPT 默认升级到 5.5。如果你依赖某个固定的旧默认模型,升级后请检查相关预设 / 模板的模型字段是否符合预期。
---
## ⚠️ 风险提示
本版本在涉及反向代理类功能上沿用 v3.12.3 / v3.13.0 / v3.15.0 提出的风险提示。
**GitHub Copilot 反向代理**:使用 Copilot 的反代路径可能违反 GitHub / Microsoft 服务条款。详情见 [v3.12.3 release notes](v3.12.3-zh.md#-风险提示)。
**Codex OAuth 反向代理**:使用 ChatGPT 订阅的 Codex OAuth 反代可能违反 OpenAI 服务条款,详情见 [v3.13.0 release notes](v3.13.0-zh.md#-风险提示)。
**Codex 第三方供应商 Chat 路由**:通过 CC Switch 本地代理把 Codex 请求转换并转发到第三方供应商时,各供应商对计费、合规与数据留存的约束各不相同,请在使用前阅读目标供应商的服务条款。
**Claude Desktop 第三方供应商代理切换**:通过 CC Switch 内置代理网关把 Claude Desktop 的请求转到第三方供应商时,第三方供应商对计费、合规与数据留存的约束各不相同,请在使用前阅读目标供应商的服务条款。
用户启用上述功能即表示**自行承担所有风险**。CC Switch 不对因使用这些功能而导致的任何账号限制、警告或服务暂停承担责任。
---
## 下载与安装
访问 [Releases](https://github.com/farion1231/cc-switch/releases/latest) 下载对应版本。
### 系统要求
| 系统 | 最低版本 | 架构 |
| ------- | -------------------------- | ----------------------------------- |
| Windows | Windows 10 及以上 | x64 |
| macOS | macOS 12 (Monterey) 及以上 | Intel (x64) / Apple Silicon (arm64) |
| Linux | 见下表 | x64 / ARM64 |
### Windows
| 文件 | 说明 |
| ---------------------------------------- | ----------------------------------- |
| `CC-Switch-v3.16.0-Windows.msi` | **推荐** - MSI 安装包,支持自动更新 |
| `CC-Switch-v3.16.0-Windows-Portable.zip` | 便携版,解压即用,不写入注册表 |
### macOS
| 文件 | 说明 |
| -------------------------------- | --------------------------------------------- |
| `CC-Switch-v3.16.0-macOS.dmg` | **推荐** - DMG 安装包,拖入 Applications 即可 |
| `CC-Switch-v3.16.0-macOS.zip` | 解压后拖入 ApplicationsUniversal Binary |
| `CC-Switch-v3.16.0-macOS.tar.gz` | 用于 Homebrew 安装和自动更新 |
> macOS 版本已通过 Apple 代码签名和公证,可直接安装使用。
### HomebrewmacOS
> 🎉 CC Switch 现已收录至 Homebrew 官方 cask 仓库,无需添加第三方 tap!
```bash
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
> Linux 资产同时提供 **x86_64** 和 **ARM64**`aarch64`)两种架构。资产文件名中包含架构标识,请按你机器的 `uname -m` 输出选择对应版本:
>
> - `CC-Switch-v3.16.0-Linux-x86_64.AppImage` / `.deb` / `.rpm`
> - `CC-Switch-v3.16.0-Linux-arm64.AppImage` / `.deb` / `.rpm`
| 发行版 | 推荐格式 | 安装方式 |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| Ubuntu / Debian / Linux Mint / Pop!\_OS | `.deb` | `sudo dpkg -i CC-Switch-*.deb``sudo apt install ./CC-Switch-*.deb` |
| Fedora / RHEL / CentOS / Rocky Linux | `.rpm` | `sudo rpm -i CC-Switch-*.rpm``sudo dnf install ./CC-Switch-*.rpm` |
| openSUSE | `.rpm` | `sudo zypper install ./CC-Switch-*.rpm` |
| Arch Linux / Manjaro | `.AppImage` | 添加执行权限后直接运行,或使用 AUR |
| 其他发行版 / 不确定 | `.AppImage` | `chmod +x CC-Switch-*.AppImage && ./CC-Switch-*.AppImage` |
+3 -3
View File
@@ -12,9 +12,9 @@
## Version / 版本 / バージョン
- Documentation version: v3.13.0
- Last updated: 2026-04-08
- Compatible with CC Switch v3.13.0+
- Documentation version: v3.15.0
- Last updated: 2026-05-16
- Compatible with CC Switch v3.15.0+
## Links
Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

@@ -2,14 +2,14 @@
## What is CC Switch
CC Switch is a cross-platform desktop application designed for developers who use AI coding tools. It helps you centrally manage configurations for five major AI coding tools: **Claude Code**, **Codex**, **Gemini CLI**, **OpenCode**, and **OpenClaw**.
CC Switch is a cross-platform desktop application designed for developers who use AI coding tools. It helps you centrally manage configurations for **Claude Code**, **Claude Desktop**, **Codex**, **Gemini CLI**, **OpenCode**, **OpenClaw**, and **Hermes**.
## What Problems Does It Solve
In your daily development workflow, you may encounter these pain points:
- **Tedious multi-provider switching**: Using different API providers (official, proxy services) requires manually editing configuration files
- **Scattered configurations**: Claude, Codex, Gemini, OpenCode, and OpenClaw each have independent configuration files in different formats
- **Scattered configurations**: Claude Code, Claude Desktop, Codex, Gemini, OpenCode, OpenClaw, and Hermes each have independent configuration files in different formats
- **No usage monitoring**: No visibility into how many API calls were made or how much they cost
- **Service instability**: When a single provider goes down, your entire workflow is interrupted
@@ -21,6 +21,7 @@ CC Switch solves these problems through a unified interface.
- One-click switching between multiple API provider configurations
- Preset templates for quickly adding common providers
- Universal provider feature for sharing configurations across apps
- Claude Desktop third-party providers, direct mode, and model mapping
- Usage query and balance display
- Endpoint speed testing
@@ -40,16 +41,18 @@ CC Switch solves these problems through a unified interface.
| Application | Description |
|-------------|-------------|
| **Claude Code** | Anthropic's official AI coding assistant |
| **Claude Desktop** | Claude desktop app with official sign-in and third-party 3P profiles |
| **Codex** | OpenAI's code generation tool |
| **Gemini CLI** | Google's AI command-line tool |
| **OpenCode** | Open-source AI coding terminal tool |
| **OpenClaw** | Open-source AI coding assistant (multi-provider gateway) |
| **Hermes** | Hermes Agent provider, MCP, Skills, and Memory management |
## Supported Platforms
- **Windows** 10 and above
- **macOS** 10.15 (Catalina) and above
- **Linux** Ubuntu 22.04+ / Debian 11+ / Fedora 34+
- **macOS** 12 (Monterey) and above
- **Linux** Ubuntu 22.04+ / Debian 11+ / Fedora 34+ (x64 / ARM64)
## Technical Architecture
@@ -1,5 +1,15 @@
# 1.2 Installation Guide
## Official Channels and System Requirements
Only download CC Switch from **[ccswitch.io](https://ccswitch.io)**, **[GitHub Releases](https://github.com/farion1231/cc-switch/releases)**, or the project source repository. Any "CC Switch" site or client that asks for payment, top-ups, or login credentials is not official.
| System | Minimum Version | Architecture |
|--------|-----------------|--------------|
| Windows | Windows 10 or later | x64 |
| macOS | macOS 12 (Monterey) or later | Intel (x64) / Apple Silicon (arm64) |
| Linux | See distribution notes below | x64 / ARM64 |
## Prerequisites
### Install Node.js
@@ -127,8 +137,8 @@ brew upgrade --cask cc-switch
### Option 2: Manual Download
1. Download `CC-Switch-v{version}-macOS.zip`
2. Extract to get `CC Switch.app`
1. Download `CC-Switch-v{version}-macOS.dmg` (recommended) or `CC-Switch-v{version}-macOS.zip`
2. Open the DMG, or extract the zip to get `CC Switch.app`
3. Drag it to the Applications folder
### Signed and Notarized
@@ -151,11 +161,11 @@ yay -S cc-switch-bin
### Debian / Ubuntu
1. Download `CC-Switch-v{version}-Linux.deb`
1. Download `CC-Switch-v{version}-Linux-x86_64.deb` or `CC-Switch-v{version}-Linux-arm64.deb` for your architecture
2. Install:
```bash
sudo dpkg -i CC-Switch-v{version}-Linux.deb
sudo dpkg -i CC-Switch-v{version}-Linux-*.deb
# If there are dependency issues
sudo apt-get install -f
@@ -163,17 +173,17 @@ sudo apt-get install -f
### AppImage (Universal)
1. Download `CC-Switch-v{version}-Linux.AppImage`
1. Download `CC-Switch-v{version}-Linux-x86_64.AppImage` or `CC-Switch-v{version}-Linux-arm64.AppImage` for your architecture
2. Add execute permission:
```bash
chmod +x CC-Switch-v{version}-Linux.AppImage
chmod +x CC-Switch-v{version}-Linux-*.AppImage
```
3. Run:
```bash
./CC-Switch-v{version}-Linux.AppImage
./CC-Switch-v{version}-Linux-*.AppImage
```
## Verify Installation
@@ -182,7 +192,7 @@ After installation, launch CC Switch:
1. The app window displays correctly
2. A CC Switch icon appears in the system tray
3. You can switch between Claude / Codex / Gemini apps
3. The app switcher shows enabled managed apps, and you can switch to the target app panel
## Auto Update
@@ -11,7 +11,7 @@
| 1 | Logo | Click to visit the GitHub project page |
| 2 | Settings Button | Open the settings page (shortcut `Cmd/Ctrl + ,`) |
| 3 | Proxy Toggle | Start/stop the local proxy service |
| 4 | App Switcher | Switch between Claude / Codex / Gemini / OpenCode / OpenClaw |
| 4 | App Switcher | Switch between Claude / Claude Desktop / Codex / Gemini / OpenCode / OpenClaw / Hermes |
| 5 | Feature Area | Skills / Prompts / MCP entry points |
| 6 | Add Button | Add a new provider |
@@ -20,10 +20,12 @@
Click the dropdown menu to switch the currently managed application:
- **Claude** - Manage Claude Code configuration
- **Claude Desktop** - Manage Claude Desktop third-party providers and official mode
- **Codex** - Manage Codex configuration
- **Gemini** - Manage Gemini CLI configuration
- **OpenCode** - Manage OpenCode configuration
- **OpenClaw** - Manage OpenClaw configuration
- **Hermes** - Manage Hermes Agent providers and Memory
After switching, the provider list displays the configurations for the selected application.
@@ -56,6 +58,8 @@ Each provider is displayed as a card, containing the following elements from lef
> **Tip**: The action buttons area (5-10) appears on hover and is hidden by default to keep the interface clean.
Starting from v3.15.0, some Claude Code and Codex provider cards also show a **Local Routing support badge**, helping you quickly identify providers that can be served through local routing.
### Button Details
| Button | State Changes | Notes |
@@ -100,12 +104,12 @@ CC Switch displays an icon in the system tray, providing quick access to operati
| Menu Item | Function |
|-----------|----------|
| Open Main Window | Show and focus the main window |
| App Submenus | Collapsible submenus grouped by Claude/Codex/Gemini (e.g., "Claude · PackyCode") |
| App Submenus | Collapsible submenus grouped by Claude/Codex/Gemini (e.g., "Claude · PackyCode"), with current provider and cached usage summaries when available |
| Provider List | Inside each submenu, click to switch; currently active shows a checkmark |
| Lightweight Mode | Toggle checkbox to enter/exit tray-only mode |
| Quit | Fully exit the application |
> **Note**: Each app submenu title shows the current provider name (e.g., "Claude · PackyCode"). Apps with no configured providers show a disabled "(no providers)" entry. App visibility is controlled by the App Visibility setting.
> **Note**: Each tray submenu title shows the current provider name (e.g., "Claude · PackyCode"). Apps with no configured providers show a disabled "(no providers)" entry. The tray currently focuses on Claude / Codex / Gemini, the apps that support proxy routing and usage summaries; main-window app visibility is still controlled by the App Visibility setting.
### Multi-language Support
@@ -82,7 +82,7 @@ When enabled, skips the Claude Code onboarding flow, suitable for users already
Choose which applications to display in the app switcher. Each app can be toggled independently, but at least one must remain visible.
Configurable apps: Claude, Codex, Gemini, OpenCode, OpenClaw.
Configurable apps: Claude, Claude Desktop, Codex, Gemini, OpenCode, OpenClaw, Hermes.
> **Use case**: If you only use Claude Code and Codex CLI, you can hide the other apps to keep the interface clean.
@@ -314,19 +314,21 @@ Automatically detects installed CLI tool versions:
| Gemini | Current version, latest version |
| OpenCode | Current version, latest version |
| OpenClaw | Current version, latest version |
| Hermes | Current version, latest version |
Click the "Refresh" button to re-detect.
Click the "Refresh" button to re-detect. When an update is available, you can update a single tool or use "Update All". Missing tools show an install button. Installs and updates run silently in the background—the button shows progress and versions refresh automatically when done.
### One-click Install Commands
### Manual Install Commands
Provides quick commands to install/update CLI tools:
Provides quick commands to install/update CLI tools (collapsed by default; click the heading to expand):
```bash
npm i -g @anthropic-ai/claude-code@latest
npm i -g @openai/codex@latest
npm i -g @google/gemini-cli@latest
npm i -g opencode@latest
npm i -g opencode-ai@latest
npm i -g openclaw@latest
python3 -m pip install --upgrade "hermes-agent[web]"
```
Click the "Copy" button to copy to clipboard.
+95 -9
View File
@@ -5,7 +5,7 @@
Click the **+** button in the top-right corner of the main interface to open the Add Provider panel.
The panel has two tabs:
- **App-specific Provider**: Only for the currently selected app (Claude/Codex/Gemini/OpenCode/OpenClaw)
- **App-specific Provider**: Only for the currently selected app (Claude Code / Claude Desktop / Codex / Gemini / OpenCode / OpenClaw / Hermes)
- **Universal Provider**: Shared configuration across apps
## Add Using Presets
@@ -56,8 +56,22 @@ Presets are pre-configured provider templates that only require an API Key to us
> The preset list may be updated with new versions. Refer to the actual list shown in the app.
#### Claude Desktop Presets
The Claude Desktop panel includes provider presets translated from the Claude Code preset catalog. When adding one, choose between:
- **Direct mode**: the provider exposes a native Anthropic Messages API and its model names are Claude Desktop-recognized role IDs (`claude-sonnet-*` / `claude-opus-*` / `claude-haiku-*`), so Claude Desktop can reach it directly
- **Model mapping mode**: model names outside the three role IDs (legacy Claude IDs, or non-Claude models like DeepSeek / Kimi) are mapped through the CC Switch local gateway into Sonnet / Opus / Haiku routes
- **Claude Desktop Official**: restores Claude Desktop's official sign-in mode
See [2.6 Claude Desktop](./2.6-claude-desktop.md) for the full workflow.
#### Codex Presets
Codex presets fall into two groups by upstream protocol.
**Native Responses protocol** (direct connection or standard proxy forwarding):
| Preset Name | Description |
|-------------|-------------|
| OpenAI Official | Log in with an OpenAI official account |
@@ -65,11 +79,32 @@ Presets are pre-configured provider templates that only require an API Key to us
| AiHubMix | AiHubMix aggregation service |
| DMXAPI | DMXAPI proxy service |
| PackyCode | PackyCode proxy service |
| Cubence | Cubence service |
| AIGoCode | AIGoCode service |
| RightCode | RightCode service |
| AICodeMirror | AICodeMirror service |
| OpenRouter | Aggregation routing service |
| Cubence / AIGoCode / RightCode / AICodeMirror, etc. | Various proxy services |
**Chat Completions protocol** (requires the **Needs Local Routing** toggle; converted automatically by the proxy):
| Preset Name | Description |
|-------------|-------------|
| DeepSeek | DeepSeek models |
| Zhipu GLM / GLM en | Zhipu AI GLM models |
| Kimi | Moonshot Kimi models |
| MiniMax / MiniMax en | MiniMax models |
| StepFun / StepFun en | StepFun Step models |
| Baidu Qianfan Coding Plan | Baidu Qianfan coding plan |
| Bailian | Alibaba Cloud Bailian (Qwen) |
| ModelScope | ModelScope community |
| Longcat | Longcat AI |
| BaiLing | BaiLing AI |
| Xiaomi MiMo / MiMo Token Plan | Xiaomi MiMo models |
| Volcengine Agentplan | Volcengine Agent Plan |
| BytePlus | BytePlus service |
| DouBaoSeed | DouBao Seed models |
| SiliconFlow / SiliconFlow en | SiliconFlow |
| Novita AI | Novita AI service |
| Nvidia | Nvidia AI service |
> 💡 When you pick a Chat Completions preset, the **Needs Local Routing** toggle and the model mapping table are configured automatically; see the "Codex Local Routing and Model Mapping" section below. The preset list is updated continuously — refer to the in-app list for the authoritative version.
#### Gemini Presets
@@ -161,7 +196,7 @@ When adding or editing a provider, you can automatically discover available mode
3. CC Switch uses the configured API Key to call the OpenAI-compatible `/v1/models` endpoint
4. Select a model from the dropdown, grouped by category
This feature covers **all five apps** **Claude / Codex / Gemini / OpenCode / OpenClaw** and works for any provider that supports the `/v1/models` endpoint.
This feature is available in model-aware provider forms for **Claude Code / Claude Desktop / Codex / Gemini / OpenCode / OpenClaw / Hermes**, and works for providers that support the `/v1/models` endpoint. Codex OAuth providers fetch live model lists from the ChatGPT Codex backend on demand.
**Common errors:**
- **Authentication failed (401/403)**: Check your API Key
@@ -233,10 +268,13 @@ requires_openai_auth = true
| `model` | Yes | Model to use (e.g., `gpt-5.2`, `gpt-4o`) |
| `model_reasoning_effort` | No | Reasoning effort: `low` / `medium` / `high` |
| `disable_response_storage` | No | Whether to disable response storage |
| `goals` | No | Enables Codex `/goal` mode when set under `[features]`; the provider editor can toggle this field for providers that need it |
| `base_url` | Yes | API endpoint URL |
| `wire_api` | No | API protocol type (usually `responses`) |
| `requires_openai_auth` | No | Whether to use OpenAI authentication |
If Codex recognizes `/goal` but cannot set a goal after switching to an API-key or custom endpoint provider, enable the provider editor's **Goal mode** switch. CC Switch writes `goals = true` under `[features]` for that provider's `~/.codex/config.toml`; restart Codex afterward. If Goal mode asks for approval more often than expected, refresh the Codex settings page and check that `approval_policy` and `sandbox_mode` still match your intended permission level.
### Gemini Configuration Format
@@ -259,7 +297,7 @@ requires_openai_auth = true
## Universal Provider
Universal providers can share configurations across Claude/Codex/Gemini/OpenCode/OpenClaw, suitable for proxy services that support multiple API formats.
Universal providers can share configurations across Claude Code / Codex / Gemini, suitable for proxy services that support multiple API formats.
### Create a Universal Provider
@@ -269,7 +307,7 @@ Universal providers can share configurations across Claude/Codex/Gemini/OpenCode
- Name
- API Key
- Endpoint URL
4. Check the apps to sync to (Claude/Codex/Gemini/OpenCode/OpenClaw)
4. Check the apps to sync to (Claude Code / Codex / Gemini)
5. Save
### Sync Mechanism
@@ -403,6 +441,8 @@ The Codex OAuth preset's default model mapping:
| Opus role | `gpt-5.4` |
| Haiku role | `gpt-5.4-mini` |
Starting from v3.15.0, Codex OAuth model selection no longer relies only on a hardcoded list. When the model selector opens, CC Switch fetches available models from the ChatGPT Codex backend on demand; the default mapping can still be overridden.
You can override the `ANTHROPIC_MODEL` and related environment variables in the provider's JSON editor to customize.
### Multi-Account Management (OAuth Auth Center)
@@ -516,6 +556,52 @@ When a toggle is unchecked, its corresponding config entry is removed entirely.
Additionally, the **Write Common Config** checkbox enables merging a global config snippet into the provider. Click **Edit Common Config** to customize the shared snippet.
### Codex Local Routing and Model Mapping
Some third-party providers only support the **OpenAI Chat Completions** protocol or use non-GPT model names (such as DeepSeek, Kimi, or MiniMax). Codex natively understands only the OpenAI Responses API and GPT-series models, so these providers need CC Switch to convert the protocol and models locally.
#### Needs Local Routing
When editing a Codex provider, a **Needs Local Routing** toggle is available:
- **When to enable**: the provider uses the Chat Completions protocol, or its model names are not Codex's default GPT series
- **When enabled**: CC Switch's local proxy converts the Responses requests Codex sends into upstream Chat Completions, then converts the response (including streaming SSE, reasoning content, and tool calls) back into Responses format
- **Prerequisite**: [local routing](../4-proxy/4.1-service.md) must be running with Codex takeover enabled for conversion to take effect; keep local routing running while in use
> 💡 When you pick a Chat-format preset such as DeepSeek or Kimi, this toggle is enabled by default — no manual setup needed.
#### Model Mapping
Once **Needs Local Routing** is enabled, a **Model Mapping** table appears below it to declare the models available for this provider:
| Field | Description |
|-------|-------------|
| Model ID | The real upstream model name, e.g. `deepseek-v4-flash` |
| Display Name | (Optional) The name shown in the `/model` command |
| Context Window | (Optional) The model's context length |
- The mapping table generates Codex's `model_catalog_json` so the `/model` command lists these third-party model names
- Entries are saved exactly as listed and are the single source of truth for the model list
- **Codex must be restarted** to refresh the model list after changes (`model_catalog_json` is loaded at Codex startup)
#### Reasoning Auto-Detection
With Local Routing on, CC Switch **auto-detects** each provider's reasoning interface and converts Codex's outgoing reasoning request into a parameter the upstream understands — **no manual setup required**. Detection is based on the provider's name, base URL, and model:
- **Aggregator / hosting platforms first**: OpenRouter, SiliconFlow, etc. are handled by platform rules (the same model can expose a completely different reasoning interface on different platforms)
- **Otherwise by model brand**: DeepSeek, Kimi / Moonshot, Zhipu GLM, Qwen, MiniMax, Xiaomi MiMo, StepFun each have their own rules
Providers fall into two reasoning-capability tiers:
| Capability | Meaning | Example providers |
|------------|---------|-------------------|
| **Effort levels supported** | Reasoning strength is adjustable (low / medium / high, etc.) | DeepSeek, OpenRouter, StepFun (`step-3.5-flash-2603` only) |
| **On/off switch only** | Reasoning can only be turned on or off; **levels have no effect** | Kimi, Zhipu GLM, Qwen, MiniMax, Xiaomi MiMo, SiliconFlow |
> ⚠️ **Effort levels do nothing for some providers**: if a provider only supports an on/off switch, changing the reasoning effort in Codex (`model_reasoning_effort` low / medium / high) has **no effect** — CC Switch does not forward the level to these upstreams (their API rejects the parameter, and sending it anyway may break the request). Their reasoning is **on by default** and works via on/off rather than tiering. Only providers with real effort levels (e.g. DeepSeek, OpenRouter) actually respond to a level change.
> 💡 **Detection is keyword matching on name / base URL / model**, not a real capability probe. Official domains (e.g. `api.deepseek.com`, `api.moonshot.cn`) are always recognized; a relay that rewrites the domain and model name may not be detected, in which case no reasoning parameter is injected.
### Codex 1M Context Window
When adding a Codex provider, an **Enable 1M Context Window** toggle is available:
@@ -523,7 +609,7 @@ When adding a Codex provider, an **Enable 1M Context Window** toggle is availabl
- **When enabled**: Sets `model_context_window = 1000000` and auto-fills `model_auto_compact_token_limit = 900000` in config.toml
- **When disabled**: Removes both fields
The auto-compact limit can be customized in the text field that appears when the toggle is on.
The auto-compact limit can be customized in the text field that appears when the toggle is on. Starting from v3.15.0, this toggle only appears when adding a new Codex provider; when editing an existing provider, adjust the fields directly in advanced configuration if needed.
### Custom Icon
@@ -39,14 +39,12 @@ Starting from v3.13.0, the tray menu is refactored from a flat list into **per-a
| Claude | All Claude providers (including Codex OAuth reverse proxy) |
| Codex | All Codex providers |
| Gemini | All Gemini providers |
| OpenCode | All OpenCode providers |
| OpenClaw | All OpenClaw providers |
**Benefits of the refactor**:
- **Prevents menu overflow**: With many providers, a flat list would exceed screen height; per-app submenus scale naturally
- **Submenu title shows the currently active provider**: You know at a glance which provider each app is using, without opening the submenu
- **Per-app isolation**: Switching Claude's provider doesn't disturb the Codex view
- **Submenu title shows the currently active provider and usage summary**: You know at a glance which provider Claude / Codex / Gemini is using, plus available cached usage information, without opening the submenu
- **Per-app isolation**: Switching Claude's provider doesn't disturb the Codex or Gemini view
> **Tip**: The combination of background residency + Lightweight Mode + per-app submenus is especially suited for heavy users who frequently switch among multiple apps. See [1.5 Personalization → Lightweight Mode](../1-getting-started/1.5-settings.md).
+3 -2
View File
@@ -151,8 +151,9 @@ Configuration uses JSON format, and the editor provides:
## Save and Activate
1. Click the "Save" button
2. If this is the currently active provider, the configuration is immediately written to the live file
3. Restart the CLI tool for changes to take effect
2. If the form detects a non-blocking issue, a "save anyway" prompt appears; confirming still saves the provider
3. If this is the currently active provider, the configuration is immediately written to the live file
4. Restart the CLI tool for changes to take effect
## Cancel Editing
@@ -24,6 +24,8 @@ Quickly create a copy of a provider, useful for:
- Backing up current configurations
- Creating test configurations
Starting from v3.15.0, universal providers also have a duplicate action, so you can create a copy first and then adjust enabled apps and models.
### Steps
1. Hover over the provider card to reveal action buttons
@@ -176,18 +176,18 @@ Interval for automatically refreshing usage data (minutes):
## Extractor Return Format
The extractor function must return an object containing the following fields:
The extractor function returns an object containing the following fields. All fields are optional:
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `isValid` | boolean | No | Whether the account is valid, defaults to true |
| `invalidMessage` | string | No | Message when invalid |
| `remaining` | number | Yes | Remaining balance |
| `unit` | string | Yes | Unit (e.g., USD, CNY, times) |
| `remaining` | number | No | Remaining balance |
| `unit` | string | No | Unit (e.g., USD, CNY, times) |
| `planName` | string | No | Plan name (supports multi-plan) |
| `total` | number | No | Total balance |
| `used` | number | No | Used amount |
| `extra` | object | No | Additional information |
| `extra` | string | No | Additional display text |
## Test Script
@@ -0,0 +1,306 @@
# 2.6 Claude Desktop
## Overview
The Claude Desktop panel lets you manage Claude Desktop provider configurations in CC Switch.
Once enabled, you can:
- Use third-party Anthropic-compatible providers in Claude Desktop
- Configure model mapping for models outside the three role IDs: legacy Claude IDs (e.g. `claude-3-5-sonnet`) and non-Claude models like DeepSeek / Kimi / DouBao / OpenAI / Gemini all need it
- Reuse Copilot / Codex OAuth account-based providers
- Switch between Claude Desktop official mode and third-party providers
Claude Desktop and Claude Code are separate app entry points. Claude Code uses `~/.claude/settings.json`, while Claude Desktop uses its own 3P profile configuration. In CC Switch they appear as separate apps: "Claude" and "Claude Desktop"; the icon badge in the bottom-right corner helps distinguish them.
## Support Scope
| Item | Description |
|------|-------------|
| Supported systems | macOS, Windows |
| Not supported yet | Writing Claude Desktop 3P configuration on Linux |
| Takes effect | Restart Claude Desktop after switching providers |
| Official mode | Uses Claude Desktop built-in sign-in; no API key or endpoint URL required |
| Third-party mode | Writes the 3P profile managed by CC Switch |
| MCP / Skills | Claude Desktop 3P profiles do not use CC Switch MCP / Skills sync |
## Quick Start
### Step 1: Open the Claude Desktop Panel
Select **Claude Desktop** in the app switcher on the left.
![Claude Desktop panel](../../assets/claude-desktop-panel-en.png)
If you do not see this entry, go to:
Settings → General → Homepage Display
Make sure Claude Desktop is not hidden.
### Step 2: Import or Add Providers
#### Recommended: Import from Claude Code
Many users configure providers in Claude Code first, then want to bring the same provider set into Claude Desktop. On first launch, or when entering the Claude Desktop panel for the first time, if no providers exist here, click **Import existing providers from Claude Code**.
![Import providers from Claude Code](../../assets/claude-desktop-import-from-claude-en.png)
If you already have many providers configured in Claude Code, this one-click import saves you from re-entering endpoint URLs, API keys, and default models one by one.
Import rules:
- Existing providers with the same ID are not overwritten
- Providers whose model names are the three role IDs (`claude-sonnet-*` / `claude-opus-*` / `claude-haiku-*`) and can connect directly are imported as direct mode
- Providers whose model names are not the three role IDs (including legacy Claude IDs), or that need format conversion, are imported as model mapping mode when possible
- `ANTHROPIC_DEFAULT_SONNET_MODEL`, `ANTHROPIC_DEFAULT_OPUS_MODEL`, and `ANTHROPIC_DEFAULT_HAIKU_MODEL` are converted into Desktop Sonnet / Opus / Haiku mappings
- The legacy `[1M]` suffix is converted into the `supports1m` flag in the Claude Desktop profile
- Providers whose model mapping cannot be inferred are skipped
After importing, review each provider's model mapping against your actual upstream models. Any model that is not a `claude-sonnet-*` / `claude-opus-*` / `claude-haiku-*` role ID—including non-Claude models like Kimi, DeepSeek, GLM, and DouBao, as well as legacy Claude IDs—usually needs model mapping mode.
If you already configured providers in Claude Code, prefer **Import existing providers from Claude Code**. This is the easiest migration path to Claude Desktop.
If there is nothing to import, or if you want to add a provider only for Claude Desktop, click the **+** button in the top-right corner.
![Add Claude Desktop provider](../../assets/claude-desktop-add-provider-en.png)
You can choose:
- **Preset provider**: choose from built-in Claude Desktop presets and fill in only the API key
- **Custom configuration**: manually enter name, endpoint URL, API key, and model settings
- **Claude Desktop Official**: restore Claude Desktop official sign-in mode
For native Anthropic Messages API providers that already accept Claude Desktop's three role IDs (`claude-sonnet-*` / `claude-opus-*` / `claude-haiku-*`), you usually only need to:
1. Choose a preset or custom provider
2. Fill in **API Key**
3. Confirm **API Endpoint**
4. Keep **Needs model mapping** off
5. Click **Add**
### Step 3: Switch and Restart Claude Desktop
Click **Enable** on a provider card.
After switching:
- Direct providers: restart Claude Desktop for the change to take effect
- Providers that need routing: keep CC Switch running, turn on Claude Desktop local routing, then restart Claude Desktop
> Note: Claude Desktop does not hot-reload configuration like Claude Code. After each provider switch, fully quit and reopen Claude Desktop.
## Two Modes
### Direct Mode
Direct mode is for providers that already expose the Anthropic Messages API and can be reached by Claude Desktop directly.
In direct mode, CC Switch points the Claude Desktop 3P profile to the provider endpoint:
```json
{
"inferenceProvider": "gateway",
"inferenceGatewayBaseUrl": "https://api.example.com",
"inferenceGatewayAuthScheme": "bearer",
"inferenceGatewayApiKey": "your API key"
}
```
Use this when:
- The provider exposes native Anthropic Messages API
- Model IDs are Claude Desktop-recognized role names: `claude-sonnet-*`, `claude-opus-*`, or `claude-haiku-*` (or the same with the `anthropic/claude-` prefix)
- No format conversion is needed
- CC Switch local routing does not need to stay running while in use
The "Manually specify Claude Desktop models" option in direct mode is advanced. Most native Claude model providers do not need it because Claude Desktop can fetch `/v1/models` automatically.
Only fill it in when the provider's `/v1/models` is unavailable, or when the returned model names cannot be recognized by Claude Desktop. Manually entered model names must follow the `claude-sonnet-*`, `claude-opus-*`, or `claude-haiku-*` shape (legacy IDs like `claude-3-5-sonnet-…` are rejected).
### Model Mapping Mode
Model mapping mode is for providers whose models are not `claude-sonnet-*` / `claude-opus-*` / `claude-haiku-*` role IDs (including legacy Claude IDs and non-Claude models such as DeepSeek and Kimi), or when CC Switch needs to convert the API format.
After **Needs model mapping** is enabled, Claude Desktop connects to the CC Switch local gateway:
```text
http://127.0.0.1:15721/claude-desktop
```
CC Switch handles:
1. Exposing safe Claude model routes to Claude Desktop
2. Mapping the model role selected in Desktop to the real upstream model
3. Converting Anthropic / OpenAI / Gemini request formats as required by the provider
4. Using the provider credentials saved in CC Switch to call upstream
Supported API formats:
| Format | Usage |
|--------|-------|
| Anthropic Messages | Native or compatible Anthropic requests |
| OpenAI Chat Completions | OpenAI-compatible `/chat/completions` |
| OpenAI Responses API | OpenAI Responses-compatible endpoints |
| Gemini Native generateContent | Gemini native API |
In model mapping mode, Claude Desktop only sees the three role routes: `claude-sonnet-*`, `claude-opus-*`, and `claude-haiku-*`. Real upstream model names are not written directly into the Claude Desktop profile.
## Configure Model Mapping
### Field Reference
| Field | Description |
|-------|-------------|
| Model role | Sonnet / Opus / Haiku route recognizable by Claude Desktop |
| Menu display name | Name shown in the Claude Desktop model menu |
| Requested model | Real upstream model ID sent to the provider |
| 1M | Declares 1M context support to Claude Desktop |
![Claude Desktop model mapping](../../assets/claude-desktop-model-mapping-rows-en.png)
### Recommended Setup
For Kimi:
| Model role | Menu display name | Requested model | 1M |
|------------|-------------------|-----------------|----|
| Sonnet | Kimi K2 | `kimi-k2` | Match provider capability |
For DeepSeek:
| Model role | Menu display name | Requested model | 1M |
|------------|-------------------|-----------------|----|
| Sonnet | DeepSeek V4 Pro | `deepseek-v4-pro` | Match provider capability |
The reason is that Claude Desktop now rejects models outside the Sonnet / Opus / Haiku role families, so CC Switch local routing performs a model mapping pass.
### Multiple Role Mapping
You can configure Sonnet, Opus, and Haiku at the same time:
| Model role | Recommended usage |
|------------|-------------------|
| Sonnet | Default main model |
| Opus | Higher quality or complex tasks |
| Haiku | Fast, lower-cost model |
If the provider only has one model, filling in just one role's requested model is enough; blank roles automatically inherit the first filled model (Sonnet first), so the Haiku that sub-agents call is always available. Model mapping mode requires at least one requested model.
## Local Routing Toggle
Model mapping mode needs CC Switch local routing to convert requests. Local routing is powerful but more complex, so the main-page routing toggle is hidden by default to avoid accidental clicks by users who do not need routing. When you need routing, show it manually.
Open:
Settings → Routing → Local Routing → enable **Show Routing Toggle on Main Page**
![Show local routing toggle setting](../../assets/local-routing-display-setting-en.png)
After enabling this display switch, return to the Claude Desktop panel. The Claude Desktop local routing toggle appears in the top-right area of the main page.
![Claude Desktop local routing toggle](../../assets/claude-desktop-route-toggle-context-en.png)
Status reference:
| Status | Description |
|--------|-------------|
| On | Local gateway is running, usually at `127.0.0.1:15721` |
| Off | Direct providers still work; model mapping providers cannot work normally |
| Loading | Routing service is starting or stopping |
Only providers with **Needs model mapping** depend on local routing. Direct providers do not need this toggle.
If another app is using proxy takeover, stopping local routing may be blocked. First disable that app's takeover in the routing service settings, then stop local routing.
## Restore Official Claude Desktop
To return to Claude Desktop official sign-in:
1. Select **Claude Desktop Official**
2. Click **Enable**
3. Restart Claude Desktop
CC Switch restores Claude Desktop's official 1P mode and removes the 3P profile managed by CC Switch.
Official mode does not need an API key or local routing.
When importing from Claude Code, CC Switch automatically adds **Claude Desktop Official**.
## Configuration File Locations
CC Switch writes Claude Desktop 3P configuration files.
### macOS
```text
~/Library/Application Support/Claude/claude_desktop_config.json
~/Library/Application Support/Claude-3p/claude_desktop_config.json
~/Library/Application Support/Claude-3p/configLibrary/_meta.json
~/Library/Application Support/Claude-3p/configLibrary/00000000-0000-4000-8000-000000157210.json
```
### Windows
```text
%LOCALAPPDATA%\Claude\claude_desktop_config.json
%LOCALAPPDATA%\Claude-3p\claude_desktop_config.json
%LOCALAPPDATA%\Claude-3p\configLibrary\_meta.json
%LOCALAPPDATA%\Claude-3p\configLibrary\00000000-0000-4000-8000-000000157210.json
```
These files are maintained automatically by CC Switch. Manual edits are not recommended. If configuration becomes inconsistent, enabling the current provider again usually repairs it.
## Status Messages
The Claude Desktop panel may show "Claude Desktop configuration needs attention".
| Message | How to handle |
|---------|---------------|
| Current platform is not supported | Only macOS / Windows currently support writing 3P configuration |
| Profile contains model names outside the Sonnet / Opus / Haiku role families | Switch to the current provider again, or edit the provider to use model mapping |
| Model mapping is enabled but no valid route exists | Edit the provider and add at least one model mapping |
| Local routing token has not been generated | Switch to the provider again; CC Switch will write a new local token |
| Profile URL does not match the current provider | Switch to the current provider again so the profile points to the expected URL |
## FAQ
### Switched successfully, but Claude Desktop did not change?
Fully quit and restart Claude Desktop. Claude Desktop usually reads the 3P profile on startup and does not hot-reload it after changes.
### Model mapping provider request failed?
Check:
- CC Switch is still running
- Claude Desktop local routing is enabled
- Provider API key and endpoint URL are correct
- Requested model is filled in the model mapping
- Claude Desktop was restarted after switching providers
### Why does my branded model name not appear in the Claude Desktop model menu?
Edit the provider, fill in **Menu display name** in model mapping, then enable the provider again and restart Claude Desktop.
### Why does direct mode fail?
Direct mode requires the provider to expose native Anthropic Messages API and accept Claude Desktop's three role IDs (`claude-sonnet-*` / `claude-opus-*` / `claude-haiku-*`). If the provider uses OpenAI, Gemini, non-Claude model IDs, or legacy Claude IDs (e.g. `claude-3-5-sonnet-…`)—any ID outside the three roles—direct mode fails, so enable **Needs model mapping**.
### Can I close CC Switch?
It depends on the mode:
- Direct mode: after Claude Desktop restarts and loads the profile, local routing does not need to keep running
- Model mapping mode: CC Switch must keep running, and Claude Desktop local routing must stay on
### Are real upstream model names written into Claude Desktop?
Not in model mapping mode. The Claude Desktop profile only stores safe Sonnet / Opus / Haiku role routes and display names. Real upstream model names stay in the CC Switch provider configuration and are mapped when requests pass through the local gateway.
## Next Steps
- [Add Provider](./2.1-add.md)
- [Switch Provider](./2.2-switch.md)
- [Proxy Service](../4-proxy/4.1-service.md)
- [App Takeover](../4-proxy/4.2-routing.md)
@@ -11,12 +11,13 @@ The Session Manager lets you browse, search, and manage conversation sessions fr
| OpenCode | `~/.local/share/opencode/` (JSON or SQLite) |
| OpenClaw | `~/.openclaw/agents/<agent>/sessions/*.jsonl` |
| Gemini CLI | `~/.cache/gemini/tmp/<project_hash>/chats/` |
| Hermes | `~/.hermes/state.db` or `~/.hermes/sessions/*.jsonl` |
## Opening the Session Manager
Click the **Sessions** button in the main navigation bar toolbar.
> **Note**: The Sessions button is visible for all five supported applications.
> **Note**: The Session Manager covers the six session sources listed above; the Claude Desktop entry reuses the Claude Code session view.
## Interface Layout
@@ -63,6 +64,7 @@ Click the provider filter dropdown (top-right of left panel) to filter by applic
- **OpenCode**
- **OpenClaw**
- **Gemini CLI**
- **Hermes**
The filter can be combined with search.
@@ -81,7 +83,7 @@ Click the **Resume** button (play icon) on a selected session to continue the co
- The terminal opens in the session's project directory
- If terminal launch fails, the command is copied to your clipboard instead
**Supported terminals (macOS):** Terminal.app, iTerm2, Ghostty, Kitty, WezTerm, Alacritty
**Supported terminals (macOS):** Terminal.app, iTerm2, Ghostty, Kitty, WezTerm, Alacritty, Warp
**On other platforms:**
- The resume command is copied to your clipboard
@@ -103,7 +105,7 @@ Starting from v3.13.0, **Claude sessions** show a **directory picker** before re
2. In the popup directory picker, confirm the default directory or choose a new one
3. CC Switch launches the Claude terminal session in the selected directory
> **Note**: Codex / Gemini / OpenCode / OpenClaw session resume flows do not yet include the directory picker and still use the session's original project directory.
> **Note**: Codex / Gemini / OpenCode / OpenClaw / Hermes session resume flows do not yet include the directory picker and still use the session's original project directory.
### Delete Session
+8 -1
View File
@@ -50,10 +50,15 @@ Key metrics displayed at the top of the page:
| Metric | Description |
|--------|-------------|
| Total Requests | Total number of requests in the time period |
| Total Tokens | Total input + output tokens |
| Real Total Tokens | Cache-normalized total of input + output + cache creation + cache read tokens |
| Cache Hit Rate | Cache read tokens as a share of cacheable input |
| Estimated Cost | Cost calculated based on pricing configuration |
| Success Rate | Percentage of successful requests |
Starting from v3.15.0, the top of the Usage page uses a filter-driven Hero card. When you change the date range, app, provider, or model filters, the Hero's real total tokens, cache hit rate, request count, and cost update together and stay aligned with the logs and stats below.
> Note: v3.15.0 normalizes cache reads, cache creation, and OpenAI-style cache reporting. Historical token and cost numbers may differ from older estimates; the current numbers follow the normalized rules.
### Time Range
Select the time range for statistics:
@@ -238,6 +243,8 @@ CC Switch includes preset official prices for common models (per million tokens)
| Model | Input | Output | Cache Read | Cache Creation |
|-------|-------|--------|------------|----------------|
| **Claude 4.8 Series** | | | | |
| claude-opus-4-8 | $5 | $25 | $0.50 | $6.25 |
| **Claude 4.5 Series** | | | | |
| claude-opus-4-5 | $5 | $25 | $0.50 | $6.25 |
| claude-sonnet-4-5 | $3 | $15 | $0.30 | $3.75 |
@@ -10,7 +10,9 @@ The model test feature (also known as **Stream Check**) verifies whether a provi
- Whether the response latency is acceptable
- Time to first token (TTFB) for streaming responses
Starting from v3.13.0, Stream Check coverage is extended to **all five apps** (Claude / Codex / Gemini / OpenCode / OpenClaw), including all OpenClaw protocol variants (such as `openai-completions`). OpenCode is auto-detected via npm package mapping; OpenClaw supports custom `auth-header` detection and handles edge cases like Bedrock error messages and `baseURL` fallback.
Starting from v3.13.0, Stream Check coverage is extended to **Claude / Codex / Gemini / OpenCode / OpenClaw**, including all OpenClaw protocol variants (such as `openai-completions`). OpenCode is auto-detected via npm package mapping; OpenClaw supports custom `auth-header` detection and handles edge cases like Bedrock error messages and `baseURL` fallback.
For Codex third-party providers that use the Chat Completions protocol (such as DeepSeek, Kimi, or MiniMax), Stream Check probes the `/chat/completions` endpoint (instead of `/responses`) and aligns its URL fallback order with the actual proxy forwarding path (origin-only addresses try `/v1/...` first), so a working provider is not mistakenly flagged as unavailable.
## Open Configuration
+17 -8
View File
@@ -1,6 +1,6 @@
# CC Switch User Manual
> All-in-One Assistant for Claude Code / Codex / Gemini CLI / OpenCode / OpenClaw
> All-in-One Assistant for Claude Code / Claude Desktop / Codex / Gemini CLI / OpenCode / OpenClaw / Hermes
## Table of Contents
@@ -19,7 +19,8 @@ CC Switch User Manual
│ ├── 2.2 Switch Provider
│ ├── 2.3 Edit Provider
│ ├── 2.4 Sort & Duplicate
── 2.5 Usage Query
── 2.5 Usage Query
│ └── 2.6 Claude Desktop
├── 3. Extensions
│ ├── 3.1 MCP Server Management
@@ -63,6 +64,7 @@ CC Switch User Manual
| [2.3-edit.md](./2-providers/2.3-edit.md) | Edit configuration, modify API Key, backfill mechanism |
| [2.4-sort-duplicate.md](./2-providers/2.4-sort-duplicate.md) | Drag-to-reorder, duplicate provider, delete |
| [2.5-usage-query.md](./2-providers/2.5-usage-query.md) | Usage query, remaining balance, multi-plan display |
| [2.6-claude-desktop.md](./2-providers/2.6-claude-desktop.md) | Claude Desktop third-party providers, direct mode, and model mapping |
### 3. Extensions
@@ -98,24 +100,31 @@ CC Switch User Manual
- **New users**: Start with [1.1 Introduction](./1-getting-started/1.1-introduction.md)
- **Installation issues**: See [1.2 Installation Guide](./1-getting-started/1.2-installation.md)
- **Configure providers**: See [2.1 Add Provider](./2-providers/2.1-add.md)
- **Use Claude Desktop**: See [2.6 Claude Desktop](./2-providers/2.6-claude-desktop.md)
- **Using proxy**: See [4.1 Proxy Service](./4-proxy/4.1-service.md)
- **Having trouble**: See [5.2 FAQ](./5-faq/5.2-questions.md)
## Version Information
- Documentation version: v3.13.0
- Last updated: 2026-04-08
- Applicable to CC Switch v3.13.0+
- Documentation version: v3.15.0
- Last updated: 2026-05-16
- Applicable to CC Switch v3.15.0+
### v3.13.0 Highlights
### v3.15.0 Highlights
- **First-class Claude Desktop panel**: supports third-party providers, direct / model mapping modes, Copilot / Codex OAuth reuse, and 3P profile writing. See [2.6 Claude Desktop](./2-providers/2.6-claude-desktop.md)
- **Role-based model mapping**: adapts Claude Desktop model validation with Sonnet / Opus / Haiku routes and `supports1m`
- **Claude Desktop local routing**: provides a local gateway at `127.0.0.1:15721/claude-desktop` for providers that need conversion
- **Routing support badges**: Claude Code / Codex provider cards indicate whether a provider can be served through Local Routing
- **Codex OAuth live model discovery**: ChatGPT Codex providers fetch available models from the ChatGPT backend on demand
- **Filter-driven Usage Hero**: shows cache-normalized real total tokens and cache hit rate, updating with date / provider / model filters — see [4.4 Usage Statistics](./4-proxy/4.4-usage.md)
- **Lightweight Mode**: Destroys the main window when minimizing to tray — near-zero idle footprint. See [1.5 Personalization](./1-getting-started/1.5-settings.md)
- **Quota & Balance Display**: Official subscriptions (Claude/Codex/Gemini/Copilot/Codex OAuth) auto-display quotas; Token Plan and third-party balances use built-in templates with one-click enable — see [2.5 Usage Query](./2-providers/2.5-usage-query.md)
- **Codex OAuth Reverse Proxy**: Reuse your ChatGPT account's Codex service inside Claude Code — see [2.1 Add Provider](./2-providers/2.1-add.md)
- **Per-App Tray Submenus**: Five independent app submenus to prevent tray overflow — see [2.2 Switch Provider](./2-providers/2.2-switch.md)
- **Per-App Tray Submenus**: Claude / Codex / Gemini submenus show the current provider and available usage summaries — see [2.2 Switch Provider](./2-providers/2.2-switch.md)
- **Skills Discovery & Batch Updates**: SHA-256 update detection, batch updates, skills.sh public registry search — see [3.3 Skills Management](./3-extensions/3.3-skills.md)
- **Full URL Endpoint Mode**: Advanced option to treat `base_url` as the full upstream endpoint — see [2.1 Add Provider](./2-providers/2.1-add.md)
- **OpenCode / OpenClaw Stream Check Coverage**: Stream Check panel extended to all five apps — see [4.5 Model Test](./4-proxy/4.5-model-test.md)
- **OpenCode / OpenClaw Stream Check Coverage**: Stream Check covers Claude / Codex / Gemini / OpenCode / OpenClaw — see [4.5 Model Test](./4-proxy/4.5-model-test.md)
## Contributing
@@ -2,14 +2,14 @@
## CC Switch とは
CC Switch はクロスプラットフォームのデスクトップアプリケーションで、AI プログラミングツールを使用する開発者向けに設計されています。**Claude Code**、**Codex**、**Gemini CLI**、**OpenCode**、**OpenClaw** の 5 つの AI プログラミングツールの設定を統一的に管理できます。
CC Switch はクロスプラットフォームのデスクトップアプリケーションで、AI プログラミングツールを使用する開発者向けに設計されています。**Claude Code**、**Claude Desktop**、**Codex**、**Gemini CLI**、**OpenCode**、**OpenClaw**、**Hermes** などの管理対象アプリの設定を統一的に管理できます。
## どのような問題を解決するか
日常の開発で、以下のような課題に直面することがあります:
- **複数プロバイダーの切り替えが面倒**:異なる API プロバイダー(公式、中継サービスなど)を使用する際、設定ファイルを手動で変更する必要がある
- **設定が分散して管理しづらい**Claude、Codex、Gemini、OpenCode、OpenClaw がそれぞれ独立した設定ファイルを持ち、フォーマットも異なる
- **設定が分散して管理しづらい**:Claude Code、Claude Desktop、Codex、Gemini、OpenCode、OpenClaw、Hermes がそれぞれ独立した設定ファイルを持ち、フォーマットも異なる
- **使用量を監視できない**:API をどれだけ呼び出したか、いくらかかったかが分からない
- **サービスが不安定**:単一プロバイダーに問題が発生すると、ワークフロー全体が中断する
@@ -21,6 +21,7 @@ CC Switch は統一されたインターフェースでこれらの問題を解
- ワンクリックで複数の API プロバイダー設定を切り替え
- プリセットテンプレートで一般的なプロバイダーを素早く追加
- 統一プロバイダー機能で、アプリ間で設定を共有
- Claude Desktop のサードパーティプロバイダー、直結モード、モデルマッピング
- 使用量クエリと残額表示
- エンドポイント速度テスト
@@ -40,16 +41,18 @@ CC Switch は統一されたインターフェースでこれらの問題を解
| アプリ | 説明 |
|------|------|
| **Claude Code** | Anthropic 公式の AI プログラミングアシスタント |
| **Claude Desktop** | Claude デスクトップアプリ。公式サインインとサードパーティ 3P profile に対応 |
| **Codex** | OpenAI のコード生成ツール |
| **Gemini CLI** | Google の AI コマンドラインツール |
| **OpenCode** | オープンソース AI プログラミングターミナルツール |
| **OpenClaw** | オープンソース AI プログラミングアシスタント(マルチプロバイダーゲートウェイ) |
| **Hermes** | Hermes Agent のプロバイダー、MCP、Skills、Memory 管理 |
## 対応プラットフォーム
- **Windows** 10 以上
- **macOS** 10.15 (Catalina) 以上
- **Linux** Ubuntu 22.04+ / Debian 11+ / Fedora 34+
- **macOS** 12 (Monterey) 以上
- **Linux** Ubuntu 22.04+ / Debian 11+ / Fedora 34+x64 / ARM64
## 技術アーキテクチャ
@@ -1,5 +1,15 @@
# 1.2 インストールガイド
## 公式チャネルとシステム要件
CC Switch は **[ccswitch.io](https://ccswitch.io)**、**[GitHub Releases](https://github.com/farion1231/cc-switch/releases)**、またはプロジェクトのソースリポジトリからのみ入手してください。支払い、チャージ、ログイン情報の入力を求める「CC Switch」サイトやクライアントは公式ではありません。
| システム | 最低バージョン | アーキテクチャ |
|------|----------------|----------------|
| Windows | Windows 10 以上 | x64 |
| macOS | macOS 12 (Monterey) 以上 | Intel (x64) / Apple Silicon (arm64) |
| Linux | 下記ディストリビューション説明を参照 | x64 / ARM64 |
## 前提条件
### Node.js のインストール
@@ -127,8 +137,8 @@ brew upgrade --cask cc-switch
### 方法 2:手動ダウンロード
1. `CC-Switch-v{バージョン}-macOS.zip` をダウンロード
2. 展開して `CC Switch.app` を取得
1. `CC-Switch-v{バージョン}-macOS.dmg`(推奨)または `CC-Switch-v{バージョン}-macOS.zip` をダウンロード
2. DMG を開く、または zip を展開して `CC Switch.app` を取得
3. 「アプリケーション」フォルダにドラッグ
### 署名・公証済み
@@ -151,11 +161,11 @@ yay -S cc-switch-bin
### Debian / Ubuntu
1. `CC-Switch-v{バージョン}-Linux.deb` をダウンロード
1. アーキテクチャに合わせて `CC-Switch-v{バージョン}-Linux-x86_64.deb` または `CC-Switch-v{バージョン}-Linux-arm64.deb` をダウンロード
2. インストール:
```bash
sudo dpkg -i CC-Switch-v{バージョン}-Linux.deb
sudo dpkg -i CC-Switch-v{バージョン}-Linux-*.deb
# 依存関係に問題がある場合
sudo apt-get install -f
@@ -163,17 +173,17 @@ sudo apt-get install -f
### AppImage(汎用)
1. `CC-Switch-v{バージョン}-Linux.AppImage` をダウンロード
1. アーキテクチャに合わせて `CC-Switch-v{バージョン}-Linux-x86_64.AppImage` または `CC-Switch-v{バージョン}-Linux-arm64.AppImage` をダウンロード
2. 実行権限を追加:
```bash
chmod +x CC-Switch-v{バージョン}-Linux.AppImage
chmod +x CC-Switch-v{バージョン}-Linux-*.AppImage
```
3. 実行:
```bash
./CC-Switch-v{バージョン}-Linux.AppImage
./CC-Switch-v{バージョン}-Linux-*.AppImage
```
## インストールの確認
@@ -182,7 +192,7 @@ chmod +x CC-Switch-v{バージョン}-Linux.AppImage
1. アプリウィンドウが正常に表示される
2. システムトレイに CC Switch のアイコンが表示される
3. Claude / Codex / Gemini の 3 つのアプリを切り替えられる
3. アプリ切り替えに有効化された管理対象アプリが表示され、目的のアプリパネルへ切り替えられる
## 自動更新
@@ -11,7 +11,7 @@
| ① | Logo | クリックで GitHub プロジェクトページにアクセス |
| ② | 設定ボタン | 設定ページを開く(ショートカット `Cmd/Ctrl + ,` |
| ③ | プロキシスイッチ | ローカルプロキシサービスの起動/停止 |
| ④ | アプリ切り替え | Claude / Codex / Gemini / OpenCode / OpenClaw を切り替え |
| ④ | アプリ切り替え | Claude / Claude Desktop / Codex / Gemini / OpenCode / OpenClaw / Hermes を切り替え |
| ⑤ | 機能エリア | Skills / Prompts / MCP の入口 |
| ⑥ | 追加ボタン | 新しいプロバイダーを追加 |
@@ -20,10 +20,12 @@
ドロップダウンメニューをクリックして、現在管理するアプリを切り替えます:
- **Claude** - Claude Code の設定を管理
- **Claude Desktop** - Claude Desktop のサードパーティプロバイダーと公式モードを管理
- **Codex** - Codex の設定を管理
- **Gemini** - Gemini CLI の設定を管理
- **OpenCode** - OpenCode の設定を管理
- **OpenClaw** - OpenClaw の設定を管理
- **Hermes** - Hermes Agent のプロバイダーと Memory を管理
切り替え後、プロバイダーリストに対応アプリの設定が表示されます。
@@ -56,6 +58,8 @@
> **ヒント**:操作ボタンエリア(⑤-⑩)はマウスホバー時に表示され、通常は非表示で画面をすっきり保ちます。
v3.15.0 から、Claude Code と Codex の一部プロバイダーカードには **Local Routing 対応バッジ**も表示されます。ローカルルーティング経由で利用できるプロバイダーを素早く判別できます。
### ボタンの詳細説明
| ボタン | 状態変化 | 説明 |
@@ -100,12 +104,12 @@ CC Switch はシステムトレイにアイコンを表示し、クイック操
| メニュー項目 | 機能 |
|--------|------|
| メインウィンドウを開く | メインウィンドウを表示してフォーカス |
| アプリサブメニュー | Claude/Codex/Gemini/OpenCode/OpenClaw ごとの折りたたみサブメニュー(例:「Claude · PackyCode」) |
| アプリサブメニュー | Claude/Codex/Gemini ごとの折りたたみサブメニュー(例:「Claude · PackyCode」)。利用可能な場合は現在のプロバイダーとキャッシュ済み使用量サマリーも表示 |
| プロバイダーリスト | 各サブメニュー内でクリックして切り替え、現在有効なものにはチェックマークを表示 |
| ライトウェイトモード | トグルチェックボックスでトレイ専用モードの開始/終了 |
| 終了 | アプリを完全に終了 |
> **注意**:各アプリのサブメニュータイトルには現在のプロバイダー名が表示されます(例:「Claude · PackyCode」)。プロバイダーが設定されていないアプリでは、無効化された「(プロバイダーなし)」エントリが表示されます。アプリ表示はアプリの表示設定で制御されます。
> **注意**:各トレイサブメニュータイトルには現在のプロバイダー名が表示されます(例:「Claude · PackyCode」)。プロバイダーが設定されていないアプリでは、無効化された「(プロバイダーなし)」エントリが表示されます。トレイは現在、プロキシルーティングと使用量サマリーに対応する Claude / Codex / Gemini にフォーカスしています。メイン画面のアプリ表示はアプリの表示設定で制御されます。
### 多言語対応
@@ -82,7 +82,7 @@ v3.13.0 より、CC Switch に **軽量モード** が追加されました —
アプリ切り替えに表示するアプリを選択します。各アプリを個別にオン/オフできますが、少なくとも 1 つは有効にする必要があります。
設定可能なアプリ:Claude、Codex、Gemini、OpenCode、OpenClaw。
設定可能なアプリ:Claude、Claude Desktop、Codex、Gemini、OpenCode、OpenClaw、Hermes
> **使用シーン**Claude Code と Codex CLI のみを使用する場合、他のアプリを非表示にしてインターフェースをシンプルに保てます。
@@ -314,19 +314,21 @@ v3.13.0 で追加された **OAuth 認証センター**(Beta)は、サード
| Gemini | 現在のバージョン、最新バージョン |
| OpenCode | 現在のバージョン、最新バージョン |
| OpenClaw | 現在のバージョン、最新バージョン |
| Hermes | 現在のバージョン、最新バージョン |
「更新」ボタンをクリックして再検出できます。
「更新」ボタンで再検出できます。更新がある場合は個別更新または「すべて更新」を利用でき、未検出のツールは個別にインストールできます。インストールと更新はバックグラウンドで静かに実行され、ボタンに進捗が表示され、完了後にバージョンが自動更新されます。
### ワンクリックインストールコマンド
### 手動インストールコマンド
CLI ツールを素早くインストール/更新するコマンドを提供:
CLI ツールを素早くインストール/更新するコマンドを提供(デフォルトで折りたたまれ、見出しをクリックで展開)
```bash
npm i -g @anthropic-ai/claude-code@latest
npm i -g @openai/codex@latest
npm i -g @google/gemini-cli@latest
npm i -g opencode@latest
npm i -g opencode-ai@latest
npm i -g openclaw@latest
python3 -m pip install --upgrade "hermes-agent[web]"
```
「コピー」ボタンでクリップボードにコピーできます。
+95 -9
View File
@@ -5,7 +5,7 @@
メイン画面右上の **+** ボタンをクリックして、プロバイダー追加パネルを開きます。
パネルは 2 つのタブに分かれています:
- **アプリ専用プロバイダー**:現在選択中のアプリ(Claude/Codex/Gemini/OpenCode/OpenClaw)専用
- **アプリ専用プロバイダー**:現在選択中のアプリ(Claude Code / Claude Desktop / Codex / Gemini / OpenCode / OpenClaw / Hermes)専用
- **統一プロバイダー**:アプリ間で共有する設定
## プリセットで追加
@@ -56,8 +56,22 @@
> ⭐ は公式パートナーを示します。プリセットリストはバージョンの更新に伴い変更される場合があります。アプリ内の実際の表示を基準にしてください。
#### Claude Desktop プリセット
Claude Desktop パネルには、Claude Code のプリセットカタログから変換されたプロバイダープリセットが含まれます。追加時には次のモードを選択できます:
- **直結モード**:プロバイダーがネイティブの Anthropic Messages API を提供し、モデル名が Claude Desktop の認識できる三つの役割 ID(`claude-sonnet-*` / `claude-opus-*` / `claude-haiku-*`)で、Claude Desktop から直接アクセスできる場合
- **モデルマッピングモード**:三つの役割 ID 以外のモデル名(旧式 Claude ID や DeepSeek / Kimi などの非 Claude モデル)を CC Switch ローカルゲートウェイ経由で Sonnet / Opus / Haiku ルートへマッピング
- **Claude Desktop Official**Claude Desktop の公式サインインモードへ戻す
詳しい手順は [2.6 Claude Desktop](./2.6-claude-desktop.md) を参照してください。
#### Codex プリセット
Codex プリセットは上流プロトコルにより 2 種類に分かれます。
**ネイティブ Responses プロトコル**(直接接続または標準プロキシ転送):
| プリセット名 | 説明 |
|----------|------|
| OpenAI 公式 | OpenAI 公式アカウントでログイン |
@@ -65,11 +79,32 @@
| AiHubMix | AiHubMix 統合サービス |
| DMXAPI | DMXAPI 中継サービス |
| PackyCode | PackyCode 中継サービス |
| Cubence | Cubence サービス |
| AIGoCode | AIGoCode サービス |
| RightCode | RightCode サービス |
| AICodeMirror | AICodeMirror サービス |
| OpenRouter | 統合ルーティングサービス |
| Cubence / AIGoCode / RightCode / AICodeMirror など | 各種中継サービス |
**Chat Completions プロトコル**(「ローカルルーティングが必要」トグルが必要。プロキシが自動変換):
| プリセット名 | 説明 |
|----------|------|
| DeepSeek | DeepSeek モデル |
| Zhipu GLM / GLM en | Zhipu AI の GLM モデル |
| Kimi | Moonshot Kimi モデル |
| MiniMax / MiniMax en | MiniMax モデル |
| StepFun / StepFun en | StepFun Step モデル |
| Baidu Qianfan Coding Plan | 百度千帆コーディングプラン |
| Bailian | Alibaba Cloud 百錬(Qwen |
| ModelScope | ModelScope コミュニティ |
| Longcat | Longcat AI |
| BaiLing | BaiLing AI |
| Xiaomi MiMo / MiMo Token Plan | Xiaomi MiMo モデル |
| Volcengine Agentplan | Volcengine Agent Plan |
| BytePlus | BytePlus サービス |
| DouBaoSeed | DouBao Seed モデル |
| SiliconFlow / SiliconFlow en | SiliconFlow |
| Novita AI | Novita AI サービス |
| Nvidia | Nvidia AI サービス |
> 💡 Chat Completions 系プリセットを選択すると、「ローカルルーティングが必要」トグルとモデルマッピング表が自動的に設定されます。詳細は下記の「Codex ローカルルーティングとモデルマッピング」セクションを参照してください。プリセット一覧は継続的に更新されます。アプリ内の表示を正としてください。
#### Gemini プリセット
@@ -161,7 +196,7 @@
3. CC Switch が設定された API Key で OpenAI 互換の `/v1/models` エンドポイントを呼び出し
4. カテゴリ別にグループ化されたドロップダウンからモデルを選択
この機能は **5 つのアプリ全対応** —— **Claude / Codex / Gemini / OpenCode / OpenClaw** のプロバイダーで利用可能で`/v1/models` エンドポイントをサポートするすべてのプロバイダーに対応します。
この機能は **Claude Code / Claude Desktop / Codex / Gemini / OpenCode / OpenClaw / Hermes** のうちモデル項目を持つプロバイダーフォームで利用でき`/v1/models` エンドポイントをサポートするプロバイダーに対応します。Codex OAuth 系プロバイダーでは、必要に応じて ChatGPT Codex バックエンドからライブモデル一覧を取得します。
**よくあるエラー:**
- **認証失敗(401/403**:API Key が正しいか確認してください
@@ -233,10 +268,13 @@ requires_openai_auth = true
| `model` | はい | 使用するモデル(例:`gpt-5.2``gpt-4o` |
| `model_reasoning_effort` | いいえ | 推論強度:`low` / `medium` / `high` |
| `disable_response_storage` | いいえ | レスポンス保存を無効にするかどうか |
| `goals` | いいえ | `[features]` 配下で `true` にすると Codex の `/goal` モードを有効化します。必要なプロバイダーでは、プロバイダー編集画面のスイッチで切り替えられます |
| `base_url` | はい | API エンドポイントアドレス |
| `wire_api` | いいえ | API プロトコルタイプ(通常 `responses` |
| `requires_openai_auth` | いいえ | OpenAI 認証方式を使用するかどうか |
API Key またはカスタムエンドポイントのプロバイダーへ切り替えた後、Codex が `/goal` を認識しているのに目標を設定できない場合は、プロバイダー編集画面の **Goal mode** スイッチを有効にしてください。CC Switch はそのプロバイダーの `~/.codex/config.toml``[features]``goals = true` を書き込みます。その後、Codex を再起動してください。Goal mode 有効化後に想定より頻繁に承認を求められる場合は、Codex の設定画面を再読み込みし、`approval_policy``sandbox_mode` が意図した権限と一致しているか確認してください。
### Gemini 設定形式
@@ -259,7 +297,7 @@ requires_openai_auth = true
## 統一プロバイダー
統一プロバイダーは Claude/Codex/Gemini/OpenCode/OpenClaw 間で設定を共有でき、複数の API 形式をサポートする中継サービスに適しています。
統一プロバイダーは Claude Code / Codex / Gemini 間で設定を共有でき、複数の API 形式をサポートする中継サービスに適しています。
### 統一プロバイダーの作成
@@ -269,7 +307,7 @@ requires_openai_auth = true
- 名前
- API Key
- エンドポイントアドレス
4. 同期するアプリにチェック(Claude/Codex/Gemini/OpenCode/OpenClaw
4. 同期するアプリにチェック(Claude Code / Codex / Gemini
5. 保存
### 同期の仕組み
@@ -403,6 +441,8 @@ Codex OAuth プリセットのデフォルトモデルマッピング:
| Opus 役割 | `gpt-5.4` |
| Haiku 役割 | `gpt-5.4-mini` |
v3.15.0 以降、Codex OAuth のモデル選択は固定リストだけに依存しません。モデルセレクターを開くと、CC Switch は必要に応じて ChatGPT Codex バックエンドから利用可能モデルを取得します。デフォルトマッピングは引き続き上書きできます。
プロバイダーの JSON エディタで `ANTHROPIC_MODEL` などの環境変数を上書きしてカスタマイズできます。
### マルチアカウント管理(OAuth 認証センター)
@@ -516,6 +556,52 @@ Claude プロバイダーの編集時、JSON エディタの上部に **クイ
また、**共通設定を書き込み** チェックボックスを有効にすると、グローバル設定スニペットをプロバイダーにマージできます。**共通設定を編集** をクリックして共有スニペットをカスタマイズできます。
### Codex ローカルルーティングとモデルマッピング
一部の第三者プロバイダーは **OpenAI Chat Completions** プロトコルのみをサポートするか、非 GPT モデル名(DeepSeek、Kimi、MiniMax など)を使用します。Codex はネイティブには OpenAI Responses API と GPT 系列モデルのみを認識するため、これらのプロバイダーでは CC Switch がローカルでプロトコルとモデルを変換する必要があります。
#### ローカルルーティングが必要
Codex プロバイダーの編集時、**ローカルルーティングが必要** トグルが利用できます:
- **有効にするタイミング**:プロバイダーが Chat Completions プロトコルを使用する、またはモデル名が Codex デフォルトの GPT 系列でない場合
- **有効時**:CC Switch のローカルプロキシが、Codex の送信する Responses リクエストを上流の Chat Completions に変換し、レスポンス(ストリーミング SSE、推論内容、ツール呼び出しを含む)を Responses 形式に再変換します
- **前提条件**:変換を有効にするには[ローカルルーティング](../4-proxy/4.1-service.md)を起動し、Codex の引き継ぎを有効にする必要があります。使用中はローカルルーティングを起動したままにしてください
> 💡 DeepSeek や Kimi などの Chat 形式プリセットを選択すると、このトグルはデフォルトで有効になっており、手動設定は不要です。
#### モデルマッピング
**ローカルルーティングが必要** を有効にすると、その下に **モデルマッピング** 表が表示され、このプロバイダーで利用可能なモデルを宣言できます:
| フィールド | 説明 |
|------|------|
| モデル ID | 上流の実際のモデル名(例:`deepseek-v4-flash` |
| 表示名 | (任意)`/model` コマンドに表示される名称 |
| コンテキストウィンドウ | (任意)モデルのコンテキスト長 |
- マッピング表は Codex の `model_catalog_json` を生成し、`/model` コマンドでこれらの第三者モデル名を表示できるようにします
- リストの内容はそのまま保存され、モデルリストの唯一の情報源となります
- 変更後、モデルリストを更新するには **Codex の再起動が必要** です(`model_catalog_json` は Codex 起動時に読み込まれます)
#### 思考能力(Reasoning)の自動判定
ローカルルーティングを有効にすると、CC Switch はプロバイダーの「思考」(reasoning)インターフェースを**自動判定**し、Codex が送る思考リクエストを上流が理解できるパラメータに変換します(**手動設定は不要**)。判定はプロバイダーの名前・エンドポイント・モデル名に基づきます:
- **集約 / ホスティングプラットフォーム優先**OpenRouter、SiliconFlow などはプラットフォーム規則で処理(同じモデルでもプラットフォームごとに思考インターフェースが全く異なる場合があるため)
- **それ以外はモデルブランド別**DeepSeek、Kimi / Moonshot、Zhipu GLM、Qwen、MiniMax、Xiaomi MiMo、StepFun などにそれぞれ規則あり
プロバイダーの「思考」能力は 2 種類に分かれます:
| 能力 | 意味 | 代表的なプロバイダー |
|------|------|----------------------|
| **思考レベル対応** | 思考の強度を調整可能(low / medium / high など) | DeepSeek、OpenRouter、StepFun`step-3.5-flash-2603` のみ) |
| **オン / オフ切替のみ** | 思考のオン / オフのみ、**レベルは無効** | Kimi、Zhipu GLM、Qwen、MiniMax、Xiaomi MiMo、SiliconFlow |
> ⚠️ **一部のプロバイダーでは思考レベルが効きません**:オン / オフ切替のみのプロバイダーでは、Codex で思考レベル(`model_reasoning_effort` の low / medium / high)を変えても**効果はありません**——CC Switch はこれらの上流にレベルを送りません(API がパラメータを受け付けず、無理に送るとリクエストが拒否される可能性があるため)。これらのプロバイダーの思考は**デフォルトでオン**で、「調整」ではなく「オン / オフ」で動作します。実際にレベル変更が効くのは、思考レベルに対応したプロバイダー(DeepSeek、OpenRouter など)だけです。
> 💡 **判定は名前 / エンドポイント / モデル名のキーワードマッチング**であり、実際の能力探索ではありません。公式ドメイン(`api.deepseek.com`、`api.moonshot.cn` など)は常に認識されますが、ドメインとモデル名を書き換えた中継サービスでは判定できないことがあり、その場合は思考パラメータが一切注入されません。
### Codex 1M コンテキストウィンドウ
Codex プロバイダーの追加時、**1M コンテキストウィンドウを有効化** トグルが利用できます:
@@ -523,7 +609,7 @@ Codex プロバイダーの追加時、**1M コンテキストウィンドウを
- **有効時**config.toml に `model_context_window = 1000000` を設定し、`model_auto_compact_token_limit = 900000` を自動入力
- **無効時**:両方のフィールドを削除
トグルがオンの場合に表示されるテキストフィールドで、自動コンパクト制限をカスタマイズできます。
トグルがオンの場合に表示されるテキストフィールドで、自動コンパクト制限をカスタマイズできます。v3.15.0 以降、このトグルは Codex プロバイダーの新規追加時のみ表示されます。既存プロバイダーの編集時は、必要に応じて高度な設定で該当フィールドを直接調整してください。
### カスタムアイコン
@@ -39,14 +39,12 @@ v3.13.0 より、トレイメニューがフラットなリストから **アプ
| Claude | Claude のすべてのプロバイダー(Codex OAuth リバースプロキシを含む) |
| Codex | Codex のすべてのプロバイダー |
| Gemini | Gemini のすべてのプロバイダー |
| OpenCode | OpenCode のすべてのプロバイダー |
| OpenClaw | OpenClaw のすべてのプロバイダー |
**リファクタリングの利点**
- **メニューのオーバーフロー防止**:プロバイダーが多数ある場合、フラットなリストでは画面の高さを超えますが、アプリ別サブメニューは自然にスケールします
- **サブメニューのタイトルに現在有効なプロバイダーを表示**:サブメニューを開かなくても、各アプリがどのプロバイダーを使用中か一目でわかります
- **アプリ別の分離**:Claude のプロバイダーを切り替えても Codex のビューには影響しません
- **サブメニューのタイトルに現在有効なプロバイダーと使用量サマリーを表示**:サブメニューを開かなくても、Claude / Codex / Gemini がどのプロバイダーを使用中か、利用可能なキャッシュ済み使用量情報とあわせて確認できます
- **アプリ別の分離**:Claude のプロバイダーを切り替えても Codex や Gemini のビューには影響しません
> **ヒント**:バックグラウンド常駐 + 軽量モード + アプリ別サブメニューの組み合わせは、複数のアプリを頻繁に切り替えるヘビーユーザーに特に適しています。[1.5 個人設定 → 軽量モード](../1-getting-started/1.5-settings.md) を参照してください。
+3 -2
View File
@@ -151,8 +151,9 @@ Claude プロバイダーの編集時、JSON エディタの上部にツール
## 保存と反映
1. 「保存」ボタンをクリック
2. 現在有効なプロバイダーの場合、設定は即座に live ファイルに書き込まれる
3. CLI ツールを再起動して反映
2. フォームが非ブロッキングな問題を検出した場合、「それでも保存」の確認が表示されます。確認すると保存できます
3. 現在有効なプロバイダーの場合、設定は即座に live ファイルに書き込まれる
4. CLI ツールを再起動して反映
## 編集のキャンセル
@@ -24,6 +24,8 @@
- 現在の設定をバックアップ
- テスト用の設定を作成
v3.15.0 以降、統一プロバイダー一覧にも複製アクションがあります。既存の統一プロバイダーをコピーしてから、有効化するアプリやモデルを調整できます。
### 操作手順
1. プロバイダーカードにマウスをホバーして操作ボタンを表示
@@ -176,18 +176,18 @@ New API タイプの中継サービス専用に設計されています:
## エクストラクターの戻り値形式
エクストラクター関数は以下のフィールドを含むオブジェクトを返す必要があります:
エクストラクター関数は以下のフィールドを含むオブジェクトを返します。すべてのフィールドは任意です:
| フィールド | 型 | 必須 | 説明 |
|------|------|------|------|
| `isValid` | boolean | いいえ | アカウントが有効かどうか、デフォルト true |
| `invalidMessage` | string | いいえ | 無効時の通知メッセージ |
| `remaining` | number | い | 残額 |
| `unit` | string | い | 単位(例:USD、CNY、回) |
| `remaining` | number | いいえ | 残額 |
| `unit` | string | いいえ | 単位(例:USD、CNY、回) |
| `planName` | string | いいえ | プラン名(複数プラン対応) |
| `total` | number | いいえ | 総額 |
| `used` | number | いいえ | 使用済み額 |
| `extra` | object | いいえ | 追加情報 |
| `extra` | string | いいえ | 追加表示テキスト |
## スクリプトのテスト
@@ -0,0 +1,306 @@
# 2.6 Claude Desktop
## 機能概要
Claude Desktop パネルでは、CC Switch 上で Claude Desktop のプロバイダー設定を管理できます。
有効にすると、次のことができます。
- Claude Desktop でサードパーティの Anthropic 互換プロバイダーを使う
- 三つの役割 ID 以外のモデルにマッピングを設定する:旧式 Claude ID(例:`claude-3-5-sonnet`)や DeepSeek / Kimi / DouBao / OpenAI / Gemini などの非 Claude モデルはいずれも必要
- Copilot / Codex OAuth のアカウント型プロバイダーを再利用する
- Claude Desktop 公式モードとサードパーティプロバイダーを切り替える
Claude Desktop と Claude Code は別々のアプリ入口です。Claude Code は `~/.claude/settings.json` を使い、Claude Desktop は専用の 3P profile 設定を使います。CC Switch 上でも「Claude」と「Claude Desktop」として別々に表示され、アイコン右下の小さなバッジで区別できます。
## 対応範囲
| 項目 | 説明 |
|------|------|
| 対応システム | macOS、Windows |
| 未対応 | Linux での Claude Desktop 3P 設定書き込み |
| 反映方法 | プロバイダー切り替え後に Claude Desktop を再起動 |
| 公式モード | Claude Desktop 内蔵サインインを使用。API Key やエンドポイント URL は不要 |
| サードパーティモード | CC Switch が管理する 3P profile に書き込み |
| MCP / Skills | Claude Desktop 3P profile は CC Switch の MCP / Skills 同期を使いません |
## クイックスタート
### ステップ 1Claude Desktop パネルへ切り替える
左側のアプリ切り替えから **Claude Desktop** を選択します。
![Claude Desktop パネル](../../assets/claude-desktop-panel-ja.png)
この入口が見つからない場合は、次を確認してください。
設定 → 一般 → ホームページ表示
Claude Desktop が非表示になっていないことを確認します。
### ステップ 2:プロバイダーをインポートまたは追加する
#### 推奨:Claude Code から一括インポート
多くのユーザーはまず Claude Code 側でプロバイダーを設定し、その同じプロバイダー群を Claude Desktop に持ち込みたいはずです。CC Switch の初回起動時、または Claude Desktop パネルを初めて開いたときにプロバイダーがまだない場合は、**Claude Code の既存プロバイダーをインポート** をクリックします。
![Claude Code からプロバイダーをインポート](../../assets/claude-desktop-import-from-claude-ja.png)
Claude Code 側に多くのプロバイダーがすでにある場合、この機能で Claude Desktop パネルへ一括インポートできます。エンドポイント URL、API Key、デフォルトモデルを一つずつ入力し直す必要がありません。
インポートルール:
- 同じ ID のプロバイダーがすでにある場合は上書きしません
- モデル名が三つの役割 ID`claude-sonnet-*` / `claude-opus-*` / `claude-haiku-*`)で直接接続できるプロバイダーは直結モードとしてインポートされます
- モデル名が三つの役割 ID でない(旧式 Claude ID を含む)、または形式変換が必要なプロバイダーは、可能な場合モデルマッピングモードとしてインポートされます
- `ANTHROPIC_DEFAULT_SONNET_MODEL``ANTHROPIC_DEFAULT_OPUS_MODEL``ANTHROPIC_DEFAULT_HAIKU_MODEL` は Desktop の Sonnet / Opus / Haiku マッピングに変換されます
- 旧形式の `[1M]` サフィックスは Claude Desktop profile の `supports1m` フラグに変換されます
- モデルマッピングを判断できないプロバイダーはスキップされます
インポート後は、各プロバイダーのモデルマッピングが実際のアップストリームモデルと合っているか確認してください。`claude-sonnet-*` / `claude-opus-*` / `claude-haiku-*` の三つの役割 ID 以外のモデル——Kimi、DeepSeek、GLM、DouBao などの非 Claude モデルや旧式 Claude ID を含む——は通常、モデルマッピングモードが必要です。
すでに Claude Code でプロバイダーを設定している場合は、まず **Claude Code の既存プロバイダーをインポート** を使ってください。Claude Desktop へ移行する最も簡単な方法です。
インポートできる設定がない場合、または Claude Desktop 専用にプロバイダーを追加したい場合は、右上の **+** ボタンをクリックします。
![Claude Desktop プロバイダーを追加](../../assets/claude-desktop-add-provider-ja.png)
選べる方法:
- **プリセットプロバイダー**:内蔵の Claude Desktop プリセットから選び、API Key だけ入力する
- **カスタム設定**:名前、エンドポイント URL、API Key、モデル設定を手動入力する
- **Claude Desktop Official**Claude Desktop の公式サインインモードへ戻す
Claude Desktop の三つの役割 ID`claude-sonnet-*` / `claude-opus-*` / `claude-haiku-*`)をすでに受け付けるネイティブ Anthropic Messages API プロバイダーでは、基本的に次の手順だけで十分です。
1. プリセットまたはカスタムプロバイダーを選ぶ
2. **API Key** を入力する
3. **API エンドポイント** を確認する
4. **モデルマッピングが必要** をオフのままにする
5. **追加** をクリックする
### ステップ 3:切り替えて Claude Desktop を再起動する
プロバイダーカードで **有効化** をクリックします。
切り替え後:
- 直結プロバイダー:Claude Desktop を再起動すると反映されます
- ルーティングが必要なプロバイダー:CC Switch を起動したまま、Claude Desktop ローカルルーティングをオンにし、Claude Desktop を再起動します
> 注意:Claude Desktop は Claude Code のように設定をホットリロードしません。プロバイダーを切り替えるたびに、Claude Desktop を完全に終了して再度開く必要があります。
## 2 つの動作モード
### 直結モード
直結モードは、プロバイダー自身が Anthropic Messages API を提供しており、Claude Desktop から直接アクセスできる場合に適しています。
直結モードでは、CC Switch が Claude Desktop の 3P profile をプロバイダーのエンドポイントへ向けます。
```json
{
"inferenceProvider": "gateway",
"inferenceGatewayBaseUrl": "https://api.example.com",
"inferenceGatewayAuthScheme": "bearer",
"inferenceGatewayApiKey": "your API key"
}
```
適したケース:
- プロバイダーがネイティブの Anthropic Messages API を公開している
- モデル ID が Claude Desktop の認識できる役割名:`claude-sonnet-*``claude-opus-*``claude-haiku-*`(または `anthropic/claude-` 接頭辞の同種名)
- 形式変換が不要
- 使用中に CC Switch のローカルルーティングを起動し続ける必要がない
直結モードの「Claude Desktop モデルを手動指定」は高度な任意設定です。多くのネイティブ Claude モデルプロバイダーでは不要で、Claude Desktop が `/v1/models` を自動取得します。
プロバイダーの `/v1/models` が使えない、または返されるモデル名を Claude Desktop が認識できない場合だけ手動で追加してください。手動で入力するモデル名は `claude-sonnet-*``claude-opus-*``claude-haiku-*` の形式である必要があります(`claude-3-5-sonnet-…` のような旧式 ID は拒否されます)。
### モデルマッピングモード
モデルマッピングモードは、プロバイダーのモデルが `claude-sonnet-*` / `claude-opus-*` / `claude-haiku-*` の三つの役割 ID でない場合(旧式 Claude ID や DeepSeek、Kimi などの非 Claude モデルを含む)、または CC Switch による API 形式変換が必要な場合に適しています。
**モデルマッピングが必要** をオンにすると、Claude Desktop は CC Switch のローカルゲートウェイへ接続します。
```text
http://127.0.0.1:15721/claude-desktop
```
CC Switch は次を担当します。
1. Claude Desktop に安全な Claude モデルルートを公開する
2. Desktop で選択したモデル役割を実際のアップストリームモデルへマッピングする
3. プロバイダーに合わせて Anthropic / OpenAI / Gemini のリクエスト形式を変換する
4. CC Switch に保存されたプロバイダー認証情報でアップストリームへアクセスする
対応 API 形式:
| 形式 | 用途 |
|------|------|
| Anthropic Messages | ネイティブまたは互換 Anthropic リクエスト |
| OpenAI Chat Completions | OpenAI 互換 `/chat/completions` |
| OpenAI Responses API | OpenAI Responses 互換エンドポイント |
| Gemini Native generateContent | Gemini ネイティブ API |
モデルマッピングモードでは、Claude Desktop から見えるのは `claude-sonnet-*` / `claude-opus-*` / `claude-haiku-*` の 3 種類の役割ルートだけです。実際のアップストリームモデル名は Claude Desktop profile に直接書き込まれません。
## モデルマッピングを設定する
### フィールド説明
| フィールド | 説明 |
|------------|------|
| モデル役割 | Claude Desktop が認識できる Sonnet / Opus / Haiku ルート |
| メニュー表示名 | Claude Desktop のモデルメニューに表示される名前 |
| リクエストモデル | プロバイダーへ送信する実際のアップストリームモデル ID |
| 1M | Claude Desktop に 1M コンテキスト対応を宣言 |
![Claude Desktop モデルマッピング](../../assets/claude-desktop-model-mapping-rows-ja.png)
### 推奨設定
Kimi を使う場合:
| モデル役割 | メニュー表示名 | リクエストモデル | 1M |
|------------|----------------|------------------|----|
| Sonnet | Kimi K2 | `kimi-k2` | プロバイダー能力に合わせる |
DeepSeek を使う場合:
| モデル役割 | メニュー表示名 | リクエストモデル | 1M |
|------------|----------------|------------------|----|
| Sonnet | DeepSeek V4 Pro | `deepseek-v4-pro` | プロバイダー能力に合わせる |
理由は、現在の Claude Desktop が Sonnet / Opus / Haiku の役割ファミリー以外のモデルを拒否するためです。そのため CC Switch のルーティング機能で一度モデルマッピングを行います。
### 複数役割のマッピング
Sonnet、Opus、Haiku の 3 つを同時に設定できます。
| モデル役割 | 推奨用途 |
|------------|----------|
| Sonnet | デフォルトの主力モデル |
| Opus | 高品質または複雑なタスク |
| Haiku | 高速・低コストモデル |
プロバイダーにモデルが 1 つしかない場合は、1 つの役割のリクエストモデルだけ入力すれば十分です。空欄の役割は最初に入力したモデル(Sonnet 優先)を自動的に引き継ぐため、サブ agent が呼び出す Haiku なども常に利用できます。モデルマッピングモードでは少なくとも 1 つのリクエストモデルが必要です。
## ローカルルーティング切り替え
モデルマッピングモードでは、リクエスト変換のために CC Switch ローカルルーティングが必要です。ローカルルーティングは強力ですが少し複雑な機能でもあるため、ルーティングを必要としないユーザーの誤操作を避けるために、メインページのルーティング切り替えはデフォルトで非表示です。必要なときだけ手動で表示してください。
開き方:
設定 → ルーティング → ローカルルーティング → **メインページにルーティング切り替えを表示** をオン
![ローカルルーティング切り替えを表示](../../assets/local-routing-display-setting-ja.png)
表示スイッチをオンにしたら Claude Desktop パネルへ戻ります。メインページ右上に Claude Desktop ローカルルーティング切り替えが表示されます。
![Claude Desktop ローカルルーティング切り替え](../../assets/claude-desktop-route-toggle-context-ja.png)
状態説明:
| 状態 | 説明 |
|------|------|
| オン | ローカルゲートウェイが起動中。通常は `127.0.0.1:15721` |
| オフ | 直結プロバイダーは利用可能。モデルマッピングプロバイダーは正常に動作しません |
| 読み込み中 | ルーティングサービスの起動または停止中 |
**モデルマッピングが必要** なプロバイダーだけがローカルルーティングに依存します。直結プロバイダーではこの切り替えは不要です。
他のアプリがプロキシ接管を使用している場合、ローカルルーティングの停止がブロックされることがあります。先にルーティングサービス設定で該当アプリの接管をオフにしてから、ローカルルーティングを停止してください。
## 公式 Claude Desktop に戻す
Claude Desktop の公式サインインへ戻す場合:
1. **Claude Desktop Official** を選択する
2. **有効化** をクリックする
3. Claude Desktop を再起動する
CC Switch は Claude Desktop の公式 1P モードを復元し、CC Switch が管理する 3P profile を削除します。
公式モードでは API Key もローカルルーティングも不要です。
Claude Code からプロバイダーをインポートするとき、CC Switch は自動的に **Claude Desktop Official** も追加します。
## 設定ファイルの場所
CC Switch は Claude Desktop の 3P 設定ディレクトリに書き込みます。
### macOS
```text
~/Library/Application Support/Claude/claude_desktop_config.json
~/Library/Application Support/Claude-3p/claude_desktop_config.json
~/Library/Application Support/Claude-3p/configLibrary/_meta.json
~/Library/Application Support/Claude-3p/configLibrary/00000000-0000-4000-8000-000000157210.json
```
### Windows
```text
%LOCALAPPDATA%\Claude\claude_desktop_config.json
%LOCALAPPDATA%\Claude-3p\claude_desktop_config.json
%LOCALAPPDATA%\Claude-3p\configLibrary\_meta.json
%LOCALAPPDATA%\Claude-3p\configLibrary\00000000-0000-4000-8000-000000157210.json
```
これらのファイルは CC Switch が自動管理します。手動編集はおすすめしません。設定の不整合が起きた場合は、現在のプロバイダーを再度有効化すると通常は修復できます。
## ステータス表示と対処
Claude Desktop パネル上部に「Claude Desktop 設定の確認が必要です」と表示されることがあります。
| 表示 | 対処方法 |
|------|----------|
| 現在のプラットフォームは未対応 | 3P 設定の書き込みは現在 macOS / Windows のみ対応 |
| profile に Sonnet / Opus / Haiku の役割ファミリー以外のモデル名がある | 現在のプロバイダーへ再度切り替える、またはモデルマッピングを使うよう編集する |
| モデルマッピングが有効だが有効なルートがない | プロバイダーを編集し、少なくとも 1 件のモデルマッピングを追加する |
| ローカルルーティング token が未生成 | そのプロバイダーへ再度切り替えると、CC Switch が新しい token を書き込みます |
| profile の URL が現在のプロバイダーと一致しない | 現在のプロバイダーへ再度切り替え、profile を正しい URL に戻します |
## よくある質問
### 切り替え成功と表示されたのに Claude Desktop が変わらない?
Claude Desktop を完全に終了して再起動してください。Claude Desktop は通常、起動時に 3P profile を読み込み、切り替え後に自動でホットリロードしません。
### モデルマッピングプロバイダーのリクエストが失敗する?
次を確認してください。
- CC Switch が起動したままになっている
- Claude Desktop ローカルルーティングがオンになっている
- プロバイダーの API Key とエンドポイント URL が正しい
- モデルマッピングにリクエストモデルが入力されている
- プロバイダー切り替え後に Claude Desktop を再起動した
### Claude Desktop のモデルメニューにブランド名が表示されない?
プロバイダーを編集し、モデルマッピングの **メニュー表示名** を入力してください。その後、プロバイダーを再度有効化し、Claude Desktop を再起動します。
### 直結モードでエラーになるのはなぜ?
直結モードでは、プロバイダーがネイティブの Anthropic Messages API を提供し、Claude Desktop の三つの役割 ID`claude-sonnet-*` / `claude-opus-*` / `claude-haiku-*`)を受け入れる必要があります。プロバイダーが OpenAI、Gemini、非 Claude モデル ID、または旧式 Claude ID(例:`claude-3-5-sonnet-…`)など三つの役割 ID 以外を使う場合は失敗するため、**モデルマッピングが必要** をオンにしてください。
### CC Switch を閉じてもよい?
モードによります。
- 直結モード:Claude Desktop が再起動して設定を読み込んだ後は、ローカルルーティングを起動し続ける必要はありません
- モデルマッピングモード:CC Switch を起動したままにし、Claude Desktop ローカルルーティングもオンにしておく必要があります
### 実際のアップストリームモデル名は Claude Desktop に書き込まれる?
モデルマッピングモードでは書き込まれません。Claude Desktop profile には安全な Sonnet / Opus / Haiku 役割ルートと表示名だけが保存されます。実際のアップストリームモデル名は CC Switch のプロバイダー設定に保存され、ローカルゲートウェイを通るリクエスト時にマッピングされます。
## 次のステップ
- [プロバイダーの追加](./2.1-add.md)
- [プロバイダーの切り替え](./2.2-switch.md)
- [プロキシサービス](../4-proxy/4.1-service.md)
- [アプリケーション接管](../4-proxy/4.2-routing.md)
@@ -11,12 +11,13 @@
| OpenCode | `~/.local/share/opencode/`JSON または SQLite |
| OpenClaw | `~/.openclaw/agents/<agent>/sessions/*.jsonl` |
| Gemini CLI | `~/.cache/gemini/tmp/<project_hash>/chats/` |
| Hermes | `~/.hermes/state.db` または `~/.hermes/sessions/*.jsonl` |
## セッションマネージャーを開く
メインナビゲーションバーの **セッション** ボタンをクリックします。
> **注意**:セッションボタンは対応する 5 つのアプリすべてで表示されます。
> **注意**:セッションマネージャーは上表の 6 種類のセッションソースを対象にします。Claude Desktop 入口では Claude Code のセッションビューを再利用します。
## インターフェースのレイアウト
@@ -63,6 +64,7 @@
- **OpenCode**
- **OpenClaw**
- **Gemini CLI**
- **Hermes**
フィルターは検索と組み合わせて使用できます。
@@ -81,7 +83,7 @@
- ターミナルはセッションのプロジェクトディレクトリで開きます
- ターミナルの起動に失敗した場合、コマンドがクリップボードにコピーされます
**対応ターミナル(macOS):** Terminal.app、iTerm2、Ghostty、Kitty、WezTerm、Alacritty
**対応ターミナル(macOS):** Terminal.app、iTerm2、Ghostty、Kitty、WezTerm、Alacritty、Warp
**その他のプラットフォーム:**
- 再開コマンドがクリップボードにコピーされます
@@ -103,7 +105,7 @@ v3.13.0 より、**Claude セッション** の再開前に **ディレクトリ
2. 表示されるディレクトリピッカーで、デフォルトのディレクトリを確認するか、新しいディレクトリを選択
3. CC Switch が選択したディレクトリで Claude ターミナルセッションを起動します
> **ヒント**Codex / Gemini / OpenCode / OpenClaw のセッション再開フローには現在ディレクトリピッカーは含まれず、セッション元のプロジェクトディレクトリを使用します。
> **ヒント**Codex / Gemini / OpenCode / OpenClaw / Hermes のセッション再開フローには現在ディレクトリピッカーは含まれず、セッション元のプロジェクトディレクトリを使用します。
### セッションの削除
+8 -1
View File
@@ -50,10 +50,15 @@ v3.13.0 より、使用量データの取得元は 2 つあります:
| 指標 | 説明 |
|------|------|
| 総リクエスト数 | 統計期間内のリクエスト総数 |
| Token | 入力 + 出力 Token の合計 |
| 実消費 Token | 入力 + 出力 + キャッシュ作成 + キャッシュ読取をキャッシュ正規化した合計 |
| キャッシュヒット率 | キャッシュ可能な入力に対するキャッシュ読取 Token の割合 |
| 推定費用 | 料金設定に基づいて計算された費用 |
| 成功率 | 成功したリクエストの割合 |
v3.15.0 以降、使用量ページ上部はフィルター連動の Hero カードになりました。日付範囲、アプリ、プロバイダー、モデルフィルターを変更すると、Hero の実消費 Token、キャッシュヒット率、リクエスト数、費用が同時に更新され、下部のログや統計一覧と整合します。
> 注意:v3.15.0 ではキャッシュ読取、キャッシュ作成、OpenAI 系プロトコルのキャッシュ報告方式を正規化しています。過去の Token や費用の数値は旧バージョンの推定値と一致しない場合があります。現在の数値は正規化後のルールに基づきます。
### 期間
統計の期間を選択できます:
@@ -238,6 +243,8 @@ CC Switch は一般的なモデルの公式価格(100 万 Token あたり)
| モデル | 入力 | 出力 | キャッシュ読取 | キャッシュ作成 |
|------|------|------|----------|----------|
| **Claude 4.8 シリーズ** | | | | |
| claude-opus-4-8 | $5 | $25 | $0.50 | $6.25 |
| **Claude 4.5 シリーズ** | | | | |
| claude-opus-4-5 | $5 | $25 | $0.50 | $6.25 |
| claude-sonnet-4-5 | $3 | $15 | $0.30 | $3.75 |
@@ -10,7 +10,9 @@
- 応答レイテンシが正常か
- ストリーミングレスポンスの初回トークン時間(TTFB)
v3.13.0 より、Stream Check の対応範囲が **5 つのアプリ全対応**Claude / Codex / Gemini / OpenCode / OpenClawに拡張され、OpenClaw の全プロトコルバリアント(`openai-completions` など)も含まれます。OpenCode は npm パッケージマッピングで自動識別、OpenClaw はカスタム `auth-header` 検出、Bedrock エラーメッセージ、`baseURL` フォールバックなどのエッジケースにも対応しています。
v3.13.0 より、Stream Check の対応範囲が **Claude / Codex / Gemini / OpenCode / OpenClaw** に拡張され、OpenClaw の全プロトコルバリアント(`openai-completions` など)も含まれます。OpenCode は npm パッケージマッピングで自動識別、OpenClaw はカスタム `auth-header` 検出、Bedrock エラーメッセージ、`baseURL` フォールバックなどのエッジケースにも対応しています。
Chat Completions プロトコルを使用する Codex 第三者プロバイダー(DeepSeek、Kimi、MiniMax など)の場合、Stream Check は `/responses` ではなく `/chat/completions` エンドポイントをプローブし、実際のプロキシ転送パスと URL フォールバック順序を一致させます(origin-only アドレスは `/v1/...` を優先)。これにより、使用可能なプロバイダーが誤って利用不可と判定されることを防ぎます。
## 設定を開く
+17 -8
View File
@@ -1,6 +1,6 @@
# CC Switch ユーザーマニュアル
> Claude Code / Codex / Gemini CLI / OpenCode / OpenClaw オールインワンアシスタント
> Claude Code / Claude Desktop / Codex / Gemini CLI / OpenCode / OpenClaw / Hermes オールインワンアシスタント
## 目次構成
@@ -19,7 +19,8 @@ CC Switch ユーザーマニュアル
│ ├── 2.2 プロバイダーの切り替え
│ ├── 2.3 プロバイダーの編集
│ ├── 2.4 並べ替えと複製
── 2.5 使用量クエリ
── 2.5 使用量クエリ
│ └── 2.6 Claude Desktop
├── 3. 拡張機能
│ ├── 3.1 MCP サーバー管理
@@ -63,6 +64,7 @@ CC Switch ユーザーマニュアル
| [2.3-edit.md](./2-providers/2.3-edit.md) | 設定の編集、API Key の変更、バックフィル機能 |
| [2.4-sort-duplicate.md](./2-providers/2.4-sort-duplicate.md) | ドラッグで並べ替え、プロバイダーの複製、削除 |
| [2.5-usage-query.md](./2-providers/2.5-usage-query.md) | 使用量クエリ、残額表示、複数プラン表示 |
| [2.6-claude-desktop.md](./2-providers/2.6-claude-desktop.md) | Claude Desktop サードパーティプロバイダー、直結モード、モデルマッピング |
### 3. 拡張機能
@@ -98,24 +100,31 @@ CC Switch ユーザーマニュアル
- **初めての方**[1.1 ソフトウェア紹介](./1-getting-started/1.1-introduction.md) からお読みください
- **インストールの問題**[1.2 インストールガイド](./1-getting-started/1.2-installation.md) をご確認ください
- **プロバイダーの設定**[2.1 プロバイダーの追加](./2-providers/2.1-add.md) をご確認ください
- **Claude Desktop の利用**[2.6 Claude Desktop](./2-providers/2.6-claude-desktop.md) をご確認ください
- **プロキシの使用**[4.1 プロキシサービス](./4-proxy/4.1-service.md) をご確認ください
- **お困りの方**[5.2 FAQ](./5-faq/5.2-questions.md) をご確認ください
## バージョン情報
- ドキュメントバージョン:v3.13.0
- 最終更新:2026-04-08
- CC Switch v3.13.0+ 対応
- ドキュメントバージョン:v3.15.0
- 最終更新:2026-05-16
- CC Switch v3.15.0+ 対応
### v3.13.0 の注目機能
### v3.15.0 の注目機能
- **Claude Desktop の一等管理パネル**:サードパーティプロバイダー、直結 / モデルマッピングの 2 モード、Copilot / Codex OAuth 再利用、3P profile 書き込みに対応 — 詳細は [2.6 Claude Desktop](./2-providers/2.6-claude-desktop.md)
- **役割別モデルマッピング**Sonnet / Opus / Haiku ルートと `supports1m` フラグで Claude Desktop のモデル検証に対応
- **Claude Desktop ローカルルーティング**:変換が必要なプロバイダー向けに `127.0.0.1:15721/claude-desktop` のローカルゲートウェイを提供
- **ルーティング対応バッジ**Claude Code / Codex のプロバイダーカードで Local Routing 対応可否を確認可能
- **Codex OAuth ライブモデル検出**ChatGPT Codex 系プロバイダーは必要に応じて ChatGPT バックエンドから利用可能モデルを取得
- **フィルター連動 Usage Hero**:キャッシュ正規化後の実消費 Token とキャッシュヒット率を表示し、日付 / プロバイダー / モデルフィルターに追従 — 詳細は [4.4 使用量統計](./4-proxy/4.4-usage.md)
- **軽量モード**:トレイへ最小化時にメインウィンドウを破棄、アイドル時のリソース使用量をほぼゼロに — 詳細は [1.5 個人設定](./1-getting-started/1.5-settings.md)
- **クォータ・残高表示**:公式サブスクリプション系(Claude/Codex/Gemini/Copilot/Codex OAuth)はカードに自動表示、Token Plan および第三者残高は内蔵テンプレートでワンクリック有効化 — 詳細は [2.5 使用量クエリ](./2-providers/2.5-usage-query.md)
- **Codex OAuth リバースプロキシ**ChatGPT アカウントで Claude Code 内から Codex サービスを再利用 — 詳細は [2.1 プロバイダーの追加](./2-providers/2.1-add.md)
- **アプリ別トレイサブメニュー**5 アプリ独立サブメニュー、メニューのオーバーフローを防止 — 詳細は [2.2 プロバイダーの切り替え](./2-providers/2.2-switch.md)
- **アプリ別トレイサブメニュー**Claude / Codex / Gemini のサブメニューで現在のプロバイダーと使用量サマリーを確認可能 — 詳細は [2.2 プロバイダーの切り替え](./2-providers/2.2-switch.md)
- **Skills の発見と一括更新**:SHA-256 ハッシュによる更新検出、一括更新、skills.sh 公式レジストリ検索 — 詳細は [3.3 Skills スキル管理](./3-extensions/3.3-skills.md)
- **完全URLエンドポイントモード**:高度なオプションで `base_url` を完全なアップストリームエンドポイントとして扱う — 詳細は [2.1 プロバイダーの追加](./2-providers/2.1-add.md)
- **OpenCode / OpenClaw ストリームチェック完全対応**Stream Check パネルを 5 アプリ全対応に拡張 — 詳細は [4.5 モデルテスト](./4-proxy/4.5-model-test.md)
- **OpenCode / OpenClaw ストリームチェック対応**Stream Check は Claude / Codex / Gemini / OpenCode / OpenClaw をカバー — 詳細は [4.5 モデルテスト](./4-proxy/4.5-model-test.md)
## コントリビュート
@@ -2,14 +2,14 @@
## 什么是 CC Switch
CC Switch 是一款跨平台桌面应用,专为使用 AI 编程工具的开发者设计。它帮助你统一管理 **Claude Code**、**Codex**、**Gemini CLI**、**OpenCode****OpenClaw** 五大 AI 编程工具的配置。
CC Switch 是一款跨平台桌面应用,专为使用 AI 编程工具的开发者设计。它帮助你统一管理 **Claude Code**、**Claude Desktop**、**Codex**、**Gemini CLI**、**OpenCode****OpenClaw** 和 **Hermes** 等受管应用的配置。
## 解决什么问题
在日常开发中,你可能会遇到这些痛点:
- **多供应商切换麻烦**:使用不同的 API 供应商(官方、中转服务商),需要手动修改配置文件
- **配置分散难管理**Claude、Codex、Gemini、OpenCode、OpenClaw 各有独立的配置文件,格式不同
- **配置分散难管理**Claude Code、Claude Desktop、Codex、Gemini、OpenCode、OpenClaw、Hermes 各有独立的配置文件,格式不同
- **无法监控用量**:不知道 API 调用了多少次,花了多少钱
- **服务不稳定**:单一供应商出问题时,整个工作流中断
@@ -21,6 +21,7 @@ CC Switch 通过统一的界面解决这些问题。
- 一键切换多个 API 供应商配置
- 支持预设模板,快速添加常用供应商
- 统一供应商功能,跨应用共享配置
- Claude Desktop 第三方供应商、直连模式与模型映射
- 用量查询与余额显示
- 端点速度测试
@@ -40,16 +41,18 @@ CC Switch 通过统一的界面解决这些问题。
| 应用 | 说明 |
|------|------|
| **Claude Code** | Anthropic 官方的 AI 编程助手 |
| **Claude Desktop** | Claude 桌面应用,支持官方登录与第三方 3P profile |
| **Codex** | OpenAI 的代码生成工具 |
| **Gemini CLI** | Google 的 AI 命令行工具 |
| **OpenCode** | 开源 AI 编程终端工具 |
| **OpenClaw** | 开源 AI 编程助手(多供应商网关) |
| **Hermes** | Hermes Agent,支持供应商、MCP、Skills 和 Memory 管理 |
## 支持的平台
- **Windows** 10 及以上
- **macOS** 10.15 (Catalina) 及以上
- **Linux** Ubuntu 22.04+ / Debian 11+ / Fedora 34+
- **macOS** 12 (Monterey) 及以上
- **Linux** Ubuntu 22.04+ / Debian 11+ / Fedora 34+x64 / ARM64
## 技术架构
@@ -1,5 +1,15 @@
# 1.2 安装指南
## 官方渠道与系统要求
请只从 **[ccswitch.io](https://ccswitch.io)**、**[GitHub Releases](https://github.com/farion1231/cc-switch/releases)** 或项目源码仓库获取 CC Switch。任何要求付费、充值或索取登录凭据的“CC Switch”网站或客户端都不是官方渠道。
| 系统 | 最低版本 | 架构 |
|------|----------|------|
| Windows | Windows 10 及以上 | x64 |
| macOS | macOS 12 (Monterey) 及以上 | Intel (x64) / Apple Silicon (arm64) |
| Linux | 见下方发行版说明 | x64 / ARM64 |
## 前置要求
### 安装 Node.js
@@ -115,6 +125,8 @@ npm install -g @google/gemini-cli --registry=https://registry.npmmirror.com
3. 双击运行安装程序
4. 按提示完成安装
注意:运行安装程序后如果没有任何反应,可以在文件上点击右键,在弹出的菜单中打开 `属性``常规`页中的 `安全` 勾选 `解除锁定`
### 绿色版(免安装)
1. 下载 `CC-Switch-v{版本号}-Windows-Portable.zip`
@@ -141,8 +153,8 @@ brew upgrade --cask cc-switch
### 方式二:手动下载
1. 下载 `CC-Switch-v{版本号}-macOS.zip`
2. 解压得到 `CC Switch.app`
1. 下载 `CC-Switch-v{版本号}-macOS.dmg`(推荐)或 `CC-Switch-v{版本号}-macOS.zip`
2. 打开 DMG,或解压 zip 得到 `CC Switch.app`
3. 拖动到「应用程序」文件夹
### 已签名并公证
@@ -165,11 +177,11 @@ yay -S cc-switch-bin
### Debian / Ubuntu
1. 下载 `CC-Switch-v{版本号}-Linux.deb`
1. 根据架构下载 `CC-Switch-v{版本号}-Linux-x86_64.deb``CC-Switch-v{版本号}-Linux-arm64.deb`
2. 安装:
```bash
sudo dpkg -i CC-Switch-v{版本号}-Linux.deb
sudo dpkg -i CC-Switch-v{版本号}-Linux-*.deb
# 如果有依赖问题
sudo apt-get install -f
@@ -177,17 +189,17 @@ sudo apt-get install -f
### AppImage(通用)
1. 下载 `CC-Switch-v{版本号}-Linux.AppImage`
1. 根据架构下载 `CC-Switch-v{版本号}-Linux-x86_64.AppImage``CC-Switch-v{版本号}-Linux-arm64.AppImage`
2. 添加执行权限:
```bash
chmod +x CC-Switch-v{版本号}-Linux.AppImage
chmod +x CC-Switch-v{版本号}-Linux-*.AppImage
```
3. 运行:
```bash
./CC-Switch-v{版本号}-Linux.AppImage
./CC-Switch-v{版本号}-Linux-*.AppImage
```
## 验证安装
@@ -196,7 +208,7 @@ chmod +x CC-Switch-v{版本号}-Linux.AppImage
1. 应用窗口正常显示
2. 系统托盘出现 CC Switch 图标
3. 能够切换 Claude / Codex / Gemini 三个应用
3. 应用切换器中能看到已启用的受管应用,并能切换到目标应用面板
## 自动更新
@@ -11,7 +11,7 @@
| ① | Logo | 点击访问 GitHub 项目页 |
| ② | 设置按钮 | 打开设置页面(快捷键 `Cmd/Ctrl + ,` |
| ③ | 代理开关 | 启动/停止本地代理服务 |
| ④ | 应用切换器 | 切换 Claude / Codex / Gemini / OpenCode / OpenClaw |
| ④ | 应用切换器 | 切换 Claude / Claude Desktop / Codex / Gemini / OpenCode / OpenClaw / Hermes |
| ⑤ | 功能区 | Skills / Prompts / MCP 入口 |
| ⑥ | 添加按钮 | 添加新供应商 |
@@ -20,10 +20,12 @@
点击下拉菜单切换当前管理的应用:
- **Claude** - 管理 Claude Code 配置
- **Claude Desktop** - 管理 Claude Desktop 第三方供应商与官方模式
- **Codex** - 管理 Codex 配置
- **Gemini** - 管理 Gemini CLI 配置
- **OpenCode** - 管理 OpenCode 配置
- **OpenClaw** - 管理 OpenClaw 配置
- **Hermes** - 管理 Hermes Agent 供应商与 Memory
切换后,供应商列表会显示对应应用的配置。
@@ -56,6 +58,8 @@
> 💡 **提示**:操作按钮区域(⑤-⑩)在鼠标悬停时显示,平时隐藏以保持界面简洁。
v3.15.0 起,Claude Code 与 Codex 的部分供应商卡片还会显示 **Local Routing 支持徽章**,用于快速判断该供应商是否适合通过本地路由转发。
### 按钮详细说明
| 按钮 | 状态变化 | 说明 |
@@ -100,12 +104,12 @@ CC Switch 在系统托盘显示图标,提供快速操作入口。
| 菜单项 | 功能 |
|--------|------|
| 打开主界面 | 显示主窗口并聚焦 |
| 应用子菜单 | 按 Claude/Codex/Gemini/OpenCode/OpenClaw 分组的折叠子菜单(如 "Claude · PackyCode" |
| 应用子菜单 | 按 Claude/Codex/Gemini 分组的折叠子菜单(如 "Claude · PackyCode",可显示当前供应商与缓存用量摘要 |
| 供应商列表 | 在每个子菜单内,点击切换,当前启用的显示勾选标记 |
| 轻量模式 | 勾选框切换,进入/退出仅托盘运行模式 |
| 退出 | 完全退出应用 |
> **注意**:每个应用子菜单的标题会显示当前供应商名称(如 "Claude · PackyCode")。没有配置供应商的应用会显示禁用的"(无供应商)"条目。应用可见性由设置中的"应用可见性"选项控制。
> **注意**:每个托盘子菜单的标题会显示当前供应商名称(如 "Claude · PackyCode")。没有配置供应商的应用会显示禁用的"(无供应商)"条目。托盘目前聚焦 Claude / Codex / Gemini 三个可代理且可统计用量的应用;主界面应用可见性由设置中的"应用可见性"选项控制。
### 多语言支持
@@ -82,7 +82,7 @@ v3.13.0 起新增「轻量模式」——一种**仅托盘运行**的状态,
选择在应用切换器中显示哪些应用。每个应用可以独立开关,但至少保留一个。
可配置的应用:Claude、Codex、Gemini、OpenCode、OpenClaw。
可配置的应用:Claude、Claude Desktop、Codex、Gemini、OpenCode、OpenClaw、Hermes
> 💡 **使用场景**:如果你只使用 Claude Code 和 Codex CLI,可以隐藏其他应用,保持界面简洁。
@@ -314,19 +314,21 @@ v3.13.0 新增的 **OAuth 认证中心**Beta)统一管理第三方 OAuth
| Gemini | 当前版本、最新版本 |
| OpenCode | 当前版本、最新版本 |
| OpenClaw | 当前版本、最新版本 |
| Hermes | 当前版本、最新版本 |
点击「刷新」按钮可重新检测。
点击「刷新」按钮可重新检测;检测到新版时可单独升级,也可以点击「全部升级」。未检测到的工具会显示安装按钮。安装与升级在后台静默执行,按钮上会显示进度,完成后自动刷新版本
### 一键安装命令
### 手动安装命令
提供快速安装/更新 CLI 工具的命令:
提供快速安装/升级 CLI 工具的命令(该区域默认折叠,点击标题展开)
```bash
npm i -g @anthropic-ai/claude-code@latest
npm i -g @openai/codex@latest
npm i -g @google/gemini-cli@latest
npm i -g opencode@latest
npm i -g opencode-ai@latest
npm i -g openclaw@latest
python3 -m pip install --upgrade "hermes-agent[web]"
```
点击「复制」按钮可复制到剪贴板。
+95 -9
View File
@@ -5,7 +5,7 @@
点击主界面右上角的 **+** 按钮,打开添加供应商面板。
面板分为两个 Tab
- **应用专属供应商**:仅用于当前选中的应用(Claude/Codex/Gemini/OpenCode/OpenClaw
- **应用专属供应商**:仅用于当前选中的应用(Claude Code / Claude Desktop / Codex / Gemini / OpenCode / OpenClaw / Hermes
- **统一供应商**:跨应用共享的配置
## 使用预设添加
@@ -56,8 +56,22 @@
> ⭐ 标注为官方合作伙伴。预设列表可能随版本更新,以应用内实际显示为准。
#### Claude Desktop 预设
Claude Desktop 面板内置从 Claude Code 预设目录转换而来的供应商预设。添加时可选择:
- **直连模式**:供应商原生支持 Anthropic Messages API,且模型名是 Claude Desktop 可识别的三档角色 ID(`claude-sonnet-*` / `claude-opus-*` / `claude-haiku-*`),Claude Desktop 可直接访问
- **模型映射模式**:模型名非三档角色 ID(旧式 Claude ID、或 DeepSeek / Kimi 等非 Claude 模型)通过 CC Switch 本地网关映射为 Sonnet / Opus / Haiku 路由
- **Claude Desktop Official**:恢复 Claude Desktop 官方登录模式
完整操作请参阅 [2.6 Claude Desktop](./2.6-claude-desktop.md)。
#### Codex 预设
Codex 预设按上游协议分两类。
**原生 Responses 协议**(可直连或经标准代理转发):
| 预设名称 | 说明 |
|----------|------|
| OpenAI 官方 | 使用 OpenAI 官方账号登录 |
@@ -65,11 +79,32 @@
| AiHubMix | AiHubMix 聚合服务 |
| DMXAPI | DMXAPI 中转服务 |
| PackyCode | PackyCode 中转服务 |
| Cubence | Cubence 服务 |
| AIGoCode | AIGoCode 服务 |
| RightCode | RightCode 服务 |
| AICodeMirror | AICodeMirror 服务 |
| OpenRouter | 聚合路由服务 |
| Cubence / AIGoCode / RightCode / AICodeMirror 等 | 各类中转服务 |
**Chat Completions 协议**(需开启「需要本地路由映射」,由代理自动转换):
| 预设名称 | 说明 |
|----------|------|
| DeepSeek | DeepSeek 模型 |
| 智谱 GLM / GLM en | 智谱 AI 的 GLM 模型 |
| Kimi | Moonshot Kimi 模型 |
| MiniMax / MiniMax en | MiniMax 模型 |
| StepFun / StepFun en | 阶跃星辰 Step 模型 |
| 百度千帆 Coding Plan | 百度千帆编程套餐 |
| 百炼 | 阿里云百炼(通义千问) |
| ModelScope | 魔搭社区 |
| Longcat | Longcat AI |
| 百灵 (BaiLing) | 百灵 AI |
| 小米 MiMo / MiMo Token Plan | 小米 MiMo 模型 |
| 火山 Agentplan | 火山引擎 Agent Plan |
| BytePlus | BytePlus 服务 |
| DouBaoSeed | 豆包 Seed 模型 |
| SiliconFlow / SiliconFlow en | 硅基流动 |
| Novita AI | Novita AI 服务 |
| Nvidia | Nvidia AI 服务 |
> 💡 选择 Chat Completions 类预设时,「需要本地路由映射」开关和模型映射表会自动配置好,无需手动设置;详见下文「Codex 本地路由与模型映射」一节。预设列表持续更新,以应用内实际显示为准。
#### Gemini 预设
@@ -161,7 +196,7 @@
3. CC Switch 使用配置的 API Key 调用 OpenAI 兼容的 `/v1/models` 端点
4. 从按类别分组的下拉菜单中选择模型
此功能覆盖全部五个应用 —— **Claude / Codex / Gemini / OpenCode / OpenClaw**,适用于所有支持 `/v1/models` 端点的供应商。
此功能覆盖 **Claude Code / Claude Desktop / Codex / Gemini / OpenCode / OpenClaw / Hermes** 中带模型字段的供应商表单,适用于支持 `/v1/models` 端点的供应商。Codex OAuth 类供应商会按需从 ChatGPT Codex 后端获取实时模型列表。
**常见错误**
- **认证失败(401/403**:检查你的 API Key 是否正确
@@ -233,10 +268,13 @@ requires_openai_auth = true
| `model` | 是 | 使用的模型(如 `gpt-5.2``gpt-4o` |
| `model_reasoning_effort` | 否 | 推理强度:`low` / `medium` / `high` |
| `disable_response_storage` | 否 | 是否禁用响应存储 |
| `goals` | 否 | 放在 `[features]` 下并设为 `true` 后启用 Codex `/goal` 模式;需要时可在供应商编辑区域通过开关启用 |
| `base_url` | 是 | API 端点地址 |
| `wire_api` | 否 | API 协议类型(通常为 `responses` |
| `requires_openai_auth` | 否 | 是否使用 OpenAI 认证方式 |
如果切换到 API Key 或自定义端点供应商后,Codex 能识别 `/goal`,但无法设置目标,请在供应商编辑区域打开 **Goal mode** 开关。CC Switch 会为该供应商在 `~/.codex/config.toml``[features]` 下写入 `goals = true`,之后请重启 Codex。如果启用 Goal mode 后比预期更频繁地请求批准,请刷新 Codex 设置页,并确认 `approval_policy``sandbox_mode` 仍符合你的权限预期。
### Gemini 配置格式
@@ -259,7 +297,7 @@ requires_openai_auth = true
## 统一供应商
统一供应商可以跨 Claude/Codex/Gemini/OpenCode/OpenClaw 共享配置,适用于支持多种 API 格式的中转服务。
统一供应商可以跨 Claude Code / Codex / Gemini 共享配置,适用于支持多种 API 格式的中转服务。
### 创建统一供应商
@@ -269,7 +307,7 @@ requires_openai_auth = true
- 名称
- API Key
- 端点地址
4. 勾选要同步的应用(Claude/Codex/Gemini/OpenCode/OpenClaw
4. 勾选要同步的应用(Claude Code / Codex / Gemini
5. 保存
### 同步机制
@@ -403,6 +441,8 @@ Codex OAuth 预设的默认模型映射:
| Opus 角色 | `gpt-5.4` |
| Haiku 角色 | `gpt-5.4-mini` |
v3.15.0 起,Codex OAuth 模型选择不再只依赖硬编码列表。打开模型选择时,CC Switch 会按需从 ChatGPT Codex 后端拉取可用模型,默认映射仍可按需覆盖。
你可以在供应商的 JSON 编辑器中覆盖 `ANTHROPIC_MODEL` 等环境变量来自定义。
### 多账号管理(OAuth 认证中心)
@@ -516,6 +556,52 @@ v3.13.0 起新增的高级选项。默认情况下,CC Switch 会把配置的 `
此外,**写入通用配置** 复选框可将全局配置片段合并到供应商中。点击 **编辑通用配置** 可自定义共享的配置片段。
### Codex 本地路由与模型映射
部分第三方供应商只支持 **OpenAI Chat Completions** 协议,或使用非 GPT 模型名(如 DeepSeek、Kimi、MiniMax)。Codex 原生只认 OpenAI Responses API 与 GPT 系列模型,因此这类供应商需要 CC Switch 在本地做协议与模型转换。
#### 需要本地路由映射
编辑 Codex 供应商时,提供 **需要本地路由映射** 开关:
- **何时打开**:供应商使用 Chat Completions 协议,或模型名不是 Codex 默认的 GPT 系列
- **打开后**CC Switch 本地代理会把 Codex 发出的 Responses 请求转换为上游的 Chat Completions,再把响应(含流式 SSE、推理内容、工具调用)转换回 Responses 格式
- **前提条件**:必须开启[本地路由服务](../4-proxy/4.1-service.md)并启用 Codex 接管,转换才会生效;使用过程中需保持本地路由开启
> 💡 选择 DeepSeek、Kimi 等 Chat 格式预设时,此开关默认已打开,无需手动设置。
#### 模型映射
「需要本地路由映射」开启后,下方会出现 **模型映射** 表,用于声明该供应商可用的模型:
| 字段 | 说明 |
|------|------|
| 模型 ID | 上游真实模型名,如 `deepseek-v4-flash` |
| 显示名称 | (可选)在 `/model` 命令中显示的名称 |
| 上下文窗口 | (可选)模型的上下文长度 |
- 映射表会生成 Codex 的 `model_catalog_json`,让 Codex 的 `/model` 命令列出这些第三方模型名
- 表中条目按填写内容原样保存,是模型列表的唯一来源
- **修改后需要重启 Codex** 才能刷新模型列表(`model_catalog_json` 在 Codex 启动时加载)
#### 思考能力(Reasoning)自适应
开启本地路由后,CC Switch 会**自动识别**供应商的「思考」(reasoning)接口,把 Codex 发出的思考请求转换成上游能理解的参数,**无需手动配置**。识别依据是供应商的名称、端点和模型名:
- **聚合 / 托管平台优先**OpenRouter、SiliconFlow 等按平台规则处理(同一模型在不同平台上的思考接口可能完全不同)
- **其余按模型品牌**DeepSeek、Kimi / Moonshot、智谱 GLM、通义千问、MiniMax、小米 MiMo、阶跃星辰 StepFun 等各有对应规则
不同供应商支持的「思考」能力分两类:
| 能力 | 含义 | 代表供应商 |
|------|------|-----------|
| **支持思考等级** | 可调节思考强度(low / medium / high 等) | DeepSeek、OpenRouter、StepFun(仅 `step-3.5-flash-2603` |
| **仅支持思考开关** | 只能开 / 关思考,**等级无效** | Kimi、智谱 GLM、通义千问、MiniMax、小米 MiMo、SiliconFlow |
> ⚠️ **思考等级对部分供应商无效**:如果供应商只支持「思考开关」,那么在 Codex 里调节思考等级(`model_reasoning_effort` 的 low / medium / high**不会有任何效果**——CC Switch 不会把等级透传给这类上游(它们的接口不接受该参数,硬传可能导致请求被拒)。这类供应商的思考默认**开启**,靠「开 / 关」而非「调档」工作。只有支持思考等级的供应商(如 DeepSeek、OpenRouter),调节等级才真正生效。
> 💡 **识别基于名称 / 端点 / 模型名的关键词匹配**,不是真正的能力探测。官方域名(如 `api.deepseek.com``api.moonshot.cn`)都能正确识别;如果你用的中转改写了域名和模型名,可能识别不到,此时不会注入任何思考参数。
### Codex 1M 上下文窗口
添加 Codex 供应商时,提供 **启用 1M 上下文窗口** 开关:
@@ -523,7 +609,7 @@ v3.13.0 起新增的高级选项。默认情况下,CC Switch 会把配置的 `
- **启用时**:在 config.toml 中设置 `model_context_window = 1000000` 并自动填充 `model_auto_compact_token_limit = 900000`
- **禁用时**:移除这两个字段
开关开启后显示的文本框可自定义自动压缩限制值。
开关开启后显示的文本框可自定义自动压缩限制值。v3.15.0 起,该开关仅在新增 Codex 供应商时显示;编辑已有供应商时可通过高级配置直接调整相关字段。
### 自定义图标
@@ -39,14 +39,12 @@ v3.13.0 起,托盘菜单从原来的扁平列表重构为**按应用分组的
| Claude | Claude 所有供应商(含 Codex OAuth 反向代理) |
| Codex | Codex 所有供应商 |
| Gemini | Gemini 所有供应商 |
| OpenCode | OpenCode 所有供应商 |
| OpenClaw | OpenClaw 所有供应商 |
**重构带来的好处**
- **防止菜单溢出**:有大量供应商时,扁平列表会超出屏幕高度;分级子菜单天然支持无限扩展
- **子菜单标题显示当前激活供应商**:无需打开子菜单即可知道每个应用当前用的是哪个供应商
- **按应用隔离操作**:切换 Claude 的供应商不会干扰到 Codex 的视图
- **子菜单标题显示当前激活供应商与用量摘要**:无需打开子菜单即可知道 Claude / Codex / Gemini 当前使用哪个供应商,以及可用的缓存用量信息
- **按应用隔离操作**:切换 Claude 的供应商不会干扰到 Codex 或 Gemini 的视图
> 💡 **提示**:后台常驻 + 轻量模式 + 分级子菜单的组合特别适合频繁切换多个应用的重度用户。参考 [1.5 个性化配置 → 轻量模式](../1-getting-started/1.5-settings.md)。
+3 -2
View File
@@ -151,8 +151,9 @@ JSON 格式的配置内容,包括:
## 保存与生效
1. 点击「保存」按钮
2. 如果是当前启用的供应商,配置立即写入 live 文件
3. 重启 CLI 工具生效
2. 如果表单检测到非阻塞问题,会出现「先存上再说」确认提示;确认后仍可保存
3. 如果是当前启用的供应商,配置立即写入 live 文件
4. 重启 CLI 工具生效
## 取消编辑
@@ -24,6 +24,8 @@
- 备份当前配置
- 创建测试用配置
v3.15.0 起,统一供应商列表也提供复制按钮,可直接从现有统一供应商创建副本后再调整同步应用和模型。
### 操作步骤
1. 鼠标悬停在供应商卡片上,显示操作按钮
@@ -176,18 +176,18 @@ CC Switch 提供三种预设模板:
## 提取器返回格式
提取器函数需要返回包含以下字段的对象:
提取器函数返回包含以下字段的对象,所有字段均可选
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `isValid` | boolean | 否 | 账户是否有效,默认 true |
| `invalidMessage` | string | 否 | 无效时的提示信息 |
| `remaining` | number | | 剩余额度 |
| `unit` | string | | 单位(如 USD、CNY、次) |
| `remaining` | number | | 剩余额度 |
| `unit` | string | | 单位(如 USD、CNY、次) |
| `planName` | string | 否 | 套餐名称(支持多套餐) |
| `total` | number | 否 | 总额度 |
| `used` | number | 否 | 已使用额度 |
| `extra` | object | 否 | 额外信息 |
| `extra` | string | 否 | 额外展示文本 |
## 测试脚本
@@ -0,0 +1,306 @@
# 2.6 Claude Desktop
## 功能说明
Claude Desktop 面板用于在 CC Switch 中管理 Claude Desktop 的供应商配置。
开启后,你可以:
- 在 Claude Desktop 中使用第三方 Anthropic 兼容供应商
- 为三档角色 ID 之外的模型配置映射:旧式 Claude ID(如 `claude-3-5-sonnet`)、以及 DeepSeek / Kimi / DouBao / OpenAI / Gemini 等非 Claude 模型都需要
- 复用 Copilot / Codex OAuth 账号类供应商
- 在 Claude Desktop 官方模式和第三方供应商之间切换
Claude Desktop 与 Claude Code 是两个不同的应用入口。Claude Code 使用 `~/.claude/settings.json`Claude Desktop 使用自己的 3P profile 配置;在 CC Switch 中也分别显示为「Claude」和「Claude Desktop」,图标右下角会有一个小图标用来区分。
## 支持范围
| 项目 | 说明 |
| ------------ | ------------------------------------------------------------- |
| 支持系统 | macOS、Windows |
| 暂不支持 | Linux 写入 Claude Desktop 3P 配置 |
| 生效方式 | 切换供应商后需要重启 Claude Desktop |
| 官方模式 | 使用 Claude Desktop 内置登录,不需要 API Key 和接口地址 |
| 第三方模式 | 写入 CC Switch 管理的 3P profile |
| MCP / Skills | Claude Desktop 3P profile 不走 CC Switch 的 MCP / Skills 同步 |
## 快速上手
### 第一步:切换到 Claude Desktop 面板
在左侧应用切换器中选择 **Claude Desktop**
![Claude Desktop 面板](../../assets/claude-desktop-panel.png)
如果你没有看到该入口,请到:
设置 → 通用 → 应用可见性
确认 Claude Desktop 没有被隐藏。
### 第二步:导入或添加供应商
#### 优先使用:从 Claude Code 一键导入
很多用户最开始是在 Claude Code 里配置供应商,然后才想把同一批供应商带到 Claude Desktop。第一次启动 CC Switch,或第一次进入 Claude Desktop 面板时,如果这里还没有供应商,可以直接点击 **将 Claude Code 中已有的供应商导入**
![从 Claude Code 导入供应商](../../assets/claude-desktop-import-from-claude.png)
如果你已经在 Claude Code 那边配置了很多供应商,这个功能可以一键把它们导入到 Claude Desktop 面板,省掉逐个重新填写接口地址、API Key 和默认模型的工作。
导入规则:
- 已存在同 ID 供应商时不会覆盖
- 模型名为三档角色 ID`claude-sonnet-*` / `claude-opus-*` / `claude-haiku-*`)且能直连的供应商会导入为直连模式
- 模型名非三档角色 ID(含旧式 Claude ID)或需要格式转换的供应商会尝试导入为模型映射模式
- `ANTHROPIC_DEFAULT_SONNET_MODEL``ANTHROPIC_DEFAULT_OPUS_MODEL``ANTHROPIC_DEFAULT_HAIKU_MODEL` 会转换为 Desktop 的 Sonnet / Opus / Haiku 映射
- 旧的 `[1M]` 后缀会转换为 Claude Desktop profile 中的 `supports1m` 标记
- 无法判断模型映射的供应商会被跳过
导入后请检查每个供应商的模型映射是否符合你的实际上游模型。任何不是 `claude-sonnet-*` / `claude-opus-*` / `claude-haiku-*` 三档角色 ID 的模型——包括 Kimi、DeepSeek、GLM、DouBao 等非 Claude 模型,以及旧式 Claude ID——通常都需要使用模型映射模式。
如果你已经在 Claude Code 中配置过供应商,优先使用上面的 **将 Claude Code 中已有的供应商导入**。这是迁移到 Claude Desktop 最省事的路径。
如果没有可导入的配置,或想单独给 Claude Desktop 添加一个供应商,再点击右上角 **+** 按钮添加供应商。
![Claude Desktop 添加供应商](../../assets/claude-desktop-add-provider.png)
你可以选择:
- **预设供应商**:从内置 Claude Desktop 预设中选择,只填写 API Key
- **自定义供应商**:手动填写名称、接口地址、API Key 和模型设置
- **Claude Desktop Official**:恢复 Claude Desktop 官方登录模式
对于已经接受 Claude Desktop 三档角色 ID`claude-sonnet-*` / `claude-opus-*` / `claude-haiku-*`)的原生 Anthropic Messages API 供应商,通常只需要:
1. 选择预设或自定义供应商
2. 填写 **API Key**
3. 确认 **接口地址**
4. 保持「需要模型映射」关闭
5. 点击「添加」
### 第三步:切换并重启 Claude Desktop
在供应商卡片上点击「启用」。
切换成功后:
- 直连供应商:重启 Claude Desktop 后生效
- 需要路由的供应商:保持 CC Switch 运行,开启 Claude Desktop 本地路由,然后重启 Claude Desktop
> 注意:Claude Desktop 不会像 Claude Code 那样热重载配置。每次切换供应商后,都需要完全退出并重新打开 Claude Desktop。
## 两种工作模式
### 直连模式
直连模式适合供应商本身已经提供 Anthropic Messages API,并且能被 Claude Desktop 直接访问。
直连模式下,CC Switch 会把 Claude Desktop 的 3P profile 指向供应商接口:
```json
{
"inferenceProvider": "gateway",
"inferenceGatewayBaseUrl": "https://api.example.com",
"inferenceGatewayAuthScheme": "bearer",
"inferenceGatewayApiKey": "你的 API Key"
}
```
适用场景:
- 供应商暴露原生 Anthropic Messages API
- 模型 ID 为 Claude Desktop 可识别的角色名:`claude-sonnet-*``claude-opus-*``claude-haiku-*`(或带 `anthropic/claude-` 前缀的同类名)
- 不需要格式转换
- 不需要 CC Switch 在使用期间保持本地路由
直连模式的「手动指定 Claude Desktop 模型列表」是高级选项。多数原生 Claude 模型供应商不需要填写,Claude Desktop 会自动读取 `/v1/models`
仅当供应商的 `/v1/models` 不可用,或返回的模型名不能被 Claude Desktop 识别时,再手动添加模型。手动填写的模型名必须是 `claude-sonnet-*``claude-opus-*``claude-haiku-*` 形态(旧式 `claude-3-5-sonnet-…` 会被拒绝)。
### 模型映射模式
模型映射模式适合供应商提供的模型不是 `claude-sonnet-*` / `claude-opus-*` / `claude-haiku-*` 三档角色 ID(包括旧式 Claude ID 和 deepseek、kimi 等非 Claude 模型),或接口格式需要 CC Switch 转换。
开启「需要模型映射」后,Claude Desktop 会连接到 CC Switch 本地网关:
```text
http://127.0.0.1:15721/claude-desktop
```
CC Switch 会负责:
1. 向 Claude Desktop 暴露安全的 Claude 模型路由
2. 把 Desktop 选择的模型角色映射到真实上游模型
3. 按供应商要求转换 Anthropic / OpenAI / Gemini 请求格式
4. 用 CC Switch 中保存的供应商凭据访问上游
支持的 API 格式:
| 格式 | 用途 |
| ----------------------------- | ------------------------------- |
| Anthropic Messages | 原生或兼容 Anthropic 请求 |
| OpenAI Chat Completions | OpenAI 兼容 `/chat/completions` |
| OpenAI Responses API | OpenAI Responses 兼容接口 |
| Gemini Native generateContent | Gemini 原生接口 |
模型映射模式下,Claude Desktop 只看到 `claude-sonnet-*` / `claude-opus-*` / `claude-haiku-*` 三类角色路由;真实模型名不会直接写进 Claude Desktop profile。
## 配置模型映射
### 字段说明
| 字段 | 说明 |
| ------------ | -------------------------------------------------- |
| 模型角色 | Claude Desktop 可识别的 Sonnet / Opus / Haiku 路由 |
| 菜单显示名 | 在 Claude Desktop 模型菜单里显示的名称 |
| 实际请求模型 | 发送给上游供应商的真实模型 ID |
| 1M | 向 Claude Desktop 声明该模型支持 1M 上下文 |
![Claude Desktop 模型映射](../../assets/claude-desktop-model-mapping-rows.png)
### 推荐写法
如果你想在 Claude Desktop 中使用 Kimi
| 模型角色 | 菜单显示名 | 实际请求模型 | 1M |
| -------- | ---------- | ------------ | ---------------- |
| Sonnet | Kimi K2 | `kimi-k2` | 按供应商能力选择 |
如果你想使用 DeepSeek
| 模型角色 | 菜单显示名 | 实际请求模型 | 1M |
| -------- | --------------- | ----------------- | ---------------- |
| Sonnet | DeepSeek V4 Pro | `deepseek-v4-pro` | 按供应商能力选择 |
这样做的原因是 Claude Desktop 现在会拒绝不属于 Sonnet / Opus / Haiku 三类角色的模型,所以需要 CC Switch 的路由功能进行一轮模型映射。
### 多角色映射
你可以同时配置 Sonnet、Opus、Haiku 三个角色:
| 模型角色 | 建议用途 |
| -------- | -------------------- |
| Sonnet | 默认主力模型 |
| Opus | 高质量或复杂任务模型 |
| Haiku | 快速、低成本模型 |
如果供应商只有一个模型,只填写一个角色的实际请求模型也可以;留空的角色会自动沿用第一个已填模型(Sonnet 优先),因此 Haiku 等子 agent 调用始终有模型可用。模型映射模式至少需要填写一个实际请求模型。
## 本地路由开关
模型映射模式需要 CC Switch 本地路由参与请求转换。本地路由是一个强大,同时有一定复杂度的功能,为了避免不需要路由功能的用户误触,主页面的本地路由开关默认隐藏,需要路由功能时,请手动把它显示出来。
打开方式:
设置 → 路由 → 本地路由 → 开启 **在主页面显示本地路由开关**
![显示本地路由开关设置](../../assets/local-routing-display-setting.png)
打开显示开关后,回到 Claude Desktop 面板,主界面右上角会看到 Claude Desktop 本地路由开关。
![Claude Desktop 本地路由开关](../../assets/claude-desktop-route-toggle-context.png)
状态说明:
| 状态 | 说明 |
| -------- | ---------------------------------------------- |
| 开启 | 本地网关正在运行,地址通常是 `127.0.0.1:15721` |
| 关闭 | 直连供应商仍可使用;模型映射供应商无法正常工作 |
| 正在加载 | 路由服务正在启动或停止 |
只有「需要模型映射」的供应商必须依赖本地路由。直连供应商不需要打开这个开关。
如果其它应用正在使用代理接管,关闭本地路由可能会被阻止。请先到设置中的路由服务区域关闭对应应用接管,再停止本地路由。
## 恢复官方 Claude Desktop
如果你想回到 Claude Desktop 官方登录:
1. 选择 **Claude Desktop Official**
2. 点击「启用」
3. 重启 Claude Desktop
CC Switch 会恢复 Claude Desktop 的官方 1P 模式,并移除 CC Switch 管理的 3P profile。
官方模式不需要 API Key,也不需要本地路由。
从 Claude Code 导入供应商的时候,会自动添加一个 **Claude Desktop Official**
## 配置文件位置
CC Switch 会写入 Claude Desktop 的 3P 配置目录。
### macOS
```text
~/Library/Application Support/Claude/claude_desktop_config.json
~/Library/Application Support/Claude-3p/claude_desktop_config.json
~/Library/Application Support/Claude-3p/configLibrary/_meta.json
~/Library/Application Support/Claude-3p/configLibrary/00000000-0000-4000-8000-000000157210.json
```
### Windows
```text
%LOCALAPPDATA%\Claude\claude_desktop_config.json
%LOCALAPPDATA%\Claude-3p\claude_desktop_config.json
%LOCALAPPDATA%\Claude-3p\configLibrary\_meta.json
%LOCALAPPDATA%\Claude-3p\configLibrary\00000000-0000-4000-8000-000000157210.json
```
配置文件由 CC Switch 自动维护,不建议手动编辑。出现配置不一致时,重新启用当前供应商通常可以修复。
## 状态提示与处理
Claude Desktop 面板顶部可能出现「Claude Desktop 配置需要检查」提示。
| 提示 | 处理方式 |
| ------------------------------------ | ------------------------------------------------ |
| 当前平台暂不支持 | 目前仅 macOS / Windows 支持写入 3P 配置 |
| profile 中存在非 Sonnet / Opus / Haiku 角色模型名 | 重新切换当前供应商,或编辑供应商改用模型映射 |
| 启用了模型映射但没有有效路由 | 编辑供应商,至少添加一条模型映射 |
| 本地路由 token 尚未生成 | 重新切换该供应商,CC Switch 会写入新的本地 token |
| profile 指向的地址与当前供应商不一致 | 重新切换当前供应商,让 profile 回到正确地址 |
## 常见问题
### 切换成功但 Claude Desktop 没变化?
请完全退出并重启 Claude Desktop。Claude Desktop 读取 3P profile 的时机通常在启动阶段,切换后不会自动热更新。
### 模型映射供应商请求失败?
检查:
- CC Switch 是否仍在运行
- Claude Desktop 本地路由是否已开启
- 供应商 API Key 和接口地址是否正确
- 模型映射中是否填写了实际请求模型
- 切换供应商后是否重启了 Claude Desktop
### Claude Desktop 模型菜单里看不到我的品牌模型名?
编辑供应商,在模型映射中填写「菜单显示名」,然后重新启用供应商并重启 Claude Desktop。
### 直连模式下为什么报错?
直连模式要求供应商提供原生 Anthropic Messages API,并接受 Claude Desktop 的三档角色 ID`claude-sonnet-*` / `claude-opus-*` / `claude-haiku-*`)。如果供应商使用 OpenAI、Gemini、非 Claude 模型 ID,或旧式 Claude ID(如 `claude-3-5-sonnet-…`)等任何非三档角色 ID,直连都会失败,请开启「需要模型映射」。
### 可以关闭 CC Switch 吗?
取决于模式:
- 直连模式:Claude Desktop 重启并加载配置后,可以不保持本地路由运行
- 模型映射模式:必须保持 CC Switch 运行,并保持 Claude Desktop 本地路由开启
### 是否会把真实上游模型名写入 Claude Desktop
模型映射模式不会。Claude Desktop profile 中只保存安全的 Sonnet / Opus / Haiku 角色路由和显示名;真实上游模型名保存在 CC Switch 的供应商配置中,请求经过本地网关时再映射。
## 下一步
- [添加供应商](./2.1-add.md)
- [切换供应商](./2.2-switch.md)
- [代理服务](../4-proxy/4.1-service.md)
- [应用路由](../4-proxy/4.2-routing.md)
@@ -11,12 +11,13 @@
| OpenCode | `~/.local/share/opencode/`JSON 或 SQLite |
| OpenClaw | `~/.openclaw/agents/<agent>/sessions/*.jsonl` |
| Gemini CLI | `~/.cache/gemini/tmp/<project_hash>/chats/` |
| Hermes | `~/.hermes/state.db``~/.hermes/sessions/*.jsonl` |
## 打开会话管理器
点击主导航栏中的 **会话** 按钮。
> **注意**:会话按钮在所有五种应用模式下均可见
> **注意**:会话管理器覆盖上表六类会话来源;Claude Desktop 入口会复用 Claude Code 会话视图
## 界面布局
@@ -63,6 +64,7 @@
- **OpenCode**
- **OpenClaw**
- **Gemini CLI**
- **Hermes**
过滤可与搜索组合使用。
@@ -81,7 +83,7 @@
- 终端会在会话的项目目录中打开
- 如果终端启动失败,命令会被复制到剪贴板
**支持的终端(macOS**Terminal.app、iTerm2、Ghostty、Kitty、WezTerm、Alacritty
**支持的终端(macOS**Terminal.app、iTerm2、Ghostty、Kitty、WezTerm、Alacritty、Warp
**其他平台**
- 恢复命令会被复制到剪贴板
@@ -103,7 +105,7 @@ v3.13.0 起,**Claude 会话**恢复前会弹出**目录选择器**,让你可
2. 在弹出的目录选择器中,确认默认目录或选择新目录
3. CC Switch 会在所选目录下启动 Claude 终端会话
> 💡 **提示**Codex / Gemini / OpenCode / OpenClaw 会话的恢复流程暂不包含目录选择器,仍使用会话原始项目目录。
> 💡 **提示**Codex / Gemini / OpenCode / OpenClaw / Hermes 会话的恢复流程暂不包含目录选择器,仍使用会话原始项目目录。
### 删除会话
+8 -1
View File
@@ -50,10 +50,15 @@ v3.13.0 起,用量数据有两个来源:
| 指标 | 说明 |
|------|------|
| 总请求数 | 统计周期内的请求总数 |
| Token | 输入 + 输出 Token 总数 |
| 真实消耗 Tokens | 输入 + 输出 + 缓存创建 + 缓存读取的缓存归一化总量 |
| 缓存命中率 | 缓存读取 Token 在可缓存输入中的占比 |
| 估算费用 | 基于定价配置计算的费用 |
| 成功率 | 成功请求的百分比 |
v3.15.0 起,用量页顶部改为筛选驱动的 Hero 卡。切换日期范围、应用、供应商或模型筛选时,Hero 中的真实消耗 Tokens、缓存命中率、请求数和费用会同步更新,并与下方日志和统计列表保持一致。
> 注意:由于缓存读取、缓存创建和 OpenAI 类协议的缓存上报方式在 v3.15.0 中做了归一化,历史 token 与费用数字可能与旧版估算不完全一致;新数字以当前归一化规则为准。
### 时间范围
可选择统计的时间范围:
@@ -238,6 +243,8 @@ CC Switch 预设了常用模型的官方价格(每百万 Token)。v3.13.0
| 模型 | 输入 | 输出 | 缓存读取 | 缓存创建 |
|------|------|------|----------|----------|
| **Claude 4.8 系列** | | | | |
| claude-opus-4-8 | $5 | $25 | $0.50 | $6.25 |
| **Claude 4.5 系列** | | | | |
| claude-opus-4-5 | $5 | $25 | $0.50 | $6.25 |
| claude-sonnet-4-5 | $3 | $15 | $0.30 | $3.75 |
@@ -10,7 +10,9 @@
- 响应延迟是否正常
- 流式响应首字节时间(TTFB
v3.13.0 起,Stream Check 覆盖范围扩展到**全部五个应用**Claude / Codex / Gemini / OpenCode / OpenClaw,包括 OpenClaw 的全部协议变体(`openai-completions` 等)。OpenCode 通过 npm 包映射自动识别;OpenClaw 支持自定义 `auth-header` 检测,并处理了 Bedrock 错误消息、`baseURL` 回退等边界情况。
v3.13.0 起,Stream Check 覆盖范围扩展到 **Claude / Codex / Gemini / OpenCode / OpenClaw**,包括 OpenClaw 的全部协议变体(`openai-completions` 等)。OpenCode 通过 npm 包映射自动识别;OpenClaw 支持自定义 `auth-header` 检测,并处理了 Bedrock 错误消息、`baseURL` 回退等边界情况。
对于使用 Chat Completions 协议的 Codex 第三方供应商(如 DeepSeek、Kimi、MiniMax),Stream Check 会探测 `/chat/completions` 端点(而非 `/responses`),并与代理实际转发的 URL 顺序保持一致(origin-only 地址优先尝试 `/v1/...`),避免把可用供应商误判为不可用。
## 打开配置
+17 -8
View File
@@ -1,6 +1,6 @@
# CC Switch 用户手册
> Claude Code / Codex / Gemini CLI / OpenCode / OpenClaw 全方位辅助工具
> Claude Code / Claude Desktop / Codex / Gemini CLI / OpenCode / OpenClaw / Hermes 全方位辅助工具
## 目录结构
@@ -19,7 +19,8 @@
│ ├── 2.2 切换供应商
│ ├── 2.3 编辑供应商
│ ├── 2.4 排序与复制
── 2.5 用量查询
── 2.5 用量查询
│ └── 2.6 Claude Desktop
├── 3. 扩展功能
│ ├── 3.1 MCP 服务器管理
@@ -63,6 +64,7 @@
| [2.3-edit.md](./2-providers/2.3-edit.md) | 编辑配置、修改 API Key、回填机制 |
| [2.4-sort-duplicate.md](./2-providers/2.4-sort-duplicate.md) | 拖拽排序、复制供应商、删除 |
| [2.5-usage-query.md](./2-providers/2.5-usage-query.md) | 用量查询、剩余额度、多套餐显示 |
| [2.6-claude-desktop.md](./2-providers/2.6-claude-desktop.md) | Claude Desktop 第三方供应商、直连与模型映射 |
### 3. 扩展功能
@@ -98,24 +100,31 @@
- **新用户**:从 [1.1 软件介绍](./1-getting-started/1.1-introduction.md) 开始
- **安装问题**:查看 [1.2 安装指南](./1-getting-started/1.2-installation.md)
- **配置供应商**:查看 [2.1 添加供应商](./2-providers/2.1-add.md)
- **使用 Claude Desktop**:查看 [2.6 Claude Desktop](./2-providers/2.6-claude-desktop.md)
- **使用代理**:查看 [4.1 代理服务](./4-proxy/4.1-service.md)
- **遇到问题**:查看 [5.2 FAQ](./5-faq/5.2-questions.md)
## 版本信息
- 文档版本:v3.13.0
- 最后更新:2026-04-08
- 适用于 CC Switch v3.13.0+
- 文档版本:v3.15.0
- 最后更新:2026-05-16
- 适用于 CC Switch v3.15.0+
### v3.13.0 亮点
### v3.15.0 亮点
- **Claude Desktop 一等管理面板**:支持第三方供应商、直连 / 模型映射两种模式、Copilot / Codex OAuth 复用与 3P profile 写入 — 详见 [2.6 Claude Desktop](./2-providers/2.6-claude-desktop.md)
- **按角色的模型映射**:用 Sonnet / Opus / Haiku 路由和 `supports1m` 标志适配 Claude Desktop 的模型校验
- **Claude Desktop 本地路由**:通过 `127.0.0.1:15721/claude-desktop` 为需要转换的供应商提供本地网关
- **路由支持徽章**Claude Code / Codex 供应商卡片会标明是否支持 Local Routing,便于选择可代理的供应商
- **Codex OAuth 实时模型发现**ChatGPT Codex 类供应商按需从 ChatGPT 后端拉取最新模型列表
- **用量看板筛选驱动 Hero**:展示缓存归一化后的真实总 token 与缓存命中率,并跟随日期 / 供应商 / 模型筛选实时更新 — 详见 [4.4 用量统计](./4-proxy/4.4-usage.md)
- **轻量模式**:退出到托盘时销毁主窗口,空闲占用接近零 — 详见 [1.5 个性化配置](./1-getting-started/1.5-settings.md)
- **配额与余额展示**:官方订阅类(Claude/Codex/Gemini/Copilot/Codex OAuth)自动展示剩余额度;Token Plan 和第三方余额通过内置模板一键启用 — 详见 [2.5 用量查询](./2-providers/2.5-usage-query.md)
- **Codex OAuth 反向代理**:用 ChatGPT 账号在 Claude Code 中复用 Codex 服务 — 详见 [2.1 添加供应商](./2-providers/2.1-add.md)
- **托盘按应用分级菜单**五应用独立子菜单,防止菜单溢出 — 详见 [2.2 切换供应商](./2-providers/2.2-switch.md)
- **托盘按应用分级菜单**Claude / Codex / Gemini 独立子菜单,标题展示当前供应商与可用用量摘要 — 详见 [2.2 切换供应商](./2-providers/2.2-switch.md)
- **Skills 发现与批量更新**:SHA-256 更新检测、批量更新、skills.sh 公共注册表搜索 — 详见 [3.3 Skills 技能管理](./3-extensions/3.3-skills.md)
- **完整 URL 端点模式**:高级选项支持将 base_url 视作完整上游端点 — 详见 [2.1 添加供应商](./2-providers/2.1-add.md)
- **OpenCode / OpenClaw 流式检测覆盖**Stream Check 面板扩展到全部五个应用 — 详见 [4.5 模型检查](./4-proxy/4.5-model-test.md)
- **OpenCode / OpenClaw 流式检测覆盖**Stream Check 面板覆盖 Claude / Codex / Gemini / OpenCode / OpenClaw — 详见 [4.5 模型检查](./4-proxy/4.5-model-test.md)
## 贡献
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "cc-switch",
"version": "3.14.1",
"version": "3.16.0",
"description": "All-in-One Assistant for Claude Code, Codex & Gemini CLI",
"type": "module",
"scripts": {
+1 -1
View File
@@ -735,7 +735,7 @@ dependencies = [
[[package]]
name = "cc-switch"
version = "3.14.1"
version = "3.16.0"
dependencies = [
"anyhow",
"arboard",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "cc-switch"
version = "3.14.1"
version = "3.16.0"
description = "All-in-One Assistant for Claude Code, Codex & Gemini CLI"
authors = ["Jason Young"]
license = "MIT"
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+33 -1
View File
@@ -3,9 +3,10 @@
//! 提供 OpenAI ChatGPT Plus/Pro OAuth 认证相关的 Tauri 命令。
//!
//! 大部分认证命令通过通用 `auth_*` 命令(参见 `commands::auth`)暴露给前端,
//! 此处定义 State wrapper 以及 Codex OAuth 专属的订阅额度查询命令。
//! 此处定义 State wrapper 以及 Codex OAuth 专属的订阅额度和模型列表查询命令。
use crate::proxy::providers::codex_oauth_auth::CodexOAuthManager;
use crate::services::model_fetch::FetchedModel;
use crate::services::subscription::{query_codex_quota, CredentialStatus, SubscriptionQuota};
use std::sync::Arc;
use tauri::State;
@@ -56,3 +57,34 @@ pub async fn get_codex_oauth_quota(
)
.await)
}
/// 获取 Codex OAuth (ChatGPT Plus/Pro) 可用模型列表
///
/// ChatGPT Codex 反代使用 `chatgpt.com/backend-api/codex/*`,不是 OpenAI 兼容
/// `/v1/models`。这里复用托管 OAuth 账号的 access_token,直接读取 Codex 后端
/// 暴露的模型列表端点。
#[tauri::command(rename_all = "camelCase")]
pub async fn get_codex_oauth_models(
account_id: Option<String>,
state: State<'_, CodexOAuthState>,
) -> Result<Vec<FetchedModel>, String> {
let manager = state.0.read().await;
let resolved = match account_id
.as_deref()
.map(str::trim)
.filter(|id| !id.is_empty())
{
Some(id) => Some(id.to_string()),
None => manager.default_account_id().await,
};
let Some(id) = resolved else {
return Err("No ChatGPT account available".to_string());
};
let token = manager
.get_valid_token_for_account(&id)
.await
.map_err(|e| format!("Codex OAuth token unavailable: {e}"))?;
crate::services::codex_oauth_models::fetch_models_with_token(&token, &id).await
}
+2 -1
View File
@@ -82,7 +82,8 @@ pub async fn get_config_status(
}
AppType::Codex => {
let auth_path = codex_config::get_codex_auth_path();
let exists = auth_path.exists();
let config_text = codex_config::read_codex_config_text().unwrap_or_default();
let exists = auth_path.exists() || !config_text.trim().is_empty();
let path = codex_config::get_codex_config_dir()
.to_string_lossy()
.to_string();
+28 -17
View File
@@ -86,11 +86,19 @@ pub async fn set_auto_failover_enabled(
"[Failover] Setting auto_failover_enabled: app_type='{app_type}', enabled={enabled}"
);
// 强一致语义:开启故障转移后立即切到队列 P1(并确保队列非空)
//
// 说明:
// - 仅在 enabled=true 时执行“切到 P1”
// - 若队列为空,则尝试把“当前供应商”自动加入队列作为 P1,避免用户在 UI 上陷入死锁(无法先加队列再开启)
// 读取当前配置
let mut config = state
.db
.get_proxy_config_for_app(&app_type)
.await
.map_err(|e| e.to_string())?;
if enabled && !config.enabled {
return Err("需要先启用该应用的代理接管,再开启故障转移".to_string());
}
// 队列为空时把当前供应商自动加入作为 P1,避免用户陷入"必须先加队列才能开启"的死锁
let mut auto_added_provider_id: Option<String> = None;
let p1_provider_id = if enabled {
let mut queue = state
.db
@@ -112,6 +120,7 @@ pub async fn set_auto_failover_enabled(
.db
.add_to_failover_queue(&app_type, &current_id)
.map_err(|e| e.to_string())?;
auto_added_provider_id = Some(current_id);
queue = state
.db
@@ -127,12 +136,20 @@ pub async fn set_auto_failover_enabled(
String::new()
};
// 读取当前配置
let mut config = state
.db
.get_proxy_config_for_app(&app_type)
.await
.map_err(|e| e.to_string())?;
// 开启前先切到 P1。只有切换成功后才写入 auto_failover_enabled=true
// 避免 P1 不可切换(例如 official provider)时留下“开关已开但目标未切”的脏状态。
if enabled {
if let Err(e) = state
.proxy_service
.switch_proxy_target(&app_type, &p1_provider_id)
.await
{
if let Some(provider_id) = auto_added_provider_id {
let _ = state.db.remove_from_failover_queue(&app_type, &provider_id);
}
return Err(e);
}
}
// 更新 auto_failover_enabled 字段
config.auto_failover_enabled = enabled;
@@ -144,13 +161,7 @@ pub async fn set_auto_failover_enabled(
.await
.map_err(|e| e.to_string())?;
// 开启后立即切到 P1:更新 is_current + 本地 settings + Live 备份(接管模式下)
if enabled {
state
.proxy_service
.switch_proxy_target(&app_type, &p1_provider_id)
.await?;
// 发射 provider-switched 事件(让前端刷新当前供应商)
let event_data = serde_json::json!({
"appType": app_type,
File diff suppressed because it is too large Load Diff
+303 -28
View File
@@ -184,16 +184,6 @@ pub fn import_claude_desktop_providers_from_claude(
continue;
}
if matches!(
provider
.meta
.as_ref()
.and_then(|meta| meta.provider_type.as_deref()),
Some("github_copilot") | Some("codex_oauth")
) {
continue;
}
let mut desktop_provider = provider.clone();
desktop_provider.in_failover_queue = false;
let meta = desktop_provider.meta.get_or_insert_with(Default::default);
@@ -216,6 +206,16 @@ pub fn import_claude_desktop_providers_from_claude(
imported += 1;
}
// Safety net: 用户可能手动删除过 claude-desktop-official seed。
// 用户主动点 import 是"重新整理 ClaudeDesktop 表"的隐式信号,把官方入口补回来。
// 失败只 warn,不影响 imported 主流程;imported 计数语义保持纯净。
if let Err(e) = state.db.ensure_official_seed_by_id(
crate::database::CLAUDE_DESKTOP_OFFICIAL_PROVIDER_ID,
AppType::ClaudeDesktop,
) {
log::warn!("Failed to ensure claude-desktop-official seed during import: {e}");
}
Ok(imported)
}
@@ -241,7 +241,7 @@ fn claude_provider_models_are_claude_safe(provider: &Provider) -> bool {
.all(crate::claude_desktop_config::is_claude_safe_model_id)
}
fn suggested_claude_desktop_routes(
pub(crate) fn suggested_claude_desktop_routes(
provider: &Provider,
) -> Option<std::collections::HashMap<String, crate::provider::ClaudeDesktopModelRoute>> {
let env = provider
@@ -249,29 +249,88 @@ fn suggested_claude_desktop_routes(
.get("env")
.and_then(|value| value.as_object())?;
let mut routes = std::collections::HashMap::new();
let supports_1m_default = !matches!(
provider
.meta
.as_ref()
.and_then(|meta| meta.provider_type.as_deref()),
Some("github_copilot") | Some("codex_oauth")
);
fn add_route(
routes: &mut std::collections::HashMap<String, crate::provider::ClaudeDesktopModelRoute>,
env: &serde_json::Map<String, serde_json::Value>,
route_id: &str,
route_key: &str,
env_key: &str,
display_name: &str,
supports_1m_default: bool,
) {
if let Some(model) = env
let Some(raw_model) = env
.get(env_key)
.and_then(|value| value.as_str())
.map(str::trim)
.filter(|value| !value.is_empty())
{
routes.insert(
route_id.to_string(),
crate::provider::ClaudeDesktopModelRoute {
model: model.to_string(),
display_name: Some(display_name.to_string()),
supports_1m: Some(true),
},
);
else {
return;
};
// Claude 端 env 值可能带 [1M] 后缀;Claude Desktop schema 不接受后缀,
// 改用 supports1m 字段表达 1M 能力。在 import 边界做单向翻译。
let marker = crate::claude_desktop_config::ONE_M_CONTEXT_MARKER.as_bytes();
let raw_bytes = raw_model.as_bytes();
let has_1m_marker = raw_bytes.len() >= marker.len()
&& raw_bytes[raw_bytes.len() - marker.len()..].eq_ignore_ascii_case(marker);
let stripped_model: &str = if has_1m_marker {
raw_model[..raw_model.len() - marker.len()].trim_end()
} else {
raw_model
};
if stripped_model.is_empty() {
return;
}
let effective_supports_1m = supports_1m_default || has_1m_marker;
let explicit_label_override = env
.get(&format!("{env_key}_NAME"))
.and_then(|value| value.as_str())
.map(str::trim)
.filter(|value| !value.is_empty())
.map(str::to_string);
let label_override = explicit_label_override.clone().or_else(|| {
(!crate::claude_desktop_config::is_claude_safe_model_id(stripped_model))
.then(|| stripped_model.to_string())
});
// 何时覆盖既有 label_override:原本为空 / 这次来的是 explicit _NAME /
// 既有值只是 stripped_model 派生的占位(被 explicit 或更具体的值挤掉)。
let should_overwrite = |existing: Option<&str>| {
existing.is_none()
|| explicit_label_override.is_some()
|| existing == Some(stripped_model)
};
let merge_into = |existing: &mut crate::provider::ClaudeDesktopModelRoute| {
let merged = existing.supports_1m.unwrap_or(false) || effective_supports_1m;
existing.supports_1m = Some(merged);
if should_overwrite(existing.label_override.as_deref()) {
existing.label_override = label_override.clone();
}
};
if let Some(existing) = routes
.values_mut()
.find(|existing| existing.model == stripped_model)
{
merge_into(existing);
return;
}
routes
.entry(route_key.to_string())
.and_modify(merge_into)
.or_insert_with(|| crate::provider::ClaudeDesktopModelRoute {
model: stripped_model.to_string(),
label_override,
supports_1m: Some(effective_supports_1m),
});
}
for spec in crate::claude_desktop_config::DEFAULT_PROXY_ROUTES {
@@ -280,18 +339,19 @@ fn suggested_claude_desktop_routes(
env,
spec.route_id,
spec.env_key,
spec.display_name,
supports_1m_default,
);
}
let primary_route = crate::claude_desktop_config::DEFAULT_PROXY_ROUTES[0];
if !routes.contains_key(primary_route.route_id) {
// 三个 default env_key 全空时用 ANTHROPIC_MODEL 派生兜底路由。
if routes.is_empty() {
let primary_route = crate::claude_desktop_config::DEFAULT_PROXY_ROUTES[0].route_id;
add_route(
&mut routes,
env,
primary_route.route_id,
primary_route,
"ANTHROPIC_MODEL",
primary_route.display_name,
supports_1m_default,
);
}
@@ -682,3 +742,218 @@ pub fn get_opencode_live_provider_ids() -> Result<Vec<String>, String> {
// ============================================================================
// OpenClaw 专属命令 → 已迁移至 commands/openclaw.rs
// ============================================================================
#[cfg(test)]
mod import_claude_desktop_tests {
use super::suggested_claude_desktop_routes;
use crate::provider::{Provider, ProviderMeta};
use serde_json::json;
fn make_provider(env: serde_json::Value, provider_type: Option<&str>) -> Provider {
let mut p = Provider::with_id(
"test-claude".to_string(),
"Test".to_string(),
json!({ "env": env }),
None,
);
if let Some(pt) = provider_type {
p.meta = Some(ProviderMeta {
provider_type: Some(pt.to_string()),
..ProviderMeta::default()
});
}
p
}
#[test]
fn route_strips_1m_suffix_and_sets_supports_1m() {
let p = make_provider(
json!({
"ANTHROPIC_DEFAULT_SONNET_MODEL": "claude-sonnet-4-5-20250929[1M]",
}),
None,
);
let routes = suggested_claude_desktop_routes(&p).expect("routes built");
let r = routes
.get("claude-sonnet-4-6")
.expect("sonnet route present");
assert_eq!(r.model, "claude-sonnet-4-5-20250929");
assert!(
!r.model.to_ascii_lowercase().contains("[1m]"),
"model must not contain [1m] suffix"
);
assert_eq!(r.label_override, None);
assert_eq!(r.supports_1m, Some(true));
}
#[test]
fn route_preserves_model_without_suffix() {
let p = make_provider(
json!({
"ANTHROPIC_DEFAULT_SONNET_MODEL": "kimi-k2",
}),
None,
);
let routes = suggested_claude_desktop_routes(&p).expect("routes built");
let r = routes
.get("claude-sonnet-4-6")
.expect("sonnet route present");
assert_eq!(r.model, "kimi-k2");
assert_eq!(r.label_override.as_deref(), Some("kimi-k2"));
// 默认 provider_type 缺省 → supports_1m_default = true
assert_eq!(r.supports_1m, Some(true));
}
#[test]
fn route_uses_claude_code_model_name_as_label_override() {
let p = make_provider(
json!({
"ANTHROPIC_DEFAULT_SONNET_MODEL": "kimi-k2",
"ANTHROPIC_DEFAULT_SONNET_MODEL_NAME": "Kimi K2",
}),
None,
);
let routes = suggested_claude_desktop_routes(&p).expect("routes built");
let r = routes
.get("claude-sonnet-4-6")
.expect("sonnet route present");
assert_eq!(r.model, "kimi-k2");
assert_eq!(r.label_override.as_deref(), Some("Kimi K2"));
}
#[test]
fn route_1m_suffix_overrides_provider_type_default() {
// github_copilot 默认 supports_1m_default = false,但 [1M] 后缀应强制 true
let p = make_provider(
json!({
"ANTHROPIC_DEFAULT_SONNET_MODEL": "gpt-5-codex[1M]",
}),
Some("github_copilot"),
);
let routes = suggested_claude_desktop_routes(&p).expect("routes built");
let r = routes
.get("claude-sonnet-4-6")
.expect("sonnet route present");
assert_eq!(r.model, "gpt-5-codex");
assert_eq!(r.label_override.as_deref(), Some("gpt-5-codex"));
assert_eq!(r.supports_1m, Some(true));
}
#[test]
fn route_github_copilot_without_suffix_keeps_false() {
let p = make_provider(
json!({
"ANTHROPIC_DEFAULT_SONNET_MODEL": "gpt-5-codex",
}),
Some("github_copilot"),
);
let routes = suggested_claude_desktop_routes(&p).expect("routes built");
let r = routes
.get("claude-sonnet-4-6")
.expect("sonnet route present");
assert_eq!(r.model, "gpt-5-codex");
assert_eq!(r.label_override.as_deref(), Some("gpt-5-codex"));
assert_eq!(r.supports_1m, Some(false));
}
#[test]
fn same_upstream_across_three_aliases_merges_to_one_route() {
let p = make_provider(
json!({
"ANTHROPIC_DEFAULT_SONNET_MODEL": "MiniMax-M2",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "MiniMax-M2",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "MiniMax-M2",
}),
None,
);
let routes = suggested_claude_desktop_routes(&p).expect("routes built");
assert_eq!(routes.len(), 1, "three aliases → one merged route");
let r = routes
.get("claude-sonnet-4-6")
.expect("merged route present");
assert_eq!(r.model, "MiniMax-M2");
assert_eq!(r.label_override.as_deref(), Some("MiniMax-M2"));
}
#[test]
fn same_upstream_with_partial_1m_marker_takes_or_aggregation() {
// sonnet 带 [1M]opus/haiku 不带 → 合并后 supports_1m == Some(true)
let p = make_provider(
json!({
"ANTHROPIC_DEFAULT_SONNET_MODEL": "MiniMax-M2[1M]",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "MiniMax-M2",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "MiniMax-M2",
}),
None,
);
let routes = suggested_claude_desktop_routes(&p).expect("routes built");
assert_eq!(routes.len(), 1);
let r = routes
.get("claude-sonnet-4-6")
.expect("merged route present");
assert_eq!(r.supports_1m, Some(true));
}
#[test]
fn different_upstream_models_produce_separate_routes() {
let p = make_provider(
json!({
"ANTHROPIC_DEFAULT_SONNET_MODEL": "GLM-4.6",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "GLM-4-Air",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "GLM-4-Flash",
}),
None,
);
let routes = suggested_claude_desktop_routes(&p).expect("routes built");
assert_eq!(routes.len(), 3);
assert_eq!(routes.get("claude-sonnet-4-6").unwrap().model, "GLM-4.6");
assert_eq!(routes.get("claude-opus-4-8").unwrap().model, "GLM-4-Air");
assert_eq!(routes.get("claude-haiku-4-5").unwrap().model, "GLM-4-Flash");
assert_eq!(
routes
.get("claude-sonnet-4-6")
.unwrap()
.label_override
.as_deref(),
Some("GLM-4.6")
);
}
#[test]
fn anthropic_model_fallback_only_triggers_when_empty() {
// 三个 default env_key 都不填,仅 ANTHROPIC_MODEL
let p = make_provider(
json!({
"ANTHROPIC_MODEL": "kimi-k2",
}),
None,
);
let routes = suggested_claude_desktop_routes(&p).expect("routes built");
assert_eq!(routes.len(), 1);
let r = routes
.get("claude-sonnet-4-6")
.expect("fallback route present");
assert_eq!(r.model, "kimi-k2");
assert_eq!(r.label_override.as_deref(), Some("kimi-k2"));
}
#[test]
fn existing_claude_prefix_not_duplicated() {
let p = make_provider(
json!({
"ANTHROPIC_DEFAULT_SONNET_MODEL": "claude-sonnet-4-5-20250929",
}),
None,
);
let routes = suggested_claude_desktop_routes(&p).expect("routes built");
assert!(routes.contains_key("claude-sonnet-4-6"));
assert!(!routes.contains_key("claude-claude-sonnet-4-5-20250929"));
assert_eq!(
routes
.get("claude-sonnet-4-6")
.expect("route")
.label_override,
None
);
}
}
+9 -1
View File
@@ -133,9 +133,17 @@ pub async fn update_proxy_config_for_app(
config: AppProxyConfig,
) -> Result<(), String> {
let db = &state.db;
let app_type = config.app_type.clone();
let circuit_config = CircuitBreakerConfig::from(&config);
db.update_proxy_config_for_app(config)
.await
.map_err(|e| e.to_string())
.map_err(|e| e.to_string())?;
state
.proxy_service
.update_circuit_breaker_config_for_app(&app_type, circuit_config)
.await
}
async fn get_default_cost_multiplier_internal(
+71 -1
View File
@@ -21,6 +21,24 @@ fn merge_settings_for_save(
}
_ => {}
}
if incoming.local_migrations.is_none() {
incoming.local_migrations = existing.local_migrations.clone();
} else if let (Some(incoming_migrations), Some(existing_migrations)) =
(&mut incoming.local_migrations, &existing.local_migrations)
{
if incoming_migrations
.codex_third_party_history_provider_bucket_v1
.is_none()
{
incoming_migrations.codex_third_party_history_provider_bucket_v1 = existing_migrations
.codex_third_party_history_provider_bucket_v1
.clone();
}
if incoming_migrations.codex_provider_template_v1.is_none() {
incoming_migrations.codex_provider_template_v1 =
existing_migrations.codex_provider_template_v1.clone();
}
}
incoming
}
@@ -83,7 +101,10 @@ pub async fn set_auto_launch(enabled: bool) -> Result<bool, String> {
#[cfg(test)]
mod tests {
use super::merge_settings_for_save;
use crate::settings::{AppSettings, WebDavSyncSettings};
use crate::settings::{
AppSettings, CodexProviderTemplateMigration, CodexThirdPartyHistoryProviderBucketMigration,
LocalMigrations, WebDavSyncSettings,
};
#[test]
fn save_settings_should_preserve_existing_webdav_when_payload_omits_it() {
@@ -204,6 +225,55 @@ mod tests {
Some("")
);
}
#[test]
fn save_settings_should_preserve_local_migrations_when_payload_omits_it() {
let existing = AppSettings {
local_migrations: Some(LocalMigrations {
codex_third_party_history_provider_bucket_v1: Some(
CodexThirdPartyHistoryProviderBucketMigration {
completed_at: "2026-05-20T00:00:00Z".to_string(),
target_provider_id: "custom".to_string(),
source_provider_ids: vec!["rightcode".to_string()],
migrated_jsonl_files: 2,
migrated_state_rows: 3,
scanned_history_files: true,
},
),
codex_provider_template_v1: Some(CodexProviderTemplateMigration {
completed_at: "2026-05-20T00:01:00Z".to_string(),
migrated_provider_ids: vec!["legacy".to_string()],
}),
}),
..AppSettings::default()
};
let incoming = AppSettings::default();
let merged = merge_settings_for_save(incoming, &existing);
let migration = merged
.local_migrations
.as_ref()
.and_then(|migrations| {
migrations
.codex_third_party_history_provider_bucket_v1
.as_ref()
})
.expect("local migration marker should be preserved");
assert_eq!(migration.target_provider_id, "custom");
assert_eq!(migration.migrated_jsonl_files, 2);
assert_eq!(migration.migrated_state_rows, 3);
let template_migration = merged
.local_migrations
.as_ref()
.and_then(|migrations| migrations.codex_provider_template_v1.as_ref())
.expect("template migration marker should be preserved");
assert_eq!(
template_migration.migrated_provider_ids,
vec!["legacy".to_string()]
);
}
}
/// 获取开机自启状态
+72 -16
View File
@@ -3,6 +3,8 @@
use crate::error::AppError;
use crate::services::usage_stats::*;
use crate::store::AppState;
use rust_decimal::Decimal;
use std::str::FromStr;
use tauri::State;
/// 获取使用量汇总
@@ -18,6 +20,16 @@ pub fn get_usage_summary(
.get_usage_summary(start_date, end_date, app_type.as_deref())
}
/// 获取按 app_type 拆分的使用量汇总
#[tauri::command]
pub fn get_usage_summary_by_app(
state: State<'_, AppState>,
start_date: Option<i64>,
end_date: Option<i64>,
) -> Result<Vec<UsageSummaryByApp>, AppError> {
state.db.get_usage_summary_by_app(start_date, end_date)
}
/// 获取每日趋势
#[tauri::command]
pub fn get_usage_trends(
@@ -139,23 +151,67 @@ pub fn update_model_pricing(
cache_creation_cost: String,
) -> Result<(), AppError> {
let db = state.db.clone();
let conn = crate::database::lock_conn!(db.conn);
let model_id = model_id.trim().to_string();
let display_name = display_name.trim().to_string();
if model_id.is_empty() {
return Err(AppError::localized(
"usage.modelIdRequired",
"模型 ID 不能为空",
"Model ID is required",
));
}
if display_name.is_empty() {
return Err(AppError::localized(
"usage.displayNameRequired",
"显示名称不能为空",
"Display name is required",
));
}
conn.execute(
"INSERT OR REPLACE INTO model_pricing (
model_id, display_name, input_cost_per_million, output_cost_per_million,
cache_read_cost_per_million, cache_creation_cost_per_million
) VALUES (?1, ?2, ?3, ?4, ?5, ?6)",
rusqlite::params![
model_id,
display_name,
input_cost,
output_cost,
cache_read_cost,
cache_creation_cost
],
)
.map_err(|e| AppError::Database(format!("更新模型定价失败: {e}")))?;
for (label, value) in [
("input_cost", &input_cost),
("output_cost", &output_cost),
("cache_read_cost", &cache_read_cost),
("cache_creation_cost", &cache_creation_cost),
] {
let parsed = Decimal::from_str(value.trim()).map_err(|e| {
AppError::localized(
"usage.invalidPrice",
format!("{label} 价格无效: {value} - {e}"),
format!("{label} price is invalid: {value} - {e}"),
)
})?;
if parsed < Decimal::ZERO {
return Err(AppError::localized(
"usage.invalidPrice",
format!("{label} 价格必须为非负数: {value}"),
format!("{label} price must be non-negative: {value}"),
));
}
}
{
let conn = crate::database::lock_conn!(db.conn);
conn.execute(
"INSERT OR REPLACE INTO model_pricing (
model_id, display_name, input_cost_per_million, output_cost_per_million,
cache_read_cost_per_million, cache_creation_cost_per_million
) VALUES (?1, ?2, ?3, ?4, ?5, ?6)",
rusqlite::params![
model_id,
display_name,
input_cost.trim(),
output_cost.trim(),
cache_read_cost.trim(),
cache_creation_cost.trim()
],
)
.map_err(|e| AppError::Database(format!("更新模型定价失败: {e}")))?;
}
if let Err(e) = db.backfill_missing_usage_costs_for_model(&model_id) {
log::warn!("模型定价更新后回填历史用量成本失败 (model_id={model_id}): {e}");
}
Ok(())
}
+134
View File
@@ -649,4 +649,138 @@ impl Database {
Ok(inserted)
}
/// 按 id 兜底插入单条 official seed(仅当目标表中该 id 不存在时插入)。
///
/// 与 `init_default_official_providers` 不同:
/// - 不触碰 `official_providers_seeded` 全局 flag,是 on-demand 修复
/// - 只处理一条 seed,由调用方决定 id + app_type
/// - 已存在则尊重用户自定义,不覆盖
///
/// 返回 Ok(true) 表示插入了新行,Ok(false) 表示已存在被跳过。
pub fn ensure_official_seed_by_id(
&self,
seed_id: &str,
app_type: crate::app_config::AppType,
) -> Result<bool, AppError> {
use crate::database::dao::providers_seed::OFFICIAL_SEEDS;
let seed = OFFICIAL_SEEDS
.iter()
.find(|s| s.id == seed_id && s.app_type == app_type)
.ok_or_else(|| {
AppError::Database(format!(
"unknown official seed: id={seed_id}, app_type={}",
app_type.as_str()
))
})?;
let app_type_str = seed.app_type.as_str();
if self.get_provider_by_id(seed_id, app_type_str)?.is_some() {
return Ok(false);
}
let settings_config: serde_json::Value = serde_json::from_str(seed.settings_config_json)
.map_err(|e| {
AppError::Database(format!("Seed JSON parse failed for {}: {e}", seed.id))
})?;
let next_sort_index = self.next_sort_index_for_app(app_type_str)?;
let now_ms = chrono::Utc::now().timestamp_millis();
let mut provider = Provider::with_id(
seed.id.to_string(),
seed.name.to_string(),
settings_config,
Some(seed.website_url.to_string()),
);
provider.category = Some("official".to_string());
provider.icon = Some(seed.icon.to_string());
provider.icon_color = Some(seed.icon_color.to_string());
provider.sort_index = Some(next_sort_index);
provider.created_at = Some(now_ms);
self.save_provider(app_type_str, &provider)?;
Ok(true)
}
}
#[cfg(test)]
mod ensure_official_seed_tests {
use crate::app_config::AppType;
use crate::database::{Database, CLAUDE_DESKTOP_OFFICIAL_PROVIDER_ID};
#[test]
fn ensure_inserts_when_missing() {
let db = Database::memory().expect("memory db");
let inserted = db
.ensure_official_seed_by_id(CLAUDE_DESKTOP_OFFICIAL_PROVIDER_ID, AppType::ClaudeDesktop)
.expect("ensure ok");
assert!(inserted, "should insert when missing");
let provider = db
.get_provider_by_id(
CLAUDE_DESKTOP_OFFICIAL_PROVIDER_ID,
AppType::ClaudeDesktop.as_str(),
)
.expect("query ok")
.expect("provider exists after ensure");
assert_eq!(provider.id, CLAUDE_DESKTOP_OFFICIAL_PROVIDER_ID);
assert_eq!(provider.name, "Claude Desktop Official");
assert_eq!(provider.category.as_deref(), Some("official"));
assert_eq!(provider.icon.as_deref(), Some("anthropic"));
assert_eq!(provider.icon_color.as_deref(), Some("#D4915D"));
}
#[test]
fn ensure_skips_when_present_and_preserves_customization() {
let db = Database::memory().expect("memory db");
db.init_default_official_providers().expect("seed");
let mut renamed = db
.get_provider_by_id(
CLAUDE_DESKTOP_OFFICIAL_PROVIDER_ID,
AppType::ClaudeDesktop.as_str(),
)
.expect("query ok")
.expect("seed present");
renamed.name = "My Custom Backup".to_string();
db.save_provider(AppType::ClaudeDesktop.as_str(), &renamed)
.expect("save customization");
let inserted = db
.ensure_official_seed_by_id(CLAUDE_DESKTOP_OFFICIAL_PROVIDER_ID, AppType::ClaudeDesktop)
.expect("ensure ok");
assert!(!inserted, "should skip when present");
let after = db
.get_provider_by_id(
CLAUDE_DESKTOP_OFFICIAL_PROVIDER_ID,
AppType::ClaudeDesktop.as_str(),
)
.expect("query ok")
.expect("still present");
assert_eq!(
after.name, "My Custom Backup",
"customization must not be overwritten"
);
}
#[test]
fn ensure_rejects_unknown_seed() {
let db = Database::memory().expect("memory db");
let result = db.ensure_official_seed_by_id("nonexistent-id", AppType::ClaudeDesktop);
assert!(result.is_err(), "unknown seed id should be Err");
}
#[test]
fn ensure_rejects_seed_app_type_mismatch() {
let db = Database::memory().expect("memory db");
let result =
db.ensure_official_seed_by_id(CLAUDE_DESKTOP_OFFICIAL_PROVIDER_ID, AppType::Claude);
assert!(result.is_err(), "(id, app_type) mismatch should be Err");
}
}
+59 -23
View File
@@ -2,12 +2,56 @@
//!
//! 处理代理配置、Provider健康状态和使用统计的数据库操作
use std::str::FromStr;
use crate::error::AppError;
use crate::proxy::types::*;
use rust_decimal::Decimal;
use super::super::{lock_conn, Database};
pub(crate) const PRICING_SOURCE_RESPONSE: &str = "response";
pub(crate) const PRICING_SOURCE_REQUEST: &str = "request";
pub(crate) fn validate_cost_multiplier(value: &str) -> Result<Decimal, AppError> {
let trimmed = value.trim();
if trimmed.is_empty() {
return Err(AppError::localized(
"error.multiplierEmpty",
"倍率不能为空",
"Multiplier cannot be empty",
));
}
let parsed = Decimal::from_str(trimmed).map_err(|e| {
AppError::localized(
"error.invalidMultiplier",
format!("无效倍率: {value} - {e}"),
format!("Invalid multiplier: {value} - {e}"),
)
})?;
if parsed < Decimal::ZERO {
return Err(AppError::localized(
"error.invalidMultiplier",
format!("无效倍率: {value} - 倍率不能为负数"),
format!("Invalid multiplier: {value} - multiplier cannot be negative"),
));
}
Ok(parsed)
}
pub(crate) fn validate_pricing_source(value: &str) -> Result<&str, AppError> {
let trimmed = value.trim();
if trimmed == PRICING_SOURCE_RESPONSE || trimmed == PRICING_SOURCE_REQUEST {
Ok(trimmed)
} else {
Err(AppError::localized(
"error.invalidPricingMode",
format!("无效计费模式: {value}"),
format!("Invalid pricing mode: {value}"),
))
}
}
impl Database {
// ==================== Global Proxy Config ====================
@@ -103,21 +147,8 @@ impl Database {
app_type: &str,
value: &str,
) -> Result<(), AppError> {
validate_cost_multiplier(value)?;
let trimmed = value.trim();
if trimmed.is_empty() {
return Err(AppError::localized(
"error.multiplierEmpty",
"倍率不能为空",
"Multiplier cannot be empty",
));
}
trimmed.parse::<Decimal>().map_err(|e| {
AppError::localized(
"error.invalidMultiplier",
format!("无效倍率: {value} - {e}"),
format!("Invalid multiplier: {value} - {e}"),
)
})?;
// 确保行存在
self.ensure_proxy_config_row_exists(app_type)?;
@@ -150,7 +181,7 @@ impl Database {
Ok(value) => Ok(value),
Err(rusqlite::Error::QueryReturnedNoRows) => {
self.init_proxy_config_rows().await?;
Ok("response".to_string())
Ok(PRICING_SOURCE_RESPONSE.to_string())
}
Err(e) => Err(AppError::Database(e.to_string())),
}
@@ -162,14 +193,7 @@ impl Database {
app_type: &str,
value: &str,
) -> Result<(), AppError> {
let trimmed = value.trim();
if !matches!(trimmed, "response" | "request") {
return Err(AppError::localized(
"error.invalidPricingMode",
format!("无效计费模式: {value}"),
format!("Invalid pricing mode: {value}"),
));
}
let trimmed = validate_pricing_source(value)?;
// 确保行存在
self.ensure_proxy_config_row_exists(app_type)?;
@@ -911,6 +935,18 @@ mod tests {
}
));
let err = db
.set_default_cost_multiplier("claude", "-0.5")
.await
.unwrap_err();
assert!(matches!(
err,
AppError::Localized {
key: "error.invalidMultiplier",
..
}
));
Ok(())
}
}
@@ -89,6 +89,9 @@ impl Database {
log::info!(
"Rolled up and pruned {deleted} proxy_request_logs (retain={retain_days}d)"
);
// 归档触发了表结构变化,前端 30 天前的统计可能跟着变,
// 通知一次让 UsageDashboard 重拉数据
crate::usage_events::notify_log_recorded();
}
Ok(deleted)
}
+5 -1
View File
@@ -32,7 +32,11 @@ mod schema;
mod tests;
// DAO 类型导出供外部使用
pub(crate) use dao::providers_seed::CLAUDE_DESKTOP_OFFICIAL_PROVIDER_ID;
pub(crate) use dao::providers_seed::{is_official_seed_id, CLAUDE_DESKTOP_OFFICIAL_PROVIDER_ID};
pub(crate) use dao::proxy::{
validate_cost_multiplier, validate_pricing_source, PRICING_SOURCE_REQUEST,
PRICING_SOURCE_RESPONSE,
};
pub use dao::FailoverQueueItem;
use crate::config::get_app_config_dir;
+163 -11
View File
@@ -1205,6 +1205,15 @@ impl Database {
/// 注意: model_id 使用短横线格式(如 claude-haiku-4-5),与 API 返回的模型名称标准化后一致
fn seed_model_pricing(conn: &Connection) -> Result<(), AppError> {
let pricing_data = [
// Claude 4.8 系列
(
"claude-opus-4-8",
"Claude Opus 4.8",
"5",
"25",
"0.50",
"6.25",
),
// Claude 4.7 系列
(
"claude-opus-4-7",
@@ -1476,6 +1485,15 @@ impl Database {
("gpt-4.1", "GPT-4.1", "2", "8", "0.50", "0"),
("gpt-4.1-mini", "GPT-4.1 Mini", "0.40", "1.60", "0.10", "0"),
("gpt-4.1-nano", "GPT-4.1 Nano", "0.10", "0.40", "0.025", "0"),
// Gemini 3.5 系列
(
"gemini-3.5-flash",
"Gemini 3.5 Flash",
"1.50",
"9.00",
"0.15",
"0",
),
// Gemini 3.1 系列
(
"gemini-3.1-pro-preview",
@@ -1485,6 +1503,14 @@ impl Database {
"0.20",
"0",
),
(
"gemini-3.1-flash-lite",
"Gemini 3.1 Flash Lite",
"0.25",
"1.50",
"0.025",
"0",
),
(
"gemini-3.1-flash-lite-preview",
"Gemini 3.1 Flash Lite Preview",
@@ -1553,6 +1579,14 @@ impl Database {
"0.02",
"0",
),
(
"step-3.5-flash-2603",
"Step 3.5 Flash 2603",
"0.10",
"0.30",
"0.02",
"0",
),
// ====== 国产模型 (USD/1M tokens) ======
// Doubao (字节跳动)
(
@@ -1579,6 +1613,14 @@ impl Database {
"0",
"0",
),
(
"doubao-seed-2-0-code-preview-latest",
"Doubao Seed 2.0 Code Preview",
"0.47",
"2.37",
"0",
"0",
),
(
"doubao-seed-2-0-lite",
"Doubao Seed 2.0 Lite",
@@ -1635,15 +1677,15 @@ impl Database {
"DeepSeek V4 Flash",
"0.14",
"0.28",
"0.028",
"0.0028",
"0",
),
(
"deepseek-v4-pro",
"DeepSeek V4 Pro",
"1.68",
"3.36",
"0.14",
"0.435",
"0.87",
"0.003625",
"0",
),
// Kimi (月之暗面)
@@ -1705,8 +1747,8 @@ impl Database {
// GLM (智谱)
("glm-4.7", "GLM-4.7", "0.39", "1.75", "0.04", "0"),
("glm-4.6", "GLM-4.6", "0.28", "1.11", "0.03", "0"),
("glm-5", "GLM-5", "0.72", "2.30", "0", "0"),
("glm-5.1", "GLM-5.1", "0.95", "3.15", "0", "0"),
("glm-5", "GLM-5", "1", "3.2", "0.2", "0"),
("glm-5.1", "GLM-5.1", "1.4", "4.4", "0.26", "0"),
// MiMo (小米)
(
"mimo-v2-flash",
@@ -1717,6 +1759,8 @@ impl Database {
"0",
),
("mimo-v2-pro", "MiMo V2 Pro", "1", "3", "0", "0"),
("mimo-v2.5", "MiMo V2.5", "0.09", "0.29", "0.009", "0"),
("mimo-v2.5-pro", "MiMo V2.5 Pro", "1", "3", "0", "0"),
// Qwen 系列 (阿里巴巴)
("qwen3.6-plus", "Qwen3.6 Plus", "0.325", "1.95", "0", "0"),
("qwen3.5-plus", "Qwen3.5 Plus", "0.26", "1.56", "0", "0"),
@@ -1737,6 +1781,22 @@ impl Database {
"0",
"0",
),
(
"qwen3-coder-480b",
"Qwen3 Coder 480B",
"0.65",
"3.25",
"0",
"0",
),
(
"qwen3-coder-480b-a35b-instruct",
"Qwen3 Coder 480B-A35B Instruct",
"0.65",
"3.25",
"0",
"0",
),
(
"qwen3-coder-flash",
"Qwen3 Coder Flash",
@@ -1792,12 +1852,13 @@ impl Database {
("grok-4", "Grok 4", "3", "15", "0.75", "0"),
(
"grok-code-fast-1",
"Grok Code Fast",
"Grok Build 0.1 (Code Fast Alias)",
"1",
"2",
"0.20",
"1.50",
"0.02",
"0",
),
("grok-build-0.1", "Grok Build 0.1", "1", "2", "0.20", "0"),
("grok-3", "Grok 3", "3", "15", "0.75", "0"),
("grok-3-mini", "Grok 3 Mini", "0.25", "0.50", "0.075", "0"),
// Mistral 系列
@@ -1889,6 +1950,96 @@ impl Database {
Ok(())
}
fn repair_current_model_pricing(conn: &Connection) -> Result<(), AppError> {
let pricing_fixes = [
(
"deepseek-v4-flash",
"DeepSeek V4 Flash",
"0.14",
"0.28",
"0.0028",
"0",
"0.14",
"0.28",
"0.028",
"0",
),
(
"deepseek-v4-pro",
"DeepSeek V4 Pro",
"0.435",
"0.87",
"0.003625",
"0",
"1.68",
"3.36",
"0.14",
"0",
),
(
"glm-5", "GLM-5", "1", "3.2", "0.2", "0", "0.72", "2.30", "0", "0",
),
(
"glm-5.1", "GLM-5.1", "1.4", "4.4", "0.26", "0", "0.95", "3.15", "0", "0",
),
(
"grok-code-fast-1",
"Grok Build 0.1 (Code Fast Alias)",
"1",
"2",
"0.20",
"0",
"0.20",
"1.50",
"0.02",
"0",
),
];
for (
model_id,
display_name,
input,
output,
cache_read,
cache_creation,
old_input,
old_output,
old_cache_read,
old_cache_creation,
) in pricing_fixes
{
conn.execute(
"UPDATE model_pricing SET
display_name = ?2,
input_cost_per_million = ?3,
output_cost_per_million = ?4,
cache_read_cost_per_million = ?5,
cache_creation_cost_per_million = ?6
WHERE model_id = ?1
AND input_cost_per_million = ?7
AND output_cost_per_million = ?8
AND cache_read_cost_per_million = ?9
AND cache_creation_cost_per_million = ?10",
rusqlite::params![
model_id,
display_name,
input,
output,
cache_read,
cache_creation,
old_input,
old_output,
old_cache_read,
old_cache_creation
],
)
.map_err(|e| AppError::Database(format!("修复模型 {model_id} 定价失败: {e}")))?;
}
Ok(())
}
/// 确保模型定价表具备默认数据
pub fn ensure_model_pricing_seeded(&self) -> Result<(), AppError> {
let conn = lock_conn!(self.conn);
@@ -1896,8 +2047,9 @@ impl Database {
}
fn ensure_model_pricing_seeded_on_conn(conn: &Connection) -> Result<(), AppError> {
// 每次启动都执行 INSERT OR IGNORE,增量追加新模型,已有数据不覆盖
Self::seed_model_pricing(conn)
// 每次启动都执行 INSERT OR IGNORE,增量追加新模型;仅修复仍等于旧内置值的定价。
Self::seed_model_pricing(conn)?;
Self::repair_current_model_pricing(conn)
}
// --- 辅助方法 ---
+60
View File
@@ -662,6 +662,66 @@ fn schema_model_pricing_is_seeded_on_init() {
);
}
#[test]
fn model_pricing_seed_repairs_known_outdated_builtin_prices() {
let db = Database::memory().expect("create memory db");
{
let conn = db.conn.lock().expect("lock conn");
conn.execute(
"UPDATE model_pricing
SET input_cost_per_million = '1.68',
output_cost_per_million = '3.36',
cache_read_cost_per_million = '0.14',
cache_creation_cost_per_million = '0'
WHERE model_id = 'deepseek-v4-pro'",
[],
)
.expect("restore old DeepSeek price");
conn.execute(
"UPDATE model_pricing
SET input_cost_per_million = '9',
output_cost_per_million = '9',
cache_read_cost_per_million = '9',
cache_creation_cost_per_million = '0'
WHERE model_id = 'glm-5.1'",
[],
)
.expect("set custom GLM price");
}
db.ensure_model_pricing_seeded()
.expect("ensure pricing seeded");
let conn = db.conn.lock().expect("lock conn");
let deepseek: (String, String, String) = conn
.query_row(
"SELECT input_cost_per_million, output_cost_per_million, cache_read_cost_per_million
FROM model_pricing WHERE model_id = 'deepseek-v4-pro'",
[],
|row| Ok((row.get(0)?, row.get(1)?, row.get(2)?)),
)
.expect("query DeepSeek price");
assert_eq!(
deepseek,
(
"0.435".to_string(),
"0.87".to_string(),
"0.003625".to_string()
)
);
let glm: (String, String, String) = conn
.query_row(
"SELECT input_cost_per_million, output_cost_per_million, cache_read_cost_per_million
FROM model_pricing WHERE model_id = 'glm-5.1'",
[],
|row| Ok((row.get(0)?, row.get(1)?, row.get(2)?)),
)
.expect("query GLM price");
assert_eq!(glm, ("9".to_string(), "9".to_string(), "9".to_string()));
}
#[test]
fn ensure_incremental_auto_vacuum_rebuilds_existing_file_db() {
let temp = NamedTempFile::new().expect("create temp db file");
+123 -44
View File
@@ -244,8 +244,23 @@ fn build_provider_meta(request: &DeepLinkImportRequest) -> Result<Option<Provide
}
/// Build Claude settings configuration
///
/// Merges env from the inline config (if any) with the standard fields from URL params.
/// URL params take priority — they overwrite same-named fields from the config.
/// Non-standard env fields (e.g. `ANTHROPIC_CUSTOM_HEADERS`, `API_TIMEOUT_MS`,
/// `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS`, ...) are preserved as-is so that
/// providers requiring extra environment variables work after deeplink import.
fn build_claude_settings(request: &DeepLinkImportRequest) -> serde_json::Value {
let mut env = serde_json::Map::new();
// Start from the full env block in the inline config (if present), so any
// custom env vars the user passed via `config=<base64-json>` survive the
// import. Falling back to an empty map keeps the previous behavior for
// deeplinks that don't carry a config field.
let mut env = extract_claude_config_env(request).unwrap_or_default();
// Now overwrite / fill in the standard fields from URL params. URL params
// are authoritative because they're what the deeplink builder put on the
// wire — for Claude these are: ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URL,
// ANTHROPIC_MODEL, and the haiku/sonnet/opus model aliases.
env.insert(
"ANTHROPIC_AUTH_TOKEN".to_string(),
json!(request.api_key.clone().unwrap_or_default()),
@@ -283,39 +298,59 @@ fn build_claude_settings(request: &DeepLinkImportRequest) -> serde_json::Value {
json!({ "env": env })
}
/// Decode and extract the `env` object from the deeplink's inline config payload.
///
/// Returns `None` when no config is attached, when the payload can't be
/// decoded/parsed, or when it doesn't contain a Claude-style `env` object.
/// This is a best-effort accessor — we deliberately don't surface parse
/// errors here because `parse_and_merge_config` will have already validated
/// the payload during the merge phase; any failure at this point just means
/// "fall back to URL-param-only behavior".
fn extract_claude_config_env(
request: &DeepLinkImportRequest,
) -> Option<serde_json::Map<String, serde_json::Value>> {
// Only the inline base64 config carries an env block. Remote config_url
// is not implemented yet (see parse_and_merge_config), so nothing else to
// try here.
let config_b64 = request.config.as_ref()?;
// Honor the declared format; default to JSON like parse_and_merge_config does.
let format = request.config_format.as_deref().unwrap_or("json");
if format != "json" {
// Claude config is always JSON in practice. TOML/other formats aren't
// expected on this app path, so don't try to handle them — safer to
// fall back than to risk silently producing the wrong shape.
return None;
}
// Decode the base64 payload. We re-decode here rather than threading the
// already-decoded value through every build_* function, because the call
// graph (parse_and_merge_config is pub and called separately for preview)
// makes signature changes invasive. Decode cost is negligible on this
// one-shot import path.
let decoded = decode_base64_param("config", config_b64).ok()?;
let json_str = std::str::from_utf8(&decoded).ok()?;
let value: serde_json::Value = serde_json::from_str(json_str).ok()?;
// Pull out the env object — same shape as Claude's own settings.json.
value.get("env").and_then(|v| v.as_object()).cloned()
}
/// Build Codex settings configuration
fn build_codex_settings(request: &DeepLinkImportRequest) -> serde_json::Value {
// Generate a safe provider name identifier
let clean_provider_name = {
let raw: String = request
.name
.clone()
.unwrap_or_else(|| "custom".to_string())
.chars()
.filter(|c| !c.is_control())
.collect();
let lower = raw.to_lowercase();
let mut key: String = lower
.chars()
.map(|c| match c {
'a'..='z' | '0'..='9' | '_' => c,
_ => '_',
})
.collect();
// Remove leading/trailing underscores
while key.starts_with('_') {
key.remove(0);
}
while key.ends_with('_') {
key.pop();
}
if key.is_empty() {
"custom".to_string()
} else {
key
}
let provider_display_name = request
.name
.as_deref()
.unwrap_or("custom")
.chars()
.filter(|c| !c.is_control())
.collect::<String>()
.trim()
.to_string();
let provider_display_name = if provider_display_name.is_empty() {
"custom".to_string()
} else {
provider_display_name
};
// Model name: use deeplink model or default
@@ -331,16 +366,20 @@ fn build_codex_settings(request: &DeepLinkImportRequest) -> serde_json::Value {
.trim_end_matches('/')
.to_string();
let provider_display_name = toml_edit::Value::from(provider_display_name.as_str()).to_string();
let model_name = toml_edit::Value::from(model_name.as_str()).to_string();
let endpoint = toml_edit::Value::from(endpoint.as_str()).to_string();
// Build config.toml content
let config_toml = format!(
r#"model_provider = "{clean_provider_name}"
model = "{model_name}"
r#"model_provider = "custom"
model = {model_name}
model_reasoning_effort = "high"
disable_response_storage = true
[model_providers.{clean_provider_name}]
name = "{clean_provider_name}"
base_url = "{endpoint}"
[model_providers.custom]
name = {provider_display_name}
base_url = {endpoint}
wire_api = "responses"
requires_openai_auth = true
"#
@@ -616,12 +655,11 @@ fn merge_codex_config(
request: &mut DeepLinkImportRequest,
config: &serde_json::Value,
) -> Result<(), AppError> {
// Auto-fill API key from auth.OPENAI_API_KEY
// Auto-fill API key from auth.OPENAI_API_KEY or Codex mobile-compatible bearer token.
if request.api_key.as_ref().is_none_or(|s| s.is_empty()) {
if let Some(api_key) = config
.get("auth")
.and_then(|v| v.get("OPENAI_API_KEY"))
.and_then(|v| v.as_str())
let config_str = config.get("config").and_then(|v| v.as_str());
if let Some(api_key) =
crate::codex_config::extract_codex_api_key(config.get("auth"), config_str)
{
request.api_key = Some(api_key.to_string());
}
@@ -767,7 +805,7 @@ mod tests {
name: Some("MyHermes".to_string()),
endpoint: Some("https://api.example.com/v1".to_string()),
api_key: Some("sk-test".to_string()),
model: Some("anthropic/claude-opus-4-7".to_string()),
model: Some("anthropic/claude-opus-4-8".to_string()),
..Default::default()
}
}
@@ -789,7 +827,7 @@ mod tests {
// models array with the deeplink model id
let models = obj.get("models").unwrap().as_array().unwrap();
assert_eq!(models.len(), 1);
assert_eq!(models[0]["id"], "anthropic/claude-opus-4-7");
assert_eq!(models[0]["id"], "anthropic/claude-opus-4-8");
}
#[test]
@@ -823,6 +861,47 @@ mod tests {
assert_eq!(obj.get("api_mode").unwrap(), "chat_completions");
}
#[test]
fn build_codex_settings_uses_custom_key_and_preserves_display_name() {
let request = DeepLinkImportRequest {
resource: "provider".to_string(),
app: Some("codex".to_string()),
name: Some("My \"Relay\"".to_string()),
endpoint: Some("https://api.example.com/v1/".to_string()),
api_key: Some("sk-test".to_string()),
model: Some("gpt-5-codex".to_string()),
..Default::default()
};
let settings = build_codex_settings(&request);
let config_text = settings
.get("config")
.and_then(|value| value.as_str())
.expect("config text");
let parsed: toml::Value = toml::from_str(config_text).expect("valid Codex config");
assert_eq!(
parsed
.get("model_provider")
.and_then(|value| value.as_str()),
Some("custom")
);
let custom_provider = parsed
.get("model_providers")
.and_then(|value| value.get("custom"))
.expect("custom model provider");
assert_eq!(
custom_provider.get("name").and_then(|value| value.as_str()),
Some("My \"Relay\"")
);
assert_eq!(
custom_provider
.get("base_url")
.and_then(|value| value.as_str()),
Some("https://api.example.com/v1")
);
}
#[test]
fn openclaw_still_uses_camel_case() {
// OpenClaw's live config natively uses camelCase; guard against a
+157
View File
@@ -267,6 +267,47 @@ fn test_parse_and_merge_config_claude() {
assert_eq!(merged.model, Some("claude-sonnet-4.5".to_string()));
}
#[test]
fn test_parse_and_merge_config_codex_uses_bearer_token() {
let config_toml = r#"model_provider = "rightcode"
model = "gpt-5-codex"
[model_providers.rightcode]
base_url = "https://rightcode.example/v1"
wire_api = "responses"
experimental_bearer_token = "sk-rightcode"
"#;
let config_json = serde_json::json!({
"auth": {},
"config": config_toml,
})
.to_string();
let config_b64 = BASE64_STANDARD.encode(config_json.as_bytes());
let request = DeepLinkImportRequest {
version: "v1".to_string(),
resource: "provider".to_string(),
app: Some("codex".to_string()),
name: Some("RightCode".to_string()),
config: Some(config_b64),
config_format: Some("json".to_string()),
..Default::default()
};
let merged = parse_and_merge_config(&request).unwrap();
assert_eq!(merged.api_key, Some("sk-rightcode".to_string()));
assert_eq!(
merged.endpoint,
Some("https://rightcode.example/v1".to_string())
);
assert_eq!(
merged.homepage,
Some("https://rightcode.example".to_string())
);
assert_eq!(merged.model, Some("gpt-5-codex".to_string()));
}
#[test]
fn test_parse_and_merge_config_url_override() {
let config_json = r#"{"env":{"ANTHROPIC_AUTH_TOKEN":"sk-old","ANTHROPIC_BASE_URL":"https://api.anthropic.com/v1"}}"#;
@@ -316,6 +357,122 @@ fn test_parse_and_merge_config_url_override() {
);
}
#[test]
fn test_build_claude_provider_preserves_custom_env_fields() {
// Regression test for: deeplink import dropped non-standard env fields
// such as ANTHROPIC_CUSTOM_HEADERS, even though the preview dialog
// showed them. The preview and the actual persisted provider must
// contain the same env keys.
use super::provider::build_provider_from_request;
let config_json = r#"{"env":{
"ANTHROPIC_AUTH_TOKEN":"sk-ant-xxx",
"ANTHROPIC_BASE_URL":"https://api.example.com",
"ANTHROPIC_CUSTOM_HEADERS":"Cookie: session=abc",
"API_TIMEOUT_MS":"3000000",
"CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS":"1",
"ANTHROPIC_DEFAULT_HAIKU_MODEL":"haiku-from-config"
}}"#;
let config_b64 = BASE64_STANDARD.encode(config_json.as_bytes());
let request = DeepLinkImportRequest {
version: "v1".to_string(),
resource: "provider".to_string(),
app: Some("claude".to_string()),
name: Some("My Provider".to_string()),
homepage: Some("https://example.com".to_string()),
endpoint: Some("https://api.example.com".to_string()),
api_key: Some("sk-ant-xxx".to_string()),
icon: None,
// URL param: must win over the same key in config (haiku-from-config)
model: Some("main-model".to_string()),
notes: None,
haiku_model: Some("haiku-from-url".to_string()),
sonnet_model: None,
opus_model: None,
config: Some(config_b64),
config_format: Some("json".to_string()),
config_url: None,
apps: None,
repo: None,
directory: None,
branch: None,
content: None,
description: None,
enabled: None,
usage_enabled: None,
usage_script: None,
usage_api_key: None,
usage_base_url: None,
usage_access_token: None,
usage_user_id: None,
usage_auto_interval: None,
};
let provider = build_provider_from_request(&AppType::Claude, &request).unwrap();
let env = provider.settings_config["env"].as_object().unwrap();
// Custom env fields from `config` must survive import
assert_eq!(env["ANTHROPIC_CUSTOM_HEADERS"], "Cookie: session=abc");
assert_eq!(env["API_TIMEOUT_MS"], "3000000");
assert_eq!(env["CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS"], "1");
// Standard fields from URL params win over config
assert_eq!(env["ANTHROPIC_AUTH_TOKEN"], "sk-ant-xxx");
assert_eq!(env["ANTHROPIC_BASE_URL"], "https://api.example.com");
assert_eq!(env["ANTHROPIC_MODEL"], "main-model");
assert_eq!(env["ANTHROPIC_DEFAULT_HAIKU_MODEL"], "haiku-from-url");
}
#[test]
fn test_build_claude_provider_without_config_unchanged() {
// Backward compatibility: deeplinks without a `config` field still
// produce exactly the same env shape as before — only the standard
// ANTHROPIC_* keys, nothing else.
use super::provider::build_provider_from_request;
let request = DeepLinkImportRequest {
version: "v1".to_string(),
resource: "provider".to_string(),
app: Some("claude".to_string()),
name: Some("Plain".to_string()),
homepage: Some("https://example.com".to_string()),
endpoint: Some("https://api.example.com".to_string()),
api_key: Some("sk".to_string()),
icon: None,
model: None,
notes: None,
haiku_model: None,
sonnet_model: None,
opus_model: None,
config: None,
config_format: None,
config_url: None,
apps: None,
repo: None,
directory: None,
branch: None,
content: None,
description: None,
enabled: None,
usage_enabled: None,
usage_script: None,
usage_api_key: None,
usage_base_url: None,
usage_access_token: None,
usage_user_id: None,
usage_auto_interval: None,
};
let provider = build_provider_from_request(&AppType::Claude, &request).unwrap();
let env = provider.settings_config["env"].as_object().unwrap();
assert_eq!(env["ANTHROPIC_AUTH_TOKEN"], "sk");
assert_eq!(env["ANTHROPIC_BASE_URL"], "https://api.example.com");
// No extras leaked in
assert_eq!(env.len(), 2);
}
// =============================================================================
// Prompt Tests
// =============================================================================
+8 -11
View File
@@ -380,7 +380,7 @@ mod tests {
# Comment line
GOOGLE_GEMINI_BASE_URL=https://example.com
GEMINI_API_KEY=sk-test123
GEMINI_MODEL=gemini-3-pro-preview
GEMINI_MODEL=gemini-3.5-flash
# Another comment
"#;
@@ -395,7 +395,7 @@ GEMINI_MODEL=gemini-3-pro-preview
assert_eq!(map.get("GEMINI_API_KEY"), Some(&"sk-test123".to_string()));
assert_eq!(
map.get("GEMINI_MODEL"),
Some(&"gemini-3-pro-preview".to_string())
Some(&"gemini-3.5-flash".to_string())
);
}
@@ -403,15 +403,12 @@ GEMINI_MODEL=gemini-3-pro-preview
fn test_serialize_env_file() {
let mut map = HashMap::new();
map.insert("GEMINI_API_KEY".to_string(), "sk-test".to_string());
map.insert(
"GEMINI_MODEL".to_string(),
"gemini-3-pro-preview".to_string(),
);
map.insert("GEMINI_MODEL".to_string(), "gemini-3.5-flash".to_string());
let content = serialize_env_file(&map);
assert!(content.contains("GEMINI_API_KEY=sk-test"));
assert!(content.contains("GEMINI_MODEL=gemini-3-pro-preview"));
assert!(content.contains("GEMINI_MODEL=gemini-3.5-flash"));
}
#[test]
@@ -435,7 +432,7 @@ GEMINI_MODEL=gemini-3-pro-preview
# Comment line
GOOGLE_GEMINI_BASE_URL=https://example.com
GEMINI_API_KEY=sk-test123
GEMINI_MODEL=gemini-3-pro-preview
GEMINI_MODEL=gemini-3.5-flash
# Another comment
"#;
@@ -452,7 +449,7 @@ GEMINI_MODEL=gemini-3-pro-preview
assert_eq!(map.get("GEMINI_API_KEY"), Some(&"sk-test123".to_string()));
assert_eq!(
map.get("GEMINI_MODEL"),
Some(&"gemini-3-pro-preview".to_string())
Some(&"gemini-3.5-flash".to_string())
);
}
@@ -619,7 +616,7 @@ KEY_WITH-DASH=value";
let settings = serde_json::json!({
"env": {
"GEMINI_API_KEY": "sk-test123",
"GEMINI_MODEL": "gemini-3-pro-preview"
"GEMINI_MODEL": "gemini-3.5-flash"
}
});
@@ -632,7 +629,7 @@ KEY_WITH-DASH=value";
// 测试缺少 API Key 的非空配置在基本验证中可以通过(用户稍后填写)
let settings = serde_json::json!({
"env": {
"GEMINI_MODEL": "gemini-3-pro-preview"
"GEMINI_MODEL": "gemini-3.5-flash"
}
});
+8 -8
View File
@@ -7,7 +7,7 @@
//!
//! ```yaml
//! model:
//! default: "anthropic/claude-opus-4-7"
//! default: "anthropic/claude-opus-4-8"
//! provider: "openrouter"
//! base_url: "https://openrouter.ai/api/v1"
//!
@@ -19,9 +19,9 @@
//! - name: openrouter
//! base_url: https://openrouter.ai/api/v1
//! api_key: sk-or-...
//! model: anthropic/claude-opus-4-7
//! model: anthropic/claude-opus-4-8
//! models:
//! anthropic/claude-opus-4-7:
//! anthropic/claude-opus-4-8:
//! context_length: 200000
//!
//! mcp_servers:
@@ -185,7 +185,7 @@ fn find_yaml_section_range(raw: &str, section_key: &str) -> Option<(usize, usize
///
/// ```yaml
/// model:
/// default: "anthropic/claude-opus-4-7"
/// default: "anthropic/claude-opus-4-8"
/// provider: "openrouter"
/// ```
fn serialize_yaml_section(key: &str, value: &serde_yaml::Value) -> Result<String, AppError> {
@@ -1219,7 +1219,7 @@ agent:
let mut m = serde_yaml::Mapping::new();
m.insert(
serde_yaml::Value::String("default".to_string()),
serde_yaml::Value::String("claude-opus-4-7".to_string()),
serde_yaml::Value::String("claude-opus-4-8".to_string()),
);
m.insert(
serde_yaml::Value::String("provider".to_string()),
@@ -1233,7 +1233,7 @@ agent:
assert!(result.contains("agent:"));
assert!(result.contains("max_turns"));
// And the model section should be updated
assert!(result.contains("claude-opus-4-7"));
assert!(result.contains("claude-opus-4-8"));
assert!(result.contains("anthropic"));
assert!(!result.contains("gpt-4"));
assert!(!result.contains("openai"));
@@ -1517,7 +1517,7 @@ custom_providers:
assert!(get_model_config().unwrap().is_none());
let model = HermesModelConfig {
default: Some("anthropic/claude-opus-4-7".to_string()),
default: Some("anthropic/claude-opus-4-8".to_string()),
provider: Some("openrouter".to_string()),
base_url: Some("https://openrouter.ai/api/v1".to_string()),
context_length: Some(200000),
@@ -1529,7 +1529,7 @@ custom_providers:
let read_model = get_model_config().unwrap().unwrap();
assert_eq!(
read_model.default.as_deref(),
Some("anthropic/claude-opus-4-7")
Some("anthropic/claude-opus-4-8")
);
assert_eq!(read_model.provider.as_deref(), Some("openrouter"));
assert_eq!(read_model.context_length, Some(200000));
+54
View File
@@ -5,6 +5,7 @@ mod claude_desktop_config;
mod claude_mcp;
mod claude_plugin;
mod codex_config;
mod codex_history_migration;
mod commands;
mod config;
mod database;
@@ -32,6 +33,7 @@ mod settings;
mod store;
mod tray;
mod usage_events;
mod usage_script;
pub use app_config::{AppType, InstalledSkill, McpApps, McpServer, MultiAppConfig, SkillApps};
@@ -335,6 +337,11 @@ pub fn run() {
)?;
}
// 注入 AppHandle 给 usage_events,让无 AppHandle 持有的写日志路径
// 也能向前端推送 `usage-log-recorded`。
// 放在日志系统初始化之后,确保 init 的日志能正常输出。
usage_events::init(app.handle().clone());
// 初始化数据库
let app_config_dir = crate::config::get_app_config_dir();
let db_path = app_config_dir.join("cc-switch.db");
@@ -535,6 +542,49 @@ pub fn run() {
Err(e) => log::warn!("✗ Failed to seed official providers: {e}"),
}
{
let db_for_codex_history_migration = app_state.db.clone();
tauri::async_runtime::spawn_blocking(move || {
match crate::codex_history_migration::maybe_migrate_codex_third_party_history_provider_bucket(
&db_for_codex_history_migration,
) {
Ok(outcome) => {
if let Some(reason) = outcome.skipped_reason {
log::debug!("○ Codex history provider bucket migration skipped: {reason}");
} else {
log::info!(
"✓ Codex history provider bucket migration completed: sources={}, jsonl_files={}, state_rows={}",
outcome.source_provider_ids.len(),
outcome.migrated_jsonl_files,
outcome.migrated_state_rows
);
}
}
Err(e) => {
log::warn!("✗ Codex history provider bucket migration failed: {e}");
}
}
match crate::codex_history_migration::maybe_migrate_codex_provider_template_bucket(
&db_for_codex_history_migration,
) {
Ok(outcome) => {
if let Some(reason) = outcome.skipped_reason {
log::debug!("○ Codex provider template bucket migration skipped: {reason}");
} else if !outcome.migrated_provider_ids.is_empty() {
log::info!(
"✓ Codex provider template bucket migration completed: providers={}",
outcome.migrated_provider_ids.len()
);
}
}
Err(e) => {
log::warn!("✗ Codex provider template bucket migration failed: {e}");
}
}
});
}
// 老用户 / 已确认的路径由 `fresh_install_at_startup` 自行拦截,这里不做写入。
// 字段只由前端在用户点击"我知道了"时 save_settings 回写,语义是"用户显式确认过"。
if !first_run_already_confirmed && fresh_install_at_startup {
@@ -1105,6 +1155,7 @@ pub fn run() {
// subscription quota
commands::get_subscription_quota,
commands::get_codex_oauth_quota,
commands::get_codex_oauth_models,
commands::get_coding_plan_quota,
commands::get_balance,
// New MCP via config.json (SSOT)
@@ -1230,6 +1281,7 @@ pub fn run() {
commands::set_auto_failover_enabled,
// Usage statistics
commands::get_usage_summary,
commands::get_usage_summary_by_app,
commands::get_usage_trends,
commands::get_provider_stats,
commands::get_model_stats,
@@ -1254,6 +1306,8 @@ pub fn run() {
commands::delete_sessions,
commands::launch_session_terminal,
commands::get_tool_versions,
commands::run_tool_lifecycle_action,
commands::probe_tool_installations,
// Provider terminal
commands::open_provider_terminal,
// Universal Provider management

Some files were not shown because too many files have changed in this diff Show More