Compare commits

...

648 Commits

Author SHA1 Message Date
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
Jason 7685ab7049 chore(release): surface ccswitch.io in release notes template
Each tagged release now leads with the canonical official website
in three languages, ensuring every Release page (which is indexed
independently by Google) becomes a dofollow backlink to ccswitch.io.
2026-05-11 15:49:36 +08:00
Jason deeeca1920 docs: add Hermes Agent to README subtitles (en/zh/ja)
Aligns README subtitles with the GitHub repo description that
now lists Hermes Agent as a managed application.
2026-05-11 15:32:23 +08:00
Jason 2fc6753e42 chore(brand): surface ccswitch.io as the sole official website
Add an "Only Official Website" header to the three READMEs, an
About panel button, and a tray menu entry — all pointing to
ccswitch.io. Consolidates brand and SEO signals on the canonical
domain across docs, GUI, and system tray.
2026-05-11 15:25:48 +08:00
Jason 4b384dfe55 perf(proxy): trim per-request hot-path work and db wait
- Guard debug body serialization with `log::log_enabled!`; previously
  serialized the filtered body to a throwaway String on every forward,
  even with debug logging off.
- Skip SSE parse + UTF-8 buffer loop when no usage collector and debug
  is off; the per-chunk `serde_json::from_str::<Value>` ran even in
  pure passthrough mode.
- Add cheap per-app SSE event pre-filter (string `contains`) so usage
  collectors only parse events that could contain usage (e.g. Claude
  `message_start` / `message_delta`).
- Skip non-streaming response body JSON parse when usage logging is
  disabled.
- Move `ProviderRouter::record_result` off the success response path
  via `tokio::spawn` for non-HalfOpen state; that call internally does
  `get_proxy_config_for_app` + `update_provider_health`, two SQLite
  ops that previously blocked TTFB.

Also: dedupe `usage_logging_enabled` (was duplicated in handlers.rs)
and merge `SseUsageCollector::{new, new_filtered}` into a single
constructor that takes `Option<StreamUsageEventFilter>`.
2026-05-11 15:25:48 +08:00
Jason 00a789e7a3 fix(proxy): improve cache hit rate for Codex/Responses requests
prompt_cache_key was falling back to provider.id when the client did not
supply a session, which collapsed every conversation onto a single key
and defeated upstream prefix caching. Only emit the key when a real
client-provided session/thread identity is available; otherwise let the
upstream use its default matching behaviour.

Additional fixes that affect cache stability:
- Canonicalise (sort) JSON keys in outgoing request bodies and in
  tool_call arguments / tool_result content so semantically identical
  requests produce identical byte sequences for upstream prefix caches.
- Exempt JSON Schema property maps (properties, patternProperties,
  definitions, \$defs) from the underscore-prefix filter so user-defined
  schema keys like _id and _meta survive.
- Add a [CacheTrace] debug log with stable hashes for instructions,
  tools, input and include to help diagnose cache misses.
- Thread session_id into the usage logger for request correlation.
2026-05-11 15:25:48 +08:00
Kwensiu aec055a1d1 fix(proxy): drop empty pages from Read tool input (#2472)
* fix(proxy): drop empty pages from Read tool input

* fix(proxy): preserve Read args across duplicate tool starts
2026-05-11 11:32:52 +08:00
Jason e45470cd91 - fix(ci): restore frontend formatting and Linux clippy
- Format Claude Desktop provider presets with Prettier

- Gate platform-specific Claude Desktop path helpers behind cfg
2026-05-10 22:31:47 +08:00
Jason 50a873ca24 chore(icons): add ClaudeCN and RunAPI raster icons
Resized to 512x512 to match the existing extracted-icons size convention
(hermes.png / lemondata.png). Source uploads were oversized (7.3 MB
8635x8635 for ClaudeCN; 800x800 for RunAPI) and would have bloated the
bundle if imported as-is.

Note: not yet wired into index.ts / metadata.ts; register there when
they need to surface in the app UI.
2026-05-10 22:12:57 +08:00
Jason 2ac5e053b4 docs: add RunAPI sponsor entry to README (en/zh/ja)
Insert sponsor row in all three README locales linking to runapi.co.
EN/JA copy adapted from the Chinese original. Banner center-cropped to
the project standard 1920x798 aspect ratio (preserves the logo and
slogan, trims the decorative top/bottom padding) and saved as JPEG to
keep file size reasonable (1.3 MB PNG -> 206 KB JPEG).
2026-05-10 22:06:41 +08:00
Jason a7dd7117e7 docs: add ClaudeCN sponsor entry to README (en/zh/ja)
Insert sponsor row in all three README locales linking to claudecn.top.
EN/JA copy adapted from the Chinese original. Banner normalized to the
project standard sponsor image spec (1920x798 RGB on white background)
and recompressed; alt text unified to "ClaudeCN" across all three files.
2026-05-10 21:49:08 +08:00
Jason b016a17783 docs: use Volcengine logo for Chinese README sponsor entry
Replace byteplus.png with localized huoshan.png (Volcengine/火山引擎)
in README_ZH.md so Chinese readers see the regional brand. EN/JA
README continue to use the BytePlus logo and link to byteplus.com.

The new logo is normalized to the project's standard sponsor image
spec: 1920x798 RGB on a white background.
2026-05-10 16:59:42 +08:00
Jason 10c874afdc docs: add BytePlus sponsor entry to README (en/zh/ja)
Insert sponsor row in all three README locales. EN/JA point to
byteplus.com/modelark; ZH points to volcengine.com/agentplan
(Volcengine being the China-region counterpart). Logo normalized
to the project-standard 1920x798 RGB white background and
recompressed (432K -> 84K).
2026-05-09 23:03:08 +08:00
Jason 5bbd83f7ca feat(claude-desktop): add 44 provider presets translated from Claude Code
- New src/config/claudeDesktopProviderPresets.ts with the Claude Code
  preset list re-shaped into Desktop's three-segment route format
  (routeId / upstreamModel / displayName); excludes OAuth providers,
  AWS Bedrock (no SigV4 support) and KAT-Coder (placeholder URL).
- Non-Claude upstream presets show upstream model id as displayName
  (e.g. deepseek-v4-pro) so the Desktop model list reflects what is
  actually being requested. OpenRouter/TheRouter/PIPELLM keep
  Sonnet/Opus/Haiku since their upstream really is Anthropic Claude.
- Wire ProviderPresetSelector into ClaudeDesktopProviderForm so
  selecting a preset back-fills baseUrl, mode, routes and apiFormat.
- Drop the hard-coded ANTHROPIC_AUTH_TOKEN write in handleSubmit so
  ANTHROPIC_API_KEY presets (LemonData / AiHubMix / Gemini Native)
  save under the correct env key, and clear the opposite key on switch.
- Hide the universal-providers tab for claude-desktop because its
  meta-driven routing has no analogue in the universal flat-env shape.
- Add apps."claude-desktop" i18n key (zh/en/ja) so the dialog tab
  label resolves instead of showing the literal key.
2026-05-09 17:19:09 +08:00
Jason 292c117509 chore(backend): satisfy cargo fmt and clippy --all-targets
- Apply rustfmt diffs in claude_desktop_config.rs
- Allow needless_return on current_platform_paths (cfg-mirrored arms)
- Allow too_many_arguments on RequestForwarder::forward
- Replace `let mut + reassign` with struct literals in tests
  (settings, backup, provider, response_processor)
- Use Path::new instead of PathBuf::from to fix cmp_owned in misc tests
- Replace 3.14 with 3.5 in config test to avoid approx_constant lint
2026-05-09 09:04:01 +08:00
Jason f526d01578 docs: update Micu API links to micuapi.ai 2026-05-08 23:27:41 +08:00
Jason 3cd74400dc docs: update Right Code sponsor description 2026-05-08 23:17:49 +08:00
Jason 950b7dd35f docs: update sponsor logos and listings
- Add ClaudeAPI as new sponsor (all 3 languages)
- Remove ChefShop sponsor entry (all 3 languages)
- Convert shengsuanyun logo from SVG to PNG
- Standardize partner logos to 1920x798 canvas
- Fix ClaudeAPI alt text typo and spacing
- Sync sponsor order across zh/en/ja READMEs
2026-05-08 23:05:13 +08:00
Jason 309f7609a5 refactor(claude-desktop): show badge only for providers requiring routing
Direct-mode providers no longer display a badge since routing is
optional for them. Proxy-mode providers now show "需要路由" / "Requires
routing" to clarify that local routing must be active.
2026-05-08 22:34:46 +08:00
Jason 1fa019026e fix(claude-desktop): match proxy model route without [1M] suffix
Claude Desktop strips the [1M] suffix from model IDs when sending
requests, causing route lookup to fail with "model route is not
configured". Fall back to base-name comparison when exact match misses.
2026-05-08 22:34:46 +08:00
Jason 21b9eb0430 refactor(claude-desktop): simplify model mapping UX
- Remove "Import from Claude" button from main provider list (keep in empty state)
- Remove "Desktop model" column from proxy mode mapping table; route names are now auto-generated
- Rename "upstream model" label to "requested model" and equalize column widths
- Rewrite model mapping hint and toggle description for end-user clarity
- Update validation messages and remove dead i18n keys (routeModelLabel)
2026-05-08 22:34:46 +08:00
Jason 2deee1097b refactor(claude-desktop): align provider form UI with Claude Code
- Rename field labels: "Gateway Base URL" → "API Endpoint", "Bearer Token" → "API Key"
- Change layout from 2-column grid to vertical sections matching Claude Code
- Reuse shared EndpointField component with format-aware amber hint box
- Replace native <datalist> with vendor-grouped ModelDropdown (OpenCode pattern)
- Move Fetch/Add buttons to section headers with compact sm styling
- Extract ModelDropdown to shared module, deduplicate from OpenCodeFormFields
- Extract renderActionButtons helper to eliminate proxy/direct button duplication
- Remove dead i18n keys (gatewayBaseUrl, bearerToken) from all 3 locales
2026-05-08 22:34:46 +08:00
Jason 34698723e3 fix(claude-desktop): remove proxy-stopped status alert
The route toggle in the top-right corner already communicates proxy
state; the extra warning banner was redundant and inconsistent with
other managed apps.
2026-05-08 22:34:46 +08:00
Jason 83f4e1d0ad refactor(claude-desktop): trim duplication in proxy and switch flows
- services/proxy.rs: collapse 10 repeated `OpenCode | OpenClaw | Hermes |
  ClaudeDesktop` match arms into `_` fallthroughs.
- claude_desktop_config.rs: extract a `with_rollback` closure shared by
  apply_provider_to_paths and restore_official_at_paths.
- useProviderActions.ts: replace the triple-nested ternary picking the
  switch-success toast message with a flat let/if/else block.

Net -36 lines. No behavior change; cargo test and pnpm typecheck pass.
2026-05-08 22:34:46 +08:00
Jason 8b3ad9caf9 feat(claude-desktop): add 3P provider switching with proxy gateway
Adds a new ClaudeDesktop AppType that writes Claude Desktop's third-party
inference profile under configLibrary/, sharing _meta.json with other
launchers (Ollama-compatible) so cc-switch can coexist with them.

Two switch modes:
- direct: provider already exposes claude-* / anthropic/claude-* model
  ids on Anthropic Messages, Claude Desktop connects to it directly.
- proxy: cc-switch's local proxy acts as the inference gateway,
  presenting only claude-* route names to Claude Desktop and mapping
  them to real upstream models. Required after Anthropic restricted
  Claude Desktop to claude-family ids.

Backend:
- New module claude_desktop_config with snapshot/rollback, official seed
  bypass, /claude-desktop/v1/{models,messages} routes, and a single
  source of truth for default proxy routes.
- Gateway token persisted in SQLite, validated on every proxied request.
- get_claude_desktop_status surfaces drift signals (stale models,
  missing routes, proxy stopped, base URL mismatch, missing token).

Frontend:
- Slim ClaudeDesktopProviderForm independent from ProviderForm,
  controlled by a top-level appId guard.
- ProviderList banner consumes the status query (5s polling) and
  renders actionable diagnostics.
- ClaudeDesktopRouteToggle in the header to start/stop the local
  gateway without touching takeover state.
- Three-locale i18n synchronised.
2026-05-08 22:34:46 +08:00
Jason e15bfbfe7a fix(proxy): reuse pooled HTTPS connections for non-Anthropic backends
The hyper raw-write path preserves original header casing but rebuilds
TCP+TLS on every request — there is no connection pool — which was the
root cause of slow reverse-proxy throughput.

Only Anthropic-native requests actually need exact header-case
preservation. Route OpenAI/Copilot/Codex/Gemini/codex_oauth requests
through the pooled reqwest client (pool_max_idle_per_host=10,
tcp_keepalive=60s) instead, so warm connections get reused.

Streaming requests get a precise first-byte timeout via
tokio::time::timeout around reqwest's send() (which resolves on
response headers), with the body phase handed off to response_processor.
The streaming-detection helper now also covers Gemini SSE endpoints
and Accept: text/event-stream, not just body.stream.
2026-05-08 22:34:46 +08:00
Dhruv_S b05be92aa1 Fix Codex startup live import duplication (#2590)
* Fix Codex startup live import duplication

* Fix: Prevent duplicate Codex default provider on restart & add startup import tests
2026-05-08 08:41:50 +08:00
bling-yshs f5fbcd0493 feat: return reasoning_content with tool_calls for DeepSeek models (#2543)
* feat: return reasoning_content with tool_calls for DeepSeek models

* fix: correct reasoning_content handling for DeepSeek tool_calls

* test: cover DeepSeek reasoning content round trip

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-05-07 23:03:07 +08:00
Butui Hu 1d44b1ba41 feat(universal-provider): add duplicate action for universal providers (#2416)
Signed-off-by: Hu Butui <hot123tea123@gmail.com>
2026-05-02 21:36:07 +08:00
Jason ddc7b4567e fix(ci): pin Claude review checkout to PR head sha
Prevents `git fetch origin pull/<N>/head:main` failures on fork PRs
whose head branch is also named `main` — using a SHA puts the runner
in detached HEAD so the main ref is free for the action's internal fetch.
2026-05-02 20:33:54 +08:00
Jason 8e59a634fd refactor(theme): drop unused MouseEvent param from setTheme
Now that the view transition animation is gone, setTheme no longer
needs click coordinates. Reduce the API surface to (theme: Theme) =>
void and simplify the call sites in mode-toggle and ThemeSettings.
2026-05-02 20:33:54 +08:00
Jason bc1f9341f4 refactor(theme): remove circular reveal animation for theme switching
The View Transitions API used here crashes WebKitGTK with SIGSEGV on
Linux. Rather than gating document.startViewTransition per platform
(see PR #2502), drop the animation entirely — it's a low-value visual
flourish on a low-frequency action that doesn't justify a permanent
platform branch.

Removes the ::view-transition-* CSS block and the coordinate plumbing
in setTheme. The optional event parameter is kept on the API surface
to keep call sites compiling; they'll be cleaned up in a follow-up
commit.
2026-05-02 20:33:54 +08:00
Probe 72ab8a5cfd fix(proxy): include zero usage in final message delta (#2485) 2026-05-02 17:27:52 +08:00
Yuxuan Sun b61dad4b43 fix(frontend): prevent selecting theme from causing segfault on Linux (#2502) 2026-05-02 17:27:11 +08:00
Jason faa6021c6f fix(ci): drop --max-turns 5 from Claude review args
Cap was too tight — review tasks need 8-15 turns to read files, analyze,
and post results. The first run after the previous prompt change failed
with error_max_turns at turn 6. The disallowedTools list already keeps
the agent in read-only mode, so an explicit turn cap is redundant.
2026-05-02 10:28:47 +08:00
Jason 79d6ede7ae chore(ci): tune Claude review prompt to reduce nitpick noise
Previous prompt produced 5-10 findings per PR including dead-code/style
nits mixed with real bugs. New prompt adds severity tiering, an 80
confidence threshold, an explicit anti-pattern list, a 5-nit cap, and
permits zero-comment LGTM as a valid outcome. Calibration follows
Anthropic Code Review docs and the claude-plugins-official prompt.
2026-05-02 10:26:36 +08:00
dependabot[bot] c2714774b9 chore(deps): bump actions/stale from 9 to 10 (#2520)
Bumps [actions/stale](https://github.com/actions/stale) from 9 to 10.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v9...v10)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-version: '10'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-02 09:44:36 +08:00
dependabot[bot] 026b5dbcb5 chore(deps): bump softprops/action-gh-release from 2 to 3 (#2519)
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2 to 3.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v2...v3)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-02 09:44:32 +08:00
dependabot[bot] 59f7105cbc chore(deps): bump pnpm/action-setup from 5 to 6 (#2518)
Bumps [pnpm/action-setup](https://github.com/pnpm/action-setup) from 5 to 6.
- [Release notes](https://github.com/pnpm/action-setup/releases)
- [Commits](https://github.com/pnpm/action-setup/compare/v5...v6)

---
updated-dependencies:
- dependency-name: pnpm/action-setup
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-02 09:44:28 +08:00
dependabot[bot] 586450a372 chore(deps): bump actions/checkout from 4 to 6 (#2517)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-02 09:43:44 +08:00
Jason 7621b645d1 chore(ci): upgrade Claude review model to Opus 4.7 2026-05-01 23:47:51 +08:00
Jason d75e4e7eb3 fix(ci): add id-token:write permission required by claude-code-action v1 2026-05-01 23:19:22 +08:00
Jason adc7ffefa4 chore(ci): add Claude Code Action for review-only @claude mentions
- Restrict to repo collaborators via author_association check
- Use OAuth token for subscription billing
- Disable Edit/Write tools and set contents:read permission to enforce review-only
2026-05-01 23:07:46 +08:00
Jason bdc4c1e8b8 fix(proxy): derive Claude auth strategy from ANTHROPIC env var name
Anthropic SDK assigns distinct semantics to the two env vars:

- ANTHROPIC_API_KEY    -> x-api-key
- ANTHROPIC_AUTH_TOKEN -> Authorization: Bearer

The Claude adapter previously collapsed both into AuthStrategy::Anthropic
and then emitted Authorization: Bearer regardless, breaking strict
Anthropic-protocol endpoints (Anthropic official, Cloudflare AI Gateway,
OpenCode Go, DashScope) and silently overriding the user's intended auth
scheme.

- claude::extract_auth: infer strategy from env var name
  (ANTHROPIC_AUTH_TOKEN -> ClaudeAuth, ANTHROPIC_API_KEY -> Anthropic),
  matching the precedence already used by extract_key.
- claude::get_auth_headers: split the Anthropic arm so it emits
  x-api-key, while ClaudeAuth and Bearer continue to use Bearer.
- stream_check: reuse ClaudeAdapter::get_auth_headers as the single
  source of truth, replacing the prior "always Bearer + maybe x-api-key"
  double injection that produced auth conflicts and false-negative
  health checks.
- Cover each strategy -> header mapping and env-var precedence with
  new unit tests in claude.rs.

Refs #2368, #2380
2026-05-01 23:07:46 +08:00
Jason 35bce24633 fix(proxy): strip leading billing header from system content (#2350)
Claude Code injects a dynamic `x-anthropic-billing-header` line at the
start of `system` content. Its rotating `cch=` token was forwarded into
OpenAI Responses `instructions` and Chat system messages, which broke
upstream prefix prompt cache reuse — a stable ~95k-token prefix was
getting re-charged on every request.

Strip only the leading occurrence in both anthropic_to_openai and
anthropic_to_responses; later occurrences are preserved so user-authored
prompt text containing the same string is not lost.
2026-05-01 23:07:46 +08:00
Jason 518d945eb8 chore(usage): drop Hermes Agent tracking integration
Hermes aggregates all in-process API calls into a single sessions row
with the `model` field locked to the initial model, so the usage
dashboard cannot cleanly surface per-call billing context. Two rounds
of UI workarounds (raw mapping, then `<model> @ <host>` display) did
not resolve the user-facing confusion, so the whole tracking
integration is dropped for now.

Removes session_usage_hermes service (and its 17 tests), sync wiring
in commands/usage.rs and lib.rs, _hermes_session/hermes_session
entries in usage_stats SQL (provider_name_coalesce CASE and
effective_usage_log_filter IN clause), frontend Tab/banner/dropdown/
icon entries, and four i18n keys per locale.

Hermes app integration outside usage tracking (proxy routing,
session manager, config) is preserved. Pre-existing hermes rows in
proxy_request_logs are left as orphans — filtered out by the
updated SQL and never surfaced in the UI.
2026-05-01 23:07:46 +08:00
BillSaul 7b667f7a44 feat: persist Tauri window state (#2377)
Add the window-state plugin and explicitly save size and position across app exit, restart, and lightweight-mode transitions.
2026-05-01 17:51:25 +08:00
xpfo 295dd9a944 fix(proxy): preserve Vertex AI full URLs (#2415) 2026-05-01 17:46:10 +08:00
makoMakoGo 064b339bab fix(claude): persist max effort via env (#2493) 2026-05-01 17:41:32 +08:00
jimmy db66348ff8 feat(providers): add Baidu Qianfan Coding Plan for Claude Code (#2322)
* feat(providers): add baidu qianfan coding plan presets

* refactor(providers): align qianfan presets with existing format

* chore(providers): narrow qianfan coding plan scope
2026-05-01 17:35:18 +08:00
Coconut-Fish 7f0c7b11e5 feat(tray): add tooltip to tray icon for better user experience (#2417)
Co-authored-by: Copilot <copilot@github.com>
2026-04-30 22:41:54 +08:00
涂瑜 fafc122d82 fix(coding-plan): correct zhipu weekly tier name by reset time (#2420)
Zhipu's `data.limits[]` returns 1 entry for legacy plans (subscribed
before 2026-02-12) and 2 entries for current plans. Previously every
TOKENS_LIMIT entry was hardcoded as `five_hour`, so the weekly bucket
was rendered with the 5-hour i18n label.

Sort TOKENS_LIMIT entries by nextResetTime ascending and assign
`five_hour` to index 0, `weekly_limit` to index 1. Legacy plans
naturally degrade to a single five_hour tier.

Also harden the parser: case-insensitive type match (defends against
upstream casing changes), reuse TIER_FIVE_HOUR/TIER_WEEKLY_LIMIT
constants, and add 8 unit tests covering both plan shapes plus
defensive edge cases.
2026-04-30 22:38:34 +08:00
magucas 693c36a12a fix(dashscope): enhance usage parsing robustness to prevent VSCode cr… (#2425)
* fix(dashscope): enhance usage parsing robustness to prevent VSCode crashes

Enhanced build_anthropic_usage_from_responses() to handle null, missing, empty,
and partial usage fields gracefully. This prevents VSCode Extension crashes with
"Cannot read properties of null (reading 'output_tokens')" when connecting to
DashScope (Alibaba Cloud Bailian) models.

Changes:
- Added defensive null checks and empty object detection
- Implemented OpenAI field name fallbacks (prompt_tokens/completion_tokens)
- Added comprehensive logging for malformed usage scenarios
- Fixed streaming SSE event handlers with null-safe usage access
- Preserved cache token fields even when input/output tokens are missing

This ensures the proxy never crashes on malformed Responses API usage objects,
returning valid Anthropic-compatible usage structures (input_tokens/output_tokens)
in all cases.

* fix(proxy): tighten Responses API usage fix per review

- Drop redundant fallback in streaming.rs Chat Completions path; the
  existing if-let-Some guard already prevents usage:null, so the extra
  layer was dead code and caused a fmt-breaking indentation issue.
- Demote partial-usage warn to debug. Streaming chunks legitimately
  arrive with partial token counts and the warn-level log was noisy.
- Rewrite CHANGELOG entry: reference #2422, broaden scope from
  DashScope-only to all api_format=openai_responses users (Codex OAuth
  is the strongest signal; DashScope compatible-mode/v1/responses is
  the original report).
- cargo fmt to clear 12 formatting differences vs main.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-04-30 22:37:54 +08:00
ayxwi 7965862e66 Make import existing side-effect free (#2429)
Co-authored-by: Xvvln <3369759202@qq.com>
2026-04-30 21:59:47 +08:00
eclipsehx 1c69269405 fix(codex): skip environment_context injection when extracting session title (#2439)
Co-authored-by: xiaohan1 <xiaohan1@chinaums.com>
2026-04-30 12:45:42 +08:00
Cao Xin 15497b0e41 fix(session): hide Codex subagent sessions (#2445) 2026-04-30 12:22:21 +08:00
Hulk 7c8720bd3f fix(terminal): prevent iTerm fallback on cold launch (#2448) 2026-04-30 12:03:46 +08:00
Chris Chen 8084bfafa8 fix(config): sort JSON keys alphabetically for deterministic output (#2469)
* fix(config): sort JSON keys alphabetically for deterministic output

Ensures settings.json keys are written in sorted order, preventing
non-deterministic git diffs when switching configs.

* test(config): add unit tests for sort_json_keys and fix formatting

Cover top-level sort, nested recursion, array order preservation,
primitive pass-through, empty collections, and the core determinism
guarantee (different insertion orders must yield identical output).

Also fix line-length in write_json_file flagged by `cargo fmt --check`.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-04-30 11:53:32 +08:00
tison 151af0ffa3 Fix log message for session usage codex (#2473)
* Fix log message for session usage codex

* Fix comments in session_usage_codex.rs
2026-04-30 11:07:06 +08:00
tison 608ee35ecd feat: support launch warp and execute session (#2466)
* feat: support launch warp and execute session

Signed-off-by: tison <wander4096@gmail.com>

* other wires

Signed-off-by: tison <wander4096@gmail.com>

* for launch with provider

Signed-off-by: tison <wander4096@gmail.com>

* fixup indirection

Signed-off-by: tison <wander4096@gmail.com>

* clippy

Signed-off-by: tison <wander4096@gmail.com>

* address comments

Signed-off-by: tison <wander4096@gmail.com>

---------

Signed-off-by: tison <wander4096@gmail.com>
2026-04-30 10:33:50 +08:00
SaladDay a1e6c3b65d 修复 Codex 切换供应商后历史记录变化 (#2349)
* Keep Codex history stable across provider switches

* Restore template Codex provider id when backfilling live config

Backfill writes the current Codex live config back to the previous
provider's stored template after a switch. Because the live file now
carries a normalized stable model_provider id, the previous provider's
template would lose its own provider-specific id (and any matching
[profiles.*] references) on every subsequent switch.

Reverse the normalization at backfill time by rewriting model_provider,
the active model_providers section, and matching profile references back
to the template's original id.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-04-30 09:54:25 +08:00
Jason eb304232b3 docs(readme): add PatewayAI sponsor across zh/en/ja
Also clean up a dangling <tr> tag in README_JA.md.
2026-04-29 22:57:23 +08:00
Jason f061b777b7 feat(usage): add Hermes Agent tracking + fix zero-cost bug + perf
Hermes:
- Parse ~/.hermes/state.db sessions (incl. profiles/*/state.db) into
  proxy_request_logs with data_source='hermes_session', WAL-aware
  incremental sync, Hermes-reported cost preferred over model_pricing
  fallback

Zero-cost bug (dashboard showed \$0 totals):
- GPT-5.5 family default pricing (~83% of affected rows used GPT-5.5)
- find_model_pricing_row: ASCII-lowercase normalization so
  "OpenAI/GPT-5.5@HIGH" matches seeded "gpt-5.5"
- Startup cost backfill in async task: scan rows where total_cost <= 0
  but tokens > 0, recompute via model_pricing in a single transaction

Performance:
- Add (app_type, created_at DESC) covering index for dashboard range
  queries
- Add expression index on COALESCE(data_source, 'proxy') so dedup EXISTS
  subqueries use index lookup instead of full scan; drop superseded
  idx_request_logs_dedup_lookup

Refactor:
- row_to_request_log_detail helper (3-way de-dup; fixes cost_multiplier
  \"1\" vs \"1.0\" drift between callers)
- Promote get_sync_state/update_sync_state to shared session_usage
  module (4 copies -> 1)
- run_step helper in lib.rs replaces 9 if-let-Err blocks
- maybe_backfill_log_costs returns bool to skip duplicate total_cost
  parsing in caller
2026-04-29 22:41:46 +08:00
Jason 2ee7cb4101 fix(usage): prevent double-counting between proxy and session-log sources
Proxy writes and session-log sync wrote to proxy_request_logs with
mismatched request_ids: only Claude on a native Anthropic backend used the
shared `session:{message_id}` key. Codex/Gemini and Claude-through-OpenAI
providers always produced distinct ids, so primary-key dedup never fired
and every real request was recorded twice.

Adds a 7-dim fingerprint dedup (app_type, 4 token counts, 2xx status,
model with case-insensitive match, ±10min window) wired into three layers:

- Write path: should_skip_session_insert() blocks duplicate session rows
  before INSERT, unifying the previously-divergent Claude/Codex/Gemini
  paths through a single DedupKey-based helper.
- Read path: effective_usage_log_filter() excludes already-covered session
  rows from every aggregation query.
- Rollup path: same filter applied so usage_daily_rollups never absorbs
  duplicates.

Also adds a covering index (idx_request_logs_dedup_lookup) so the EXISTS
subquery stays index-only, and a transform.rs regression test that pins
openai_to_anthropic id preservation - the missing piece that lets
Claude+OpenAI-compatible providers reuse the session: id scheme.
2026-04-29 22:41:46 +08:00
Jason bcf8434c1f chore(kimi): update Kimi For Coding website URL to /code/docs/
Sync the preset's websiteUrl from the legacy /coding/docs/ path to
the current /code/docs/ path across all four app presets (claude,
hermes, openclaw, opencode).
2026-04-29 22:41:46 +08:00
Jason d2556be5b9 fix(balance): show USD on SiliconFlow international site (was CNY)
The query_siliconflow function received an is_cn flag that only switched
the request domain (.cn vs .com) but the response builder hardcoded
unit="CNY" for both sites. International users at api.siliconflow.com
saw their USD balance labelled as CNY. Now unit and plan_name follow
is_cn, so the EN site shows USD and "SiliconFlow (EN)".
2026-04-29 22:41:46 +08:00
Jason 5b6339d78c chore(codex): hide 1M context window toggle in provider edit form
Codex models no longer accept model_context_window=1000000, so the
toggle and its paired auto-compact-limit input are commented out in
the provider edit form. State hooks, helper imports, and i18n keys
are preserved so the UI can be restored in one batch if upstream
support returns. The TOML editor remains visible, allowing manual
edits if needed.
2026-04-29 22:41:46 +08:00
codeasier 21e2d68d76 fix(proxy): preserve scoped reasoning_content for tool calls (#2367)
- Preserve `reasoning_content` for Kimi/Moonshot OpenAI Chat compatibility paths.
- Keep generic OpenAI-compatible requests free of non-standard `reasoning_content` fields.
- Continue skipping thinking-only assistant messages.
- Add regressions for generic skip and Kimi/Moonshot preservation behavior.
2026-04-28 17:08:59 +08:00
codeasier 6441bc5c01 fix(proxy): dedupe streaming message_delta (#2366)
- Deduplicate repeated upstream `finish_reason` chunks so only one Anthropic `message_delta` is emitted.
- Preserve late `choices: []` usage-only chunks before sending the final `message_delta`.
- Keep stream error paths from emitting successful terminal events.
- Add regressions for duplicate finish reasons, usage-only chunks, missing `[DONE]`, and truncated streams.
2026-04-28 17:08:43 +08:00
tison 4536b95ac9 refactor: prefer default shell in commands::try_get_version (#2286)
Signed-off-by: tison <wander4096@gmail.com>
2026-04-25 17:00:36 +08:00
allen_xln 85f0be9e1d feat(provider-form): soften validation with "save anyway" prompt (#2307)
* feat(provider-form): soften business-rule validation with "save anyway" prompt

Refactor handleSubmit so empty-field / missing-item validations (provider
name, endpoint, API key, opencode model, template variables, provider key
required) no longer hard-reject with toast.error. Instead they are collected
into an issues list and presented via a ConfirmDialog; the user can cancel
or choose "Save anyway" to proceed.

Integrity constraints stay as hard rejections:
- providerKey regex / duplicate (would corrupt other providers)
- Copilot / Codex OAuth not authenticated (no token, cannot establish)
- omo Other Fields JSON not an object / parse failure

This aligns the frontend with the backend's existing "relaxed save / strict
switch" split (see gemini_config.rs: validate_gemini_settings vs
validate_gemini_settings_strict) and unblocks legitimate configs such as
AWS Bedrock, Vertex AI, and custom Gemini base URLs that the UI previously
refused to save.

Refs: #2196, #1204

* fix(provider-form): address review feedback on soft-validation

P1: move empty providerKey back to hard rejection for OpenCode / OpenClaw /
Hermes. Since providerKey is the primary identity for these apps and the
mutations layer throws "Provider key is required" when absent, letting users
click "save anyway" would surface a generic error toast instead of a
precise, actionable one. Treat empty providerKey as an integrity constraint
alongside regex / duplicate checks.

P2: give the soft-confirm submit path its own submitting state. The
confirm-dialog path bypassed react-hook-form's isSubmitting lifecycle, so
slow or failing saves left the outer submit button responsive and could
spawn unhandled rejections. Now the confirm handler awaits performSubmit
inside try/catch/finally, uses an isConfirmSubmitting flag to gate both
confirm and cancel clicks, and folds the flag into the outer disabled
state and onSubmittingChange callback.

Refs: #2307 review comments

* chore(clippy): use push for single char '…' in truncate_body

Clippy 1.95 added single_char_add_str which flagged the push_str("…")
in truncate_body. Rebased onto latest upstream/main and applied the
suggested fix so the Backend Checks clippy job passes.

Unrelated to this PR's core changes; bundled in so the PR is mergeable
without waiting for a separate upstream fix.

---------

Co-authored-by: Allen <allen@AllenMacBook-M4-Pro.local>
2026-04-25 09:28:28 +08:00
Jason 08e2b29b8a feat(compshare): add Coding Plan preset across claude/codex/hermes/openclaw
Introduce a dedicated "Compshare Coding Plan" variant pointing to
https://cp.compshare.cn (with /v1 for OpenAI-compatible apps). Reuses
the existing ucloud icon and promotion copy, while adding a new
providerForm.presets.ucloudCoding key in zh/en/ja.
2026-04-24 23:57:04 +08:00
Jason 948fa87ae3 docs(readme): update Crazyrouter $2 credit claim flow across zh/en/ja
The $2 sign-up credit is no longer granted automatically — users now
need to contact Crazyrouter's customer support after registering to
claim it. Sync all three README variants and drop the outdated
"instantly / 即時進呈" wording. Also fix a stray double space in the
English sentence.
2026-04-24 23:38:55 +08:00
Jason 4833d24d83 docs(readme): refresh Compshare sponsor blurb across zh/en/ja
Update the Compshare entry to describe the new offering: per-use
domestic-model Coding Plan packages with officially-relayed overseas
models, replacing the outdated "60-80% off" discount wording. Keep all
three README variants in sync.
2026-04-24 23:34:46 +08:00
Jason 221af57a49 fix(readme): flatten LionCC logo onto white background
The original lioncc.png had a transparent background, which made the
black "LionCC" wordmark blend into GitHub's dark-mode page and become
hard to read. Composite the artwork onto solid white so the logo stays
legible in every theme without changing any markup.
2026-04-24 23:30:25 +08:00
Jason b1f9ce4653 feat(deepseek): switch presets to V4 (flash/pro) and add pricing
DeepSeek released V4 flash/pro; legacy IDs deepseek-chat / deepseek-reasoner
now alias to deepseek-v4-flash and will be deprecated.

- Update claude/hermes/opencode/openclaw presets to v4-pro / v4-flash,
  context 128K -> 1M; Claude Anthropic-compat endpoint routes OPUS/SONNET
  to v4-pro and HAIKU to v4-flash, plus an explicit modelsUrl override.
- Seed deepseek-v4-flash ($0.14/$0.28 per 1M) and deepseek-v4-pro
  ($1.68/$3.36 per 1M) into model_pricing; older v3.x / chat / reasoner
  rows kept for historical usage stats (INSERT OR IGNORE).
- Refresh user-manual (zh/en/ja) pricing table and note that legacy model
  IDs are billed at v4-flash rates.
2026-04-24 23:24:37 +08:00
Jason 67dbfc0a8c fix(model-fetch): support /models for Anthropic-compat subpath providers
Providers like DeepSeek, Kimi, Zhipu GLM and MiniMax expose the
Anthropic-compatible API on a subpath (e.g. /anthropic) while the
OpenAI-style /models endpoint lives at the API root. The previous
heuristic blindly appended /v1/models to the Base URL, so every such
provider returned 404 and the UI mislabeled it as "provider does not
support fetching models".

Backend now generates a candidate list and tries them in order:
preset override -> baseURL /v1/models -> stripped-subpath /v1/models ->
stripped-subpath /models. Non-404/405 responses (auth, network) stop
immediately so we never retry against hostile status codes. Known
compat suffixes are kept in a length-descending constant so the
longest match wins; response bodies are truncated to 512 chars to
avoid HTML 404 pages bloating the error string.

Preset type gains an optional modelsUrl (DeepSeek points at
https://api.deepseek.com/models). Frontend threads the override
through fetchModelsForConfig when the current Base URL still matches
the preset default. A new fetchModelsEndpointNotFound i18n key
replaces the misleading "not supported" toast for exhausted-candidate
and 404/405 cases (zh/en/ja).
2026-04-24 23:20:10 +08:00
Jason fcd83ee30d fix(copilot): resolve Claude model IDs against live /models list
Copilot upstream returns model_not_supported when the client sends
dash-form Claude IDs (claude-sonnet-4-6, claude-sonnet-4-6[1m]) while
/models only accepts dot form (claude-sonnet-4.6, -1m suffix).

- Add copilot_model_map: syntax normalize (dash->dot, [1m]->-1m) plus
  live /models exact match and family-version fallback, reusing the
  existing 5 min auth cache. Returns None when the whole family is
  absent so upstream surfaces an explicit error instead of silently
  switching families.
- Wire into forwarder Copilot hook; runs before anthropic_to_openai
  conversion.
- Default Opus slot in the Copilot preset maps to Sonnet 4.6: Pro
  dropped all Opus on 2026-04-20 and Pro+ bills Opus 4.7 at 7.5x.
  Users who want real Opus can switch manually in the UI.

Refs: https://github.com/farion1231/cc-switch/issues/2016
2026-04-24 22:58:58 +08:00
Jason c002688a84 chore(release): bump version to 3.14.1
- Add v3.14.1 release notes (en/zh/ja) covering tray usage visibility,
  Codex OAuth stability fixes, Skills import/install reliability, and
  removal of the Hermes config health scanner
- Cut [Unreleased] into [3.14.1] in CHANGELOG with PR references
- Bump version in package.json, Cargo.toml, Cargo.lock, tauri.conf.json
2026-04-23 21:17:30 +08:00
Jason 4737158439 feat(tray): show coding-plan usage for Kimi / Zhipu / MiniMax
dc04165f surfaced tray usage badges for Claude/Codex/Gemini official
OAuth only. Chinese coding-plan providers already expose 5h + weekly
windows through coding_plan::get_coding_plan_quota, but two gaps kept
the tray from rendering them.

- format_script_summary read only data.first(), truncating the tier-
  flattened UsageResult to a single window. Detect plan_name matching
  TIER_FIVE_HOUR / TIER_WEEKLY_LIMIT and emit the "🟢 h12% w80%" layout
  used by format_subscription_summary; worst utilization drives the
  emoji. Copilot / balance / custom scripts keep the legacy single-
  bucket output via fallback.

- usage_script previously required manual activation through
  UsageScriptModal. Auto-inject meta.usage_script on Claude provider
  creation when ANTHROPIC_BASE_URL matches a known coding plan, so the
  tray lights up without the user opening the modal. Does not overwrite
  existing usage_script on update.

Extract the URL route table out of UsageScriptModal into a shared
codingPlanProviders module so the modal, the creation hook, and the
Rust coding_plan::detect_provider mirror all agree on one list.
Add TIER_WEEKLY_LIMIT alongside TIER_FIVE_HOUR and a createUsageScript()
factory to collapse the duplicated default fields across four call
sites and drop the remaining stringly-typed tier names.
2026-04-23 17:34:39 +08:00
Jason cdcc423122 refactor(hermes): drop config health check scanner
The Hermes config.yaml schema has stabilized and users have migrated to
the current provider fields, so the value of scanning for model.provider
dangling references, custom_providers shape errors, v12 migration residue
etc. no longer justifies the maintenance surface — and the scan produces
false positives when users keep some providers under Hermes' v12+
providers: dict (Hermes' runtime merges both shapes, but CC Switch's
scanner only looked at the list form).

Removes the whole HermesHealthWarning type, scan_hermes_config_health
command, HermesHealthBanner React component, useHermesHealth hook,
warnings field on HermesWriteOutcome, and the three helper functions
(yaml_as_non_empty_str, collect_mapping_string_keys, hermes_warning)
that only served the scanner. Drops the matching i18n keys in
zh/en/ja and the fixInWebUI button label that only the banner used.
2026-04-23 16:18:38 +08:00
涂瑜 dc04165f18 feat(tray): show cached provider usage in the system tray menu (#2184)
* feat: add Rust-side write-through usage cache

Introduce an in-memory UsageCache on AppState that the existing usage
query commands populate on success. The cache is read-only to the rest
of the app today; the next commit consumes it from the tray menu.

- New services::usage_cache module with split maps: subscription keyed
  by AppType, script keyed by (AppType, provider_id).
- AppType gains Eq + Hash so it can be used as a HashMap key.
- commands::subscription::get_subscription_quota now takes State<AppState>
  and writes through on success (signature change is invisible to the
  frontend — Tauri injects State automatically).
- commands::provider::queryProviderUsage body extracted into an inner
  async fn; the public command wraps it with write-through, covering
  Copilot, coding-plan, balance, and generic script paths uniformly.

Cache is in-memory only; auto-query interval and the upcoming tray
refresh action rebuild it after restarts.

* feat(tray): surface cached usage in the system tray menu

Read UsageCache populated by the previous commit and render it in three
places, scoped to whatever TRAY_SECTIONS covers (Claude/Codex/Gemini):

1. Inline suffix on each provider submenu item
   "AnyProvider  · 🟢 5h 18% / 7d 23%"
2. Disabled summary row per visible app under "Show Main"
   "Claude · Anthropic Official · 🟢 5h 18% / 7d 23%"
3. "Refresh all usage" menu item that triggers get_subscription_quota +
   queryProviderUsage for every applicable provider, then rebuilds the
   tray menu via the existing refresh_tray_menu path.

Color encoding uses emoji (🟢 <70% / 🟠 70-89% / 🔴 ≥90%) since Tauri 2
tray labels are plain text. Missing cache entry leaves the label
unchanged — tray never issues network requests when opened. Three new
i18n-ready strings live in TrayTexts (en/zh/ja), following the existing
pattern for tray text.

Closes #2178.

* feat(usage): bridge tray UsageCache writes to frontend React Query

Why: tray hover triggers backend-only refresh that wrote to UsageCache but
never notified the frontend, leaving main UI stale while tray showed fresh
numbers. Emit a payload-carrying event after each cache write so React Query
can setQueryData directly, keeping both views in sync without duplicate fetches.

* fix(tray): skip hidden apps on hover refresh and drop stale disabled-script cache

Address P2 findings from automated review on #2184:

1. refresh_all_usage_in_tray now filters TRAY_SECTIONS by settings.visible_apps
   before scheduling subscription/script queries, matching create_tray_menu and
   preventing wasted external API calls (and rate-limit/auth-error log noise)
   for apps the user has hidden.

2. format_usage_suffix only trusts the script cache when provider.meta.usage_script
   is still enabled; when a script is disabled/removed the cached suffix is now
   invalidated so the tray label no longer shows stale data indefinitely.

* refactor: consolidate codex provider helpers and fix test semantics

- Add Provider::is_codex_oauth() and Provider::codex_fast_mode_enabled()
  to eliminate duplicated meta extraction in claude.rs and stream_check.rs
- Fix non-codex-oauth tests to pass codex_fast_mode=false (was true, harmless
  but semantically misleading)
- Remove redundant is_dir() guard after resolve_skill_source_dir already
  guarantees the returned path is a directory

* style: apply cargo fmt

* fix(tray): reflect failed refreshes in cache and support Gemini flash-lite

Follow-up to the tray usage-display feature addressing review feedback:

- Write snapshots for both Ok(success:false) and Err paths in
  queryProviderUsage / get_subscription_quota so stale success data
  no longer persists across failed refreshes; the original Err is
  still returned to the frontend onError handler.
- Include gemini_flash_lite tier in the tray summary with label "l".
  Matches the frontend SubscriptionQuotaFooter and keeps the worst
  emoji correct when lite is the highest utilization.
- Add TIER_GEMINI_PRO / _FLASH / _FLASH_LITE constants in
  services/subscription.rs and reuse them in classify_gemini_model
  and sort_order.
- Extract Provider::has_usage_script_enabled() to remove the
  duplicated meta.usage_script chain at two call sites.
- Use db.get_provider_by_id in refresh_all_usage_in_tray instead of
  materialising the full provider map, and parallelise subscription
  and script futures via futures::future::join.
- Narrow refresh_all_usage_in_tray to each section's effective
  current provider (script if enabled, else subscription when the
  provider is official). Hover refreshes now issue at most
  TRAY_SECTIONS.len() outbound requests.
- Add 10 unit tests in tray::tests covering Claude/Codex h/w dispatch,
  Gemini p/f/l dispatch (including lite-only and lite-worst cases),
  and success/failure guards.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-04-23 16:17:15 +08:00
Coconut-Fish 010b163430 Fix/一键配置失效 (#2249)
* style(FailoverQueueManager): 显示供应商备注信息

* style(FailoverQueueItem): 添加供应商备注字段以支持备注信息显示

* style(FailoverQueueManager): 显示供应商备注信息

* style(FailoverQueueItem): 添加供应商备注字段以支持备注信息显示

* style(FailoverQueueManager): 更新供应商备注信息的显示样式

* style(FailoverQueueItem): 添加条件序列化以优化供应商备注字段

* fix: 优化模型状态管理,确保配置更新时正确引用最新设置

* fix(skill): improve error handling for skill source directory resolution

Co-authored-by: Copilot <copilot@github.com>

* fix(gemini): simplify project directory retrieval in scan_sessions function

* fix(useModelState): optimize latestConfigRef assignment in useModelState hook

* fix(useModelState): remove unnecessary blank line in useModelState hook

---------

Co-authored-by: Copilot <copilot@github.com>
2026-04-23 15:36:03 +08:00
santugege 59735f976b fix(skill): resolve root-level repo skills consistently (#2231)
Co-authored-by: luoyaoqi <luoyaoqi@robam.com>
2026-04-23 12:21:47 +08:00
Jesus Díaz Rivas 10e0772d8c feat: Add Codex OAuth FAST mode toggle (#2210)
* Add Codex OAuth FAST mode toggle

* fix(codex-oauth): default FAST mode to off to avoid surprise quota burn

service_tier="priority" consumes ChatGPT subscription quota at a higher
rate. Users must now opt in explicitly rather than inherit FAST mode
silently when this feature ships.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-04-23 12:05:17 +08:00
lif 444c123ad0 [codex] Stabilize Codex OAuth cache routing (#2218)
* Stabilize Codex OAuth cache routing

Codex OAuth-backed Claude proxy requests now reuse a client-provided session identity for prompt cache routing and send Codex-like session headers when that identity exists. Generated proxy UUIDs are intentionally excluded so they do not fragment cache locality.\n\nThe same path exposed two runtime issues during validation: rustls needed an explicit process crypto provider, and Codex OAuth can return Responses SSE even when the original Claude request is non-streaming. Those are handled so cache-routed requests can complete instead of panicking or being parsed as JSON.\n\nConstraint: Official Codex uses conversation identity and Responses session headers for prompt cache routing.\nRejected: Always use generated proxy session IDs | generated IDs change per request and reduce cache reuse.\nConfidence: medium\nScope-risk: moderate\nDirective: Do not remove the client-provided-session guard unless generated session IDs become stable per conversation.\nTested: cargo test codex_oauth\nTested: Local dev app health check on 127.0.0.1:15721\nTested: Local proxy logs showed cache_read_tokens after restart\nNot-tested: Full cargo test without local cc-switch port conflict\nRelated: #2217

* feat(proxy): aggregate forced Codex OAuth SSE into JSON for non-streaming clients

Narrow override on top of #2235's streaming fallback.

Codex OAuth always forces upstream openai_responses into SSE, even
when the original Claude request is stream:false. #2235 handles this
by routing such responses through the streaming transform so the
client receives text/event-stream — that avoids the 422 that JSON
parsing would produce, and it also protects any other provider that
unexpectedly returns SSE (the response.is_sse() guard).

But for Claude SDK callers that sent stream:false, returning SSE
still violates the Anthropic non-streaming contract. This commit
adds an override on exactly one combination — non-streaming client
+ codex_oauth + openai_responses — to aggregate the upstream
Responses SSE into a synthetic Responses JSON and then run the
regular responses_to_anthropic non-streaming transform. All other
paths, including the generic response.is_sse() fallback, remain
on the streaming path from #2235.

The aggregator reuses proxy::sse::take_sse_block / strip_sse_field,
which support both \n\n and \r\n\r\n delimiters; a hand-rolled
split("\n\n") would silently fail on real HTTPS upstreams.

Tests cover the happy path, CRLF delimiters, response.failed
errors, and the missing response.completed defensive branch.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-04-23 11:15:01 +08:00
nmsn 3ad7d0b1cc fix: use TOML parser instead of regex for Codex model extraction (#2222) (#2227)
* fix(codex): use TOML parser instead of regex for model extraction

Regex only matched model=... on first line, TOML parser handles
multiline TOML correctly.

Fixes #2222

* fix(stream_check): drop unused regex::Regex import

The previous commit replaced the only Regex usage in stream_check.rs
with toml::Table parsing, leaving `use regex::Regex;` orphaned.
Without this removal, `cargo clippy -- -D warnings` (run in CI)
fails with `unused import: regex::Regex`.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-04-23 10:38:08 +08:00
涂瑜 29e87487a1 fix(skills): prevent duplicate imports when import button is double-clicked (#2211)
Closes #2139

Two related defects let the installed-skills count balloon when users
tap the import confirm button multiple times — either deliberately or
because the button is still clickable while a slow import is in flight:

- The confirm button only disabled itself while `selected.size === 0`,
  so it stayed clickable during a pending mutation. Each extra click
  triggered another `importFromApps` mutation.
- `useImportSkillsFromApps` appended the server response to the
  installed cache without deduping, so re-firing the mutation stacked
  the same skills into the list again.

Disable the confirm (and cancel) buttons while the mutation is pending
— matching the `isRestoring` / `isDeleting` pattern already used by
`RestoreSkillsDialog` — and merge success payloads by
`InstalledSkill.id` so repeated results overwrite rather than
accumulate.

The merge is extracted as a pure `mergeImportedSkills` reducer to make
the behaviour unit-testable and to short-circuit on an empty payload,
returning the existing reference so React Query does not notify
subscribers about a no-op cache update.
2026-04-23 10:25:01 +08:00
Coconut-Fish 7bfe2609db Style/session manager list UI (#2201)
* style(FailoverQueueManager): 显示供应商备注信息

* style(FailoverQueueItem): 添加供应商备注字段以支持备注信息显示

* style(FailoverQueueManager): 显示供应商备注信息

* style(FailoverQueueItem): 添加供应商备注字段以支持备注信息显示

* style(FailoverQueueManager): 更新供应商备注信息的显示样式

* style(FailoverQueueItem): 添加条件序列化以优化供应商备注字段

* style(App, SettingsPage, ScrollArea): 调整组件样式以改善布局和视觉效果

* style(App, SettingsPage, ScrollArea): 调整组件样式以改善布局和视觉效果

* style(SettingsPage, useSettings): 统一代码格式,调整样式和变量声明

* style(App): 调整底部内边距以改善布局
2026-04-23 08:56:57 +08:00
tison e7ff2ee47d fix: gemini cli resume session can have project_dir (#2240)
Signed-off-by: tison <wander4096@gmail.com>
2026-04-23 08:55:11 +08:00
xpfo 7ddf7ffd66 fix(proxy): handle Codex OAuth responses as streaming (#2235) 2026-04-23 08:54:31 +08:00
tison 1b3c53d235 fix: always show name on hover (#2237)
Signed-off-by: tison <wander4096@gmail.com>
2026-04-22 23:19:52 +08:00
Jason c7ba3cf51d fix(pricing): correct Kimi K2.6 seed prices to match official rates
Moonshot's official USD pricing for kimi-k2.6 is $0.95 input /
$4.00 output / $0.16 cache-hit per 1M tokens (~58-60% higher than
K2.5). The previous commit copied K2.5's $0.60/$2.50/$0.10, which
would have under-billed K2.6 traffic in the usage dashboard.

No migration needed since this version is unreleased; INSERT OR
IGNORE will write the correct values on first launch.
2026-04-22 14:32:03 +08:00
Jason 85295cf23f chore(release): bump version to 3.14.0 2026-04-22 12:29:27 +08:00
Jason 1f25411524 feat(presets): upgrade Kimi K2.5 to K2.6 in direct Moonshot configs
Bump model id and display name from K2.5 to K2.6 in Hermes, OpenClaw,
OpenCode, and Claude (direct api.moonshot.cn) presets. Pricing,
context window, and base URL are unchanged.

Add kimi-k2.6 row to model_pricing seed; no migration needed since
seed_model_pricing uses INSERT OR IGNORE and runs on every startup
via ensure_model_pricing_seeded. Old kimi-k2.5 row is kept to
preserve historical usage stats.

Nvidia aggregator forwards (moonshotai/kimi-k2.5) intentionally keep
the K2.5 SKU until Nvidia's catalog confirms K2.6.
2026-04-22 12:17:19 +08:00
Jason 6495da03b7 docs(release-notes): add v3.14.0 release notes (en/zh/ja)
Cover Hermes Agent onboarding (6th managed app), Claude Opus 4.7
rollout, Gemini Native API proxy, "Local Routing" rename,
application-level window controls, Copilot premium consumption
deep optimization, session list virtualization, Usage date range
picker, Stream Check error classification, pricing v8->v9 reseed,
and related breaking changes.

18 external PR contributions credited in all three locales.
2026-04-22 11:51:32 +08:00
Jason 95b21ff27e docs(changelog): extend v3.14.0 entries with late additions
Fold six late commits into the v3.14.0 section (Added / Changed / Fixed)
and refresh the stats header against the actual v3.13.0..HEAD diff:
100 commits | 219 files | +20,548 / -3,569.

Late additions covered: Hermes dashboard toolbar launch, LemonData
preset across all six apps, DDSHub Codex endpoint, Hermes toolbar
icon + MCP reorder, Hermes health-check schema fix, Usage modal
support for Hermes/OpenClaw.
2026-04-22 11:51:25 +08:00
Jason ae1fd2b662 feat(presets): add DDSHub Codex preset
DDSHub now exposes a Codex-compatible endpoint at the same host as
its Claude service. Base URL omits the /v1 suffix since the gateway
auto-routes OpenAI SDK paths.
2026-04-22 10:42:24 +08:00
Jason f4a9021461 feat(presets): add LemonData provider across all six apps
Register LemonData (third-party partner) preset for Claude, Codex,
Gemini, OpenCode, OpenClaw, and Hermes, plus icon assets and i18n
partner promotion copy (zh/en/ja). Claude preset uses
ANTHROPIC_API_KEY auth; OpenAI-compatible apps target gpt-5.4.
2026-04-22 10:39:17 +08:00
Jason 2274da0b8e style(hermes): use dashboard icon and move MCP to toolbar end
Swap ExternalLink for LayoutDashboard on the Hermes Web UI button —
clicking it may launch `hermes dashboard` rather than just open a URL,
so a panel-style glyph reads truer than a generic external-link icon.
Also reorder the toolbar so MCP sits in the final slot, matching the
claude/codex/gemini/opencode layout.
2026-04-21 23:05:52 +08:00
Jason 7ac822d241 fix(hermes): stop health check from borrowing OpenClaw schema
Hermes providers were routed through check_additive_app_stream, the
OpenClaw dispatcher, which reads camelCase fields (baseUrl/apiKey/api)
and emits "OpenClaw is missing ..." errors. Hermes stores snake_case
fields (base_url/api_key/api_mode) with different protocol tags, so
users saw "OpenClaw provider is missing baseUrl" even after filling in
every Hermes field correctly.

Introduce check_hermes_stream with Hermes-specific extractors. Route
api_mode (chat_completions / anthropic_messages / codex_responses) to
the matching check_claude_stream api_format, and return bedrock_converse
as unsupported. Resolve api_mode before extracting URL/API key so users
who picked bedrock_converse see the real cause first rather than a
misleading "missing base_url" message.
2026-04-21 23:00:37 +08:00
Jason 4dd11ab427 fix(usage): support Hermes and OpenClaw in usage query modal
Extend getProviderCredentials to read flat settingsConfig fields for
Hermes (snake_case base_url / api_key) and OpenClaw (camelCase baseUrl
/ apiKey), so the "official balance" template auto-selects for matching
providers like SiliconFlow.

Also refactor the BALANCE and TOKEN_PLAN test paths in handleTest to
reuse the precomputed providerCredentials instead of re-reading
env.ANTHROPIC_* directly, which previously caused empty key errors for
non-Claude apps even when the key was configured.
2026-04-21 22:40:53 +08:00
Jason 8e9452b7ec feat(hermes): launch dashboard from toolbar when Web UI is offline
When the Hermes Web UI probe fails, the toolbar entry now opens an info
confirm dialog offering to run `hermes dashboard` in the user's preferred
terminal. Accepting spawns it via a temp bash/batch script; `hermes
dashboard` itself opens the browser once ready, so we do not poll.
The Memory panel and Health banner keep the existing toast behavior.

Also corrects the stale `hermes web` hint in the offline toast (the real
command is `hermes dashboard`) and reorders Linux terminal detection to
try `which` before stat'ing /usr/bin, /bin, /usr/local/bin.
2026-04-21 21:11:15 +08:00
Jason 38709c94db docs(changelog): add v3.14.0 release notes
Summarize the 94 commits since v3.13.0 (216 files, +19,923 / -3,554)
into Keep-a-Changelog entries: Hermes Agent as the 6th managed app,
Claude Opus 4.7 rollout, Gemini Native API proxy, Copilot GHES,
session list virtualization, usage date range picker, and the
"Local Proxy Takeover" -> "Local Routing" rename.

Breaking changes collected in a dedicated section: explicit Hermes
api_mode, ANTHROPIC_REASONING_MODEL removal, per-provider proxy
removal, schema bumps (v8->v9 pricing reseed, v9->v10 Hermes columns),
and XCodeAPI preset removal.
2026-04-21 17:32:53 +08:00
Jason db92f2b3b0 style(providers): apply prettier to common-config hooks
Reformat three hooks brought in from upstream #2191 so that
format:check passes in CI.
2026-04-21 12:05:48 +08:00
Jason eb1cd17ab2 fix(header): stop auto-compact from latching after maximize
useAutoCompact cached normalWidthRef = el.scrollWidth on every
non-compact resize, but per DOM spec scrollWidth === clientWidth
when content fits. Maximizing the window (content no longer
overflows) therefore wrote the container width into
normalWidthRef, making it impossible to re-enter compact when
the window was restored to its original size.

Move the assignment inside the overflow branch so the cache is
only written at the actual compact threshold, where scrollWidth
reflects the real content width.
2026-04-21 11:57:07 +08:00
Jason 29a28d2a74 style(header): unify toolbar icon button width across apps
Normalize all icon-only ghost buttons in the header toolbar to
32x32 (w-8 px-2). Previously Hermes/OpenClaw used default sm
padding (~40px) while Claude's Skills/Sessions used w-8 px-2,
so switching apps caused a width jump and put useAutoCompact's
cached normalWidthRef out of sync across apps.
2026-04-21 11:57:07 +08:00
Jason 1227e29d8b feat(skills): enable Hermes in unified Skills management
Wire hermes through SkillApps struct, DAO SQL, command parser, and
SKILLS_APP_IDS. Add a Skills entry to the Hermes toolbar. Simplify
skill_sync test fixtures to use SkillApps::default().
2026-04-21 11:57:07 +08:00
Jason 0be75668cc feat(hermes): align provider schema with Hermes Agent 0.10.0
Hermes 0.10.0 tightened custom_providers validation (commit 2cdae233):
invalid base_urls are rejected, unknown fields produce warnings, and
new fields (rate_limit_delay, bedrock_converse, key_env) landed.

- Add bedrock_converse to the api_mode selector (and i18n labels)
- Expose rate_limit_delay in a provider-level advanced panel
- Validate base_url client-side (URL shape, template-token friendly)
- Drop per-model max_tokens — not in _VALID_CUSTOM_PROVIDER_FIELDS
- Round-trip test asserts set_provider preserves rate_limit_delay /
  key_env / any unknown forward-compat field
2026-04-21 11:57:07 +08:00
Jason 111ddf8d73 style: apply prettier and rustfmt
No behavior changes. Brings three files back in line with the project
formatters (CI runs `pnpm format:check` and `cargo fmt --check`).
2026-04-21 11:57:07 +08:00
Jason 08727528aa test: sync stale fixtures and isolate openclaw env tests
Three unrelated test failures surfaced after rebase:

- McpFormModal expected the apps boolean set without `hermes`; Hermes MCP
  support is now wired, so the fixture must include `hermes: false`.
- therouter Gemini preset was bumped to `gemini-3.1-pro` in a later
  commit; update the assertions to match current config.
- openclaw_config tests mutate process-level `CC_SWITCH_TEST_HOME` and
  `HOME` inside a module-local Mutex, but hermes_config does the same
  under its own separate Mutex. Running both modules in parallel let the
  env races corrupt hermes_config's `with_test_home`. Tag the four
  env-mutating openclaw tests with `#[serial]` so they serialize across
  modules via serial_test's process-wide default key.
2026-04-21 11:57:07 +08:00
Jason c8d91298c7 fix(providers): drop legacy ANTHROPIC_REASONING_MODEL from Claude quick-set
The model-mapping quick-set button referenced an undefined `reasoningModel`
prop and wrote `ANTHROPIC_REASONING_MODEL`, which the backend explicitly
marks as deprecated legacy (see services/provider/mod.rs and
services/proxy.rs). Remove all three references so typecheck passes and
the button matches the provider model schema.
2026-04-21 11:57:07 +08:00
Jason 21a1518f9f refactor(hermes): drop "Auto" api_mode and require explicit protocol
Hermes' built-in api_mode detection only matches a handful of official
endpoints (api.openai.com, api.anthropic.com, api.x.ai, AWS Bedrock);
third-party / proxy endpoints silently fall back to chat_completions,
which causes opaque 401/404s on Anthropic-protocol or Codex-Responses
providers. The "Auto" option was misleading for the common third-party
case.

- Drop the "Auto" option from the API Mode dropdown; remove the
  HermesApiModeChoice sentinel type so writes always emit api_mode.
- Default new providers and legacy entries lacking api_mode to
  chat_completions (only persisted on user save).
- Deeplink imports now write api_mode: chat_completions explicitly
  instead of relying on URL heuristics; test renamed accordingly.
- Rename the "Codex Responses (Copilot / OpenCode)" label to
  "OpenAI Responses" to match OpenAI's /v1/responses naming.
2026-04-21 11:57:07 +08:00
Jason a9461ad52f docs(readme): update SiliconFlow signup bonus to ¥16
Sync the bonus credit amount across en/zh/ja README files to reflect
the current SiliconFlow sponsor offer.
2026-04-21 11:57:07 +08:00
Jason f57edfd697 refactor(hermes): share provider-source marker constants and write guard
After /simplify review of the P1-3 second wave, two small cleanups:

- Lift the `_cc_source` / `providers_dict` magic strings out of
  ProviderCard into a shared helper (`isHermesReadOnlyProvider`) and
  named constants in hermesProviderPresets.ts. Front-end and back-end
  now document the same marker contract in two mirrored places
  instead of drifting strings.

- Replace the duplicate `is_dict_only_provider` + `format!` branches
  at the top of `set_provider` / `remove_provider` with a single
  `ensure_provider_writable(config, name, verb)` guard. Future error
  copy tweaks only have to happen once.

No behaviour change; all 52 hermes_config tests stay green.
2026-04-21 11:57:07 +08:00
Jason abb305a82f feat(hermes): render providers: dict overlays as read-only cards
ProviderCard now detects Hermes provider entries sourced from the
v12+ `providers:` dict via the `_cc_source` marker that the backend
injects, and renders a "Hermes Managed" badge beside the title.
ProviderActions receives an `isReadOnly` prop that disables the Edit
and Delete buttons (with a tooltip pointing the user at Hermes Web
UI) while keeping Switch and Duplicate enabled — switching only
touches `model.*`, and duplicate lets users fork the overlay into
their own `custom_providers:` list.

Three-locale i18n keys `provider.managedByHermes` /
`provider.managedByHermesHint` added.
2026-04-21 11:57:07 +08:00
Jason 3f4739365e feat(hermes): surface providers: dict entries read-only
Hermes v12+ migrated some provider entries from the `custom_providers:`
list into a `providers:` dict (keyed by id). CC Switch previously
ignored that source entirely, leaving users blind to providers they had
configured via Hermes' own Web UI; the only feedback was a generic
migration warning in the health banner.

`get_providers()` now unions both sources, matching upstream
`get_compatible_custom_providers` dedup order (list wins on name
collision). Entries coming from the dict carry a `_cc_source =
"providers_dict"` marker plus the original `provider_key`, which the
UI layer will use to render them read-only. `set_provider` and
`remove_provider` now refuse to touch dict-only entries, steering the
user to Hermes Web UI. `sanitize_hermes_provider_keys` strips the UI
markers on write so they never reach YAML.

The `schema_migrated_v12` health warning copy reframes the situation:
entries are shown read-only in CC Switch rather than invisible.
2026-04-21 11:57:07 +08:00
Jason e10a300c80 fix(hermes): prevent YAML pollution and drop of OAuth mcp auth
DeepLink Hermes import was emitting camelCase (baseUrl / apiKey /
apiMode) that the Hermes runtime does not recognise, poisoning
`custom_providers:` entries on activation. The MCP sync path was
also stripping `auth: oauth` on round-trip, silently downgrading
OAuth-type servers to unauthenticated calls.

The Hermes deeplink branch now emits snake_case via a dedicated
builder; `sanitize_hermes_provider_keys` runs on both `set_provider`
and `get_providers` so legacy DB records heal on next access.
`HERMES_EXTRA_FIELDS` preserves `auth`. The `api_mode` dropdown gains
`codex_responses` (Copilot / OpenCode), and the schema-migrated
warning copy no longer hard-codes "v12" (upstream `_config_version`
is now 19).
2026-04-21 11:57:07 +08:00
Jason 185ac2be9b feat(hermes): memory enable switch + clearer migration warning copy
Replaces the greyed-out "Memory is disabled" banner with a real Switch
at the top of each memory tab. Users can now toggle Hermes' memory/user
blobs without leaving CC Switch; the underlying write goes through the
merge-aware `set_memory_enabled`, so budgets and external-provider
settings survive toggle operations. The new `useToggleHermesMemoryEnabled`
mutation invalidates the limits query so the Switch state and the
amber disabled-hint update in lockstep.

Reworks the `schema_migrated_v12` health banner copy to match the
simplified "CC Switch only manages custom_providers" posture — it now
tells users to reconcile migrated dict entries via Hermes Web UI,
instead of the earlier (and now inaccurate) "CC Switch reads both".
2026-04-21 11:57:07 +08:00
Jason b8a3534cb5 feat(settings): add Hermes config dir override with data-driven dispatch
Adds a dedicated Hermes row to the directory-override settings so users
can point CC Switch at alternate Hermes config locations (e.g. a second
profile directory for work/personal split). `get_config_dir` on the
Rust side already supports hermes; this just wires up the frontend row.

Wiring it through `useDirectorySettings` revealed a scaling problem:
every supported app required five parallel ternary chains across
`computeDefaultConfigDir`, `updateDirectory`, `browseDirectory`,
`resetDirectory`, and `updateDirectoryState`. Replaces those with two
lookup tables (`APP_DIRECTORY_META`, `DIRECTORY_KEY_TO_SETTINGS_FIELD`)
so adding the next app is two entries, not fifteen edit sites.

Drive-by cleanup from the same touch:
* `resetAllDirectories` takes a `ResolvedAppDirectoryOverrides` object
  instead of five positional optional strings.
* `setResolvedDirs` returns the same reference when the sanitized
  value is unchanged, so no-op edits don't cascade renders.

Also lands all i18n updates for this series (`hermesConfigDir` and
placeholder, Memory section's enable/disable/toggleFailed copy, and
the reworded `schemaMigratedV12` warning) in zh/en/ja together.
2026-04-21 11:57:07 +08:00
Jason 31fb998575 refactor(hermes): simplify schema handling + preserve unknown provider fields
Drops the v11→v12 providers-dict compat layer: CC Switch now only
reads/writes `custom_providers:`, leaving migrated `providers:` dict
entries to Hermes Web UI for reconciliation (Hermes' runtime already
merges both shapes via `get_compatible_custom_providers`). The
`schema_migrated_v12` health warning now points users there when a
dict-migrated config is detected.

Adds forward-compat merge to `set_provider`: when updating an existing
entry, on-disk fields the UI payload didn't submit (e.g. Hermes-only
`request_timeout_seconds`, `key_env`) are carried over. Without this,
editing one field via CC Switch would silently strip the rest.

Adds `set_memory_enabled` + `set_hermes_memory_enabled` Tauri command
for the upcoming memory-switch UI. Writes go through a merge-aware
section replacement so character budgets and external-provider fields
survive toggle operations.

Removes four dict-only helpers (`normalize_providers_dict_entry_for_read`,
`rename_alias_key`, `json_obj_non_empty_str`,
`resolve_provider_name_from_yaml_entry`) and the multi-section write
helper. Simplifies `get_providers` / `remove_provider` / health scan
back to list-only. Replaces nine obsolete dict-related tests with
`set_provider_preserves_unknown_fields_on_update` and
`set_memory_enabled_preserves_other_fields`.
2026-04-21 11:57:07 +08:00
Jason acc6d795e4 feat(hermes): replace Prompts entry with Memory panel
Hermes has no slash-prompt concept (templates live as Skills), so the
Prompts tab for the Hermes app was always empty. Swap the toolbar Book
button for a Brain button that opens a new Memory panel editing
~/.hermes/memories/{MEMORY,USER}.md — Hermes' first-class memory store
which its Web UI exposes only as on/off toggles, never as an editor.

The panel shows each file in its own tab with a character-budget bar
read from config.yaml's nested memory.* section (memory_char_limit /
user_char_limit, default 2200 / 1375). Edits are written atomically;
Hermes picks them up on the next session start per MemoryStore.

Also extract useDarkMode to src/hooks/useDarkMode.ts — the codebase
already repeats the same MutationObserver pattern in 12+ places; this
PR introduces the shared hook and uses it once, leaving the migration
of the other copies to a follow-up.
2026-04-21 11:57:07 +08:00
Jason 088b47b08a refactor(hermes): delegate deep config to Hermes Web UI
Slim the Hermes surface in CC Switch to match its core positioning —
cross-client provider switching and shared MCP/prompts/skills — and
delegate deep configuration (model, agent, env, skills, cron, logs)
to the Hermes Web UI at http://127.0.0.1:9119.

- Drop AgentPanel/EnvPanel/ModelPanel and their mutation commands,
  hooks, types, and i18n keys across zh/en/ja.
- Add open_hermes_web_ui Tauri command that probes /api/status and
  launches the URL in the system browser. Hermes injects its own
  session token into the returned HTML, so CC Switch doesn't need
  to touch auth.
- Surface the launcher from the Hermes toolbar and the health banner
  via a shared useOpenHermesWebUI() hook; the offline error code is
  defined once per side and referenced across the contract.
- Keep read-only access to model.provider so ProviderList can still
  highlight the active supplier; apply_switch_defaults continues to
  write the top-level model section when switching providers.

Net diff: +152 / -1253.
2026-04-21 11:57:06 +08:00
Jason 041f74db18 fix(presets): refresh stale context windows for DeepSeek and Claude 1M
- DeepSeek V3.2 / R1 (Hermes, OpenClaw): 64K → 128K context
- DeepSeek R1 max output: 8K → 64K (includes CoT tokens)
- Claude Opus 4.7 / Sonnet 4.6 via OpenRouter: 200K → 1M context
2026-04-21 11:57:06 +08:00
Jason ce5c3e5c6a fix(presets): refresh stale model IDs and backfill Hermes model lists
- Bump NewAPI universal preset to Claude 4.7 / Sonnet 4.6 / Haiku 4.5 and
  Gemini 3.1; fix opusModel mistakenly pointing to Sonnet
- Bump Gemini Native (Claude preset) to gemini-3.1-pro / gemini-3-flash
- Bump TheRouter Gemini preset to gemini-3.1-pro
- Backfill models[] + suggestedDefaults for 15 Hermes anthropic_messages
  presets:
    * Bailian For Coding: qwen3-coder-plus / qwen3-max
    * Kimi For Coding: kimi-for-coding
    * 13 third-party Claude proxies: claude-opus-4-7 / sonnet-4-6 /
      haiku-4-5-20251001
- Add Claude Haiku 4.5 entry to Hermes OpenRouter model list
2026-04-21 11:57:06 +08:00
Jason 3255b17185 feat(hermes): switch eligible presets to chat_completions + GPT-5.4
Migrate 18 Hermes provider presets from anthropic_messages to
chat_completions to sidestep known upstream Hermes bugs (model-name
dot-mangling in normalize_model_name, api_mode drop after v11->v12
migration, and auxiliary_client OpenAI hardcode).

Native providers now target each vendor's official OpenAI-compatible
endpoint with correct model IDs: Kimi (kimi-k2.5-preview on /v1),
Bailian (compatible-mode/v1 with Qwen3 defaults), Xiaomi MiMo, Longcat
(/openai/v1), Zhipu GLM (/api/paas/v4), ModelScope, MiniMax, SiliconFlow,
and Novita (/v3/openai).

Aggregators (Shengsuanyun, AiHubMix, DMXAPI, Compshare, TheRouter)
default to GPT-5.4 on chat_completions, mirroring the Codex preset
lineup. TheRouter omits gpt-5.4-pro since that variant is Responses-only
and Hermes implements only chat_completions. OpenRouter's existing
openai/gpt-5 entry is bumped to openai/gpt-5.4.

Claude-only proxies are left on anthropic_messages; their Codex
counterparts use wire_api=responses, so there is no evidence their
chat_completions endpoints serve OpenAI models.
2026-04-21 11:57:06 +08:00
Jason b4e29be8a0 chore(hermes): prune unused official presets and fix Nous endpoint
Remove the Anthropic, OpenAI, and Google AI presets from the Hermes
preset list. They were placeholder samples introduced when the Hermes
module first landed and do not match the actual user paths in
CC Switch (Claude / Codex go through OAuth, Gemini Native is its own
adapter), and the upstream endpoints are not reachable for most of
the target users anyway.

Fix the Nous Research preset: its base_url was a fabricated domain
(inference.nous.hermes.dev) that has never resolved. Point it at the
real Nous Portal endpoint (inference-api.nousresearch.com/v1) and
add apiKeyUrl so users can jump straight to portal.nousresearch.com
to provision a key.

Drop the now-orphan providerForm.presets.{anthropic,openai,googleai}
i18n keys from zh / en / ja since no preset references them anymore.
2026-04-21 11:57:06 +08:00
Jason 8d6353699c feat(presets): sync Claude provider presets to Hermes
Import 38 Claude presets into Hermes by mapping env-style
ANTHROPIC_BASE_URL/AUTH_TOKEN to flat base_url/api_key, deriving
api_mode from apiFormat (anthropic_messages or chat_completions),
deduping ANTHROPIC_*_MODEL into models[], and pointing
suggestedDefaults at ANTHROPIC_MODEL. Skip OAuth-only presets
(Codex, Copilot), Bedrock SigV4, Gemini Native, and the three
already shipped on the Hermes side (OpenRouter, Anthropic,
DeepSeek). Place Shengsuanyun at the head of the Hermes array so
the partner shows first in the preset panel.

In the Claude preset list, restore Shengsuanyun back ahead of
Gemini Native. The Gemini Native preset (#1918) was inserted
between Claude Official and Shengsuanyun, which made the
third_party category register first in the reduce-based grouping
and pushed the aggregator block (and Shengsuanyun) behind it.

Backfill the missing providerForm.presets translations across zh,
en, and ja (openrouter, anthropic, openai, googleai, deepseek,
together; plus shengsuanyun for en and ja) so existing Hermes
preset names no longer render literal i18n keys.
2026-04-21 11:57:06 +08:00
Jason 828ec2ce07 fix(hermes): show active provider and wire add/enable/remove actions
Switching a Hermes provider previously only fired a toast because the frontend treated Hermes as non-additive (unlike backend AppType::is_additive_mode, which lists OpenCode | OpenClaw | Hermes) and relied on the unused is_current DB flag for highlighting. Align the UI model with the backend:

- Include Hermes in ProviderActions' isAdditiveMode so the main button switches between "Add" and "Remove".
- Drive the "current" highlight from model.provider (via useHermesModelConfig) instead of the DB is_current field; model.provider is Hermes's real SSOT for the active provider.
- Reuse OpenClaw's set-as-default button slot to expose an "Enable" action on Hermes that calls switchProvider, so providers already in config can be activated without re-adding. switch_normal + apply_switch_defaults already atomically update custom_providers and model.provider, so no backend change is needed.
- Invalidate liveProviderIds + modelConfig + health in parallel after add/update/delete/switch via a new invalidateHermesProviderCaches helper, replacing four copies of three sequential awaits.
2026-04-21 11:57:06 +08:00
Jason 5056978d80 fix(hermes): persist providers under custom_providers so api_mode/model survive
Writing to the v12+ `providers:` dict broke every anthropic_messages
provider. Hermes `runtime_provider.py::_get_named_custom_provider` has a
bug in its `providers:` branch: the returned entry drops `api_mode`,
`transport`, `models`, and singular `model:`, and
`_resolve_named_custom_runtime` then falls back to `chat_completions` —
so an Anthropic-format endpoint receives OpenAI-format requests and
returns 404.

Keep using the legacy `custom_providers:` list; its normalization path
(`_normalize_custom_provider_entry`) preserves every field. In addition,
write a singular `model:` alongside the plural `models:` dict so the
Hermes runtime and `/model` picker see the default model id.

Also keep the `apply_switch_defaults` fix from the prior attempt:
`model.provider` is always updated, and `model.default` is only
overwritten when the new provider declares at least one model — so
switching to an incomplete provider no longer silently no-ops.
2026-04-21 11:57:06 +08:00
Jason 497a543c1b feat(hermes): add API mode dropdown and per-provider model editor in form
The Hermes provider form previously only exposed Base URL and API Key,
forcing users to drop into the Model panel to hand-edit model IDs after
adding a provider. Following OpenClaw's shape, the form now carries:

- An API Mode selector (auto-detect / chat_completions / anthropic_messages).
  "auto" is a UI-only sentinel — selecting it deletes api_mode from the
  config so the YAML doesn't leak a redundant field.
- A model list editor where the first row is badged as the default and
  each row has a collapsible Advanced panel for context_length and
  max_tokens. Adding/removing rows uses a UUID-keyed ref so typing in
  one input doesn't drop focus when another row is added.
- A Fetch Models button that pulls /v1/models from the configured
  endpoint and exposes the catalog in a per-row dropdown, identical to
  OpenClaw's flow. The vendor grouping is memoized so keystrokes don't
  trigger a reduce+sort per model row — Radix DropdownMenuContent does
  not lazy-mount, so the inner JSX evaluates on every render regardless
  of whether the menu is open.

Three-locale i18n keys are added together (zh/en/ja).
2026-04-21 11:57:06 +08:00
Jason f935bac633 feat(hermes): bind per-provider models to top-level model: on switch
Hermes custom_providers entries now carry an ordered models array
(id / context_length / max_tokens) plus suggestedDefaults. The backend
serializes the array to the YAML dict shape Hermes expects on write and
inverts it on read, preserving insertion order via the preserve_order
feature on serde_json.

When a user switches providers, switch_normal calls apply_switch_defaults
so the top-level model.default / model.provider follow the selected
provider's first model. Previously switching a Hermes provider only
shuffled custom_providers[] and left Hermes pointing at whatever
model.provider was set before.

Seven existing Hermes presets now ship with a curated models list so
switching lands on a working default without a detour through the
Model panel.
2026-04-21 11:57:06 +08:00
Jason 63aa310576 feat(copilot): strip thinking blocks before forwarding to save premium quota
Copilot routes through OpenAI-compatible endpoints that reject Anthropic's
thinking and redacted_thinking blocks. Previously the request would fail
upstream, burning one premium interaction, and only then trigger
thinking_rectifier to retry. This adds a proactive strip_thinking_blocks
pass in the Copilot optimization pipeline (step 3.5, after tool_result
merging). Signature fields and top-level thinking are left alone — those
are the reactive rectifier's job on the error path.

Also fixes a default-value inconsistency where CopilotOptimizerConfig's
Default impl used "gpt-4o-mini" while the serde default function returned
"gpt-5-mini" (aligned to gpt-5-mini, matching the reference implementation).

Aligned with yuegongzi/copilot-api's /v1/messages handler behavior.
2026-04-21 11:57:06 +08:00
Jason 615c430dd3 docs(readme): trim SSSAiCode sponsor blurb and sync across locales
Drop the ¥0.5/$ pricing claim and monthly/paygo line from the SSSAiCode
entry in all three READMEs, keeping only the fast-invoicing mention.
Also collapse a duplicate blank line after the LemonData row in the JA
README to match the ZH version.
2026-04-21 11:57:06 +08:00
Jason 5d3cd7eb85 fix(icons): replace placeholder Hermes icon with Nous brand artwork
The previous Hermes icon was an inline purple "H" SVG unrelated to the
real Hermes Agent brand. Replace it with the official Nous Research
avatar sourced from hermes-agent/landingpage/icon-512.png, routed
through iconUrls as a Vite URL import. The PNG is post-processed to
strip the 4px black rectangle border (cropped inward by 6px and pasted
back onto a 512x512 transparent canvas). Also switch defaultColor to
black to match the monochrome artwork when the asset falls back to an
initial glyph.
2026-04-21 11:57:06 +08:00
Jason 1684cb3233 feat(presets): migrate all aggregator and Bedrock presets to Claude Opus 4.7
- OpenClaw: replace opus-4-6 with opus-4-7 across 17 aggregator presets
  (id, name, primary, modelCatalog); AWS Bedrock entry rewritten to new
  SKU anthropic.claude-opus-4-7 (drops -v1 and dated suffix per official
  4.7 model card) and pricing corrected to $5/$25/$0.50/$6.25 during the
  SKU swap, aligning with schema.rs source of truth
- OpenCode: same replacement for 13 aggregators plus
  OPENCODE_PRESET_MODEL_VARIANTS entries for @ai-sdk/amazon-bedrock and
  @ai-sdk/anthropic, plus AWS Bedrock provider models map
- OpenRouter / TheRouter / GitHub Copilot in claudeProviderPresets use
  dot-style id; update to anthropic/claude-opus-4.7 (missed by 509d2250)
- omo: switch agent/category recommended to opus-4-7; replace key in
  OMO_BACKGROUND_TASK_PLACEHOLDER priority map
- hermes_config.rs: update doc comments and test fixtures to opus-4-7;
  Hermes ModelPanel placeholder and i18n defaultHint examples follow
- i18n unspecifiedHigh category description bumped to 'Claude Opus 4.7
  max variant' to match omo recommended
- Test fixtures updated: therouter preset assertion and opencode Bedrock
  variant lookup now check for opus-4-7
- Sonnet 4.6 / Haiku 4.5 untouched - no official 4.7 release for them
2026-04-21 11:57:06 +08:00
Jason 83c3c3b494 feat(pricing): add Claude Opus 4.7 with adaptive thinking and Bedrock SKU
- Seed claude-opus-4-7 pricing (same tier as 4.6: $5 / $25 / $0.50 /
  $6.25 per million tokens). Relies on incremental INSERT OR IGNORE
  seeding; no SCHEMA_VERSION bump needed.
- Whitelist opus-4-7 in thinking optimizer so it uses adaptive
  thinking + max effort + 1M context beta, matching 4.6 behavior.
- Bump default OPUS model in PIPELLM and AWS Bedrock (AKSK / API Key)
  presets to 4.7. Bedrock SKU drops the -v1 suffix per the official
  4.7 model card (anthropic.claude-opus-4-7 and
  global.anthropic.claude-opus-4-7).
2026-04-21 11:57:06 +08:00
Jason 50431b7ec9 feat(usage-script): add User-Agent header to New API template
Align the New API usage query template with the GENERAL template by
including "User-Agent: cc-switch/1.0" in its request headers, so
cc-switch requests are identifiable in provider server logs and less
likely to be blocked by UA-based rate limiting on some New API
deployments.
2026-04-21 11:57:06 +08:00
Jason 8b65a31c7c feat(claude): upgrade effort toggle from "high" to "max"
Per Anthropic's effort parameter docs, "high" is the API default and
setting effortLevel="high" is equivalent to omitting the field entirely.
The toggle previously produced no effect.

Claude Opus 4.6, Sonnet 4.6, and Opus 4.7 now support a "max" level
that enables unconstrained reasoning. Rename the checkbox (effortHigh
-> effortMax) and write effortLevel="max" when toggled on. Existing
"high" values in user configs are left untouched.

Updates zh/en/ja locales and user-manual entries accordingly.
2026-04-21 11:57:06 +08:00
Jason d03e6f9951 chore(lint): pin Rust toolchain to 1.95 and adopt clippy 1.95 suggestions
- Add rust-toolchain.toml to align local and CI Rust versions, eliminating
  clippy roulette caused by `dtolnay/rust-toolchain@stable` drift.
- Fix 9 clippy 1.95 findings introduced by Hermes Phase 4-8 modules:
  * 4x unnecessary_sort_by  -> sort_by_key (with Reverse for desc)
  * 3x collapsible_match    -> match guards
  * 1x while_let_loop       -> while let
  * 1x useless_conversion   -> drop redundant .into_iter()
2026-04-21 11:57:06 +08:00
Jason 0ca36b9d51 fix: address Hermes review findings (5 medium issues)
- Add missing Hermes MCP import on first launch (lib.rs)
- Add Hermes branch in ProviderForm defaultValues fallback
- Include Hermes in session manager subtitle (zh/en/ja)
- Rename check_openclaw_stream to check_additive_app_stream
- Cache parsed HERMES_DEFAULT_CONFIG to avoid repeated JSON.parse
2026-04-21 11:57:06 +08:00
Jason e8953c286f feat: implement Hermes session manager with SQLite + JSONL support (Phase 6)
- Add hermes.rs session provider with dual-source scanning:
  SQLite (state.db) as primary, JSONL transcripts as fallback
- Dynamic schema discovery via PRAGMA table_info for SQLite resilience
- Use read_head_tail_lines for efficient JSONL metadata extraction
  (head 30 lines for metadata, tail 10 for last_active_at)
- Support both flat and nested JSONL message formats
- Add SQLite session loading and transactional deletion
- Register hermes in parallel session scan (thread::scope)
- Add "hermes" to frontend ProviderFilter type
- 7 unit tests covering JSONL parsing, SQLite source parsing, deletion
2026-04-21 11:57:06 +08:00
Jason 240969d8c7 feat: add Hermes UI components, presets, and config panels (Phase 8)
- Add 7 provider presets (OpenRouter, Anthropic, OpenAI, Google, DeepSeek, Together, Nous)
- Create HermesFormFields + useHermesFormState for provider form integration
- Create Model/Agent/Env config panels with save/load functionality
- Create HermesHealthBanner for config warnings
- Add hermes icon (violet winged H) to icon system
- Integrate into App.tsx: 3 new view types (hermesModel/hermesAgent/hermesEnv),
  sidebar buttons (Brain/Bot/KeyRound), health banner, session support
- Integrate into ProviderForm: presets, form state, key validation, rendering
- Integrate into AddProviderDialog: universal tab exclusion, providerKey, base_url extraction
- Add i18n keys for all Hermes UI (zh/en/ja)
2026-04-21 11:57:06 +08:00
Jason a0b585992a feat: add Hermes frontend types, API layer, and hooks (Phase 7)
- Add "hermes" to AppId union type and all exhaustive Record<AppId>
- Add HermesModelConfig, HermesAgentConfig, HermesEnvConfig types
- Add hermes field to VisibleApps, McpApps, ProxyTakeoverStatus
- Create src/lib/api/hermes.ts with Tauri invoke wrappers
- Create src/hooks/useHermes.ts with 5 query + 3 mutation hooks
- Register hermes in APP_IDS, APP_ICON_MAP (violet color scheme)
- Split MCP_SKILLS_APP_IDS into MCP_APP_IDS (includes hermes) and
  SKILLS_APP_IDS (excludes hermes, since Hermes has no Skills support)
- Wire hermes additive-mode into App.tsx (remove/duplicate handlers),
  ProviderList.tsx (live provider ID query + In Config badge),
  mutations.ts (cache invalidation on switch/add/delete)
- Add Hermes checkbox to McpFormModal
- Add basic hermes i18n keys (en/zh/ja)
2026-04-21 11:57:06 +08:00
Jason 576ff53a75 feat: implement Hermes MCP sync module (Phase 4)
Add mcp/hermes.rs with bidirectional MCP format conversion:
- convert_to_hermes_format: strip type field, infer from command/url
- convert_from_hermes_format: infer type, strip Hermes-specific fields
- Merge-on-write: existing Hermes fields (tools, sampling, timeout,
  roots, enabled) preserved when user has customized them
- update_mcp_servers_yaml: closure-based read-modify-write under write
  lock to prevent TOCTOU races in concurrent sync operations
- 9 unit tests for format conversion and merge logic

Wire up all MCP service dispatch:
- Replace Hermes TODO stubs with real sync/remove calls
- Remove Hermes from sync_all_enabled skip list
- Enable deep link hermes MCP flag (apps.hermes = true)
- Add Hermes import to import_mcp_from_apps command
2026-04-21 11:57:06 +08:00
Jason 6d0e9f4c74 feat: implement Hermes config module and commands (Phase 3)
Add hermes_config.rs (~1190 lines) with YAML section-level replacement
that preserves comments and formatting in unmanaged sections:
- Type definitions: HermesModelConfig, HermesAgentConfig, HermesEnvConfig
- YAML section finder (find_yaml_section_range) with column-0 key detection
- Provider CRUD on custom_providers array (indexed by name field)
- Model/Agent config get/set via yaml<->json conversion
- .env dotenv read/write preserving comments and line ordering
- Health check, backup with rotation, write lock (OnceLock<Mutex>)
- MCP section access stubs for Phase 4
- 19 unit tests

Add commands/hermes.rs with 10 Tauri commands registered in lib.rs.
Replace all Hermes TODO stubs in services/provider/live.rs with real
implementations (import, remove, write-to-live, read-live-settings).
2026-04-21 11:57:06 +08:00
Jason a2e9e1938b feat: add database migration v9→v10 for Hermes support (Phase 2)
- Bump SCHEMA_VERSION from 9 to 10
- Add enabled_hermes column to mcp_servers and skills tables
- Add migrate_v9_to_v10 with table_exists guard for skills (may not
  exist in databases migrated from very old versions)
- Update dao/mcp.rs to fully read/write enabled_hermes in all queries
- Update dao/skills.rs: don't SELECT enabled_hermes (Hermes doesn't
  support Skills yet), keep column indices clean
2026-04-21 11:57:06 +08:00
Jason 81af0a57f9 feat: add Hermes Agent as 6th supported app type (Phase 1)
Register AppType::Hermes across the entire Rust backend:
- Add Hermes variant to AppType enum with additive mode and MCP support
- Add hermes field to McpApps, SkillApps, CommonConfigSnippets, and all
  per-app structs (McpRoot, PromptRoot, VisibleApps, AppSettings)
- Create minimal hermes_config.rs with get_hermes_dir() respecting
  settings override, matching the pattern of other app config modules
- Update all match arms in commands, services, deeplink, proxy, mcp,
  session_manager, and test files
- Extract shared build_additive_app_settings() to eliminate duplication
  between OpenClaw and Hermes deep link handling
- Combine identical OpenClaw/Hermes proxy match arms into unified arms
2026-04-21 11:57:06 +08:00
Jason 701e7d9581 fix: surface backend error details in proxy toast messages
The takeover.failed i18n template lacked the {{detail}} placeholder
and three useProxyStatus onError callbacks omitted the detail variable,
so proxy start/stop/takeover failures all displayed a generic message
regardless of the underlying cause.
2026-04-21 11:57:06 +08:00
Jason e4c34b34e7 fix: remove ANTHROPIC_REASONING_MODEL to decouple thinking from model selection (#2081)
ANTHROPIC_REASONING_MODEL was a non-official env var that forced all
requests with thinking params to use a single "reasoning model",
overriding the user's /model selection. Since new Claude Code versions
send adaptive thinking by default, this caused /model to silently fail.

- Remove reasoning_model field and has_thinking_enabled() from model_mapper
- Simplify map_model() to pure type-based matching (haiku/sonnet/opus)
- Remove reasoning model UI field from provider form
- Retain ANTHROPIC_REASONING_MODEL in ENV_EXCLUDES and override-key
  cleanup lists so legacy configs don't leak into common config
2026-04-21 11:57:06 +08:00
Jason eab0a69d2c fix: unify weekly_limit tier label to match official 7-day naming 2026-04-21 11:57:06 +08:00
Jason 4e790ac059 fix: hide unknown subscription quota tiers from provider card UI 2026-04-21 11:57:06 +08:00
chengww c5b15dd25e fix(claude-plugin): sync current provider config to settings.json (#1905)
* fix(claude-plugin): sync current provider config to settings.json on toggle enable

- Extract syncClaudePluginIfChanged to share logic between autoSaveSettings and saveSettings
- Fix P1: enableClaudePluginIntegration toggle in General tab now actually syncs ~/.claude/settings.json
- Fix P2: check syncCurrentProvidersLiveSafe() return value and show toast on failure
- Fix P3: sync providers on both enable and disable, not just enable
- Fix P4: avoid double syncCurrentProvidersLiveSafe when plugin toggle + dir change happen together
- Remove duplicate comment
- Add missing providersApi.getCurrent/getAll mocks in tests

* style: reformat after rebase onto main

Prettier flagged a line-break introduced by the openclaw directory
change (from main) after rebase.

* fix(claude-plugin): read prev enabled state from live cache to avoid stale closure

syncClaudePluginIfChanged compared enabled against data?.enableClaudePluginIntegration
captured in a useCallback closure. After invalidateQueries + refetch, the React
Query cache is up to date, but the consuming hook's closure does not see the new
value until React re-renders. Quick on->off toggles could therefore skip
applyClaudePluginConfig, leaving ~/.claude/config.json in the previously enabled
state even though settings.json was persisted as disabled.

Read the previous value synchronously from queryClient.getQueryData(["settings"])
before saveMutation.mutateAsync(), then pass it to the helper as prevEnabled.
getQueryData bypasses the closure and reflects the live cache at call time.

Test covers the race: closure data stays at false while the cache reports true;
the helper must still call applyClaudePluginConfig({ official: true }).

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-04-21 11:56:13 +08:00
zxZeng cc77a040e2 fix: common config checkbox state not persisting for Codex/Claude/Gemini (#2191)
修复:Codex/Claude/Gemini 通用配置勾选状态无法正确保存的问题

Co-authored-by: 曾兴 <zengx@gantsoftware.com>
2026-04-21 11:04:31 +08:00
hengm3467 1b345fbefb Add StepFun and StepFun en Step Plan presets (#2155)
* Add StepFun CN and EN presets

* Add StepFun 2603 model presets

* Make StepFun 2603 the default model

* Revert StepFun branding assets
2026-04-21 10:46:26 +08:00
Li Yang 61bfc29d82 fix(tray): use an app-specific tray id (#1978)
Co-authored-by: liyang <liyang25@pku.edu.cn>
2026-04-21 10:42:59 +08:00
Suda202 2c9252dec5 Fix Ghostty session restore launch path (#1976)
* fix: launch Ghostty via shell command

Use Ghostty's shell execution path instead of injecting raw terminal input so Claude resume commands run reliably when opening a session terminal.

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

* fix(ghostty): pass cwd via --working-directory instead of shell string

Use Ghostty's native --working-directory flag to set the working
directory, matching the pattern used by Alacritty. This avoids shell
expansion of special characters (e.g. $VAR, spaces) in project paths.

The command is now passed directly to -c without a cd prefix.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-20 12:42:00 +08:00
Franklin 34349a2743 Add OpenClaw config directory settings (#1518)
Co-authored-by: 张斌 <zhangbin25@xiaomi.com>
2026-04-20 08:44:38 +08:00
King 8ba92b5470 feat(ui): add quick-set button for model mapping fields (#2179)
* feat(ui): add quick-set button for model mapping fields

Add a "一键设置" (Quick Set) button in the model mapping section to
simplify provider configuration. When users enter a model name in any
of the five model fields, they can now click this button to populate
all fields with that same value.

This addresses the UX friction of manually filling all five model
mapping fields (主模型, 推理模型, Haiku, Sonnet, Opus) when the
provider uses the same model name across all request types.

Implementation:
- Add Wand2 icon import from lucide-react
- Insert quick-set button alongside existing fetch-models button
- Logic picks first non-empty model value and applies to all fields
- Show success toast after applying
- Disabled state when all model fields are empty
- Add i18n strings for zh, en, ja locales

Relates to user feedback about tedious model configuration workflow.

* style(ui): format ClaudeFormFields component code

Apply consistent code formatting to ClaudeFormFields.tsx following
project linting rules. Includes multi-line import statements and
improved readability for conditional expressions.
2026-04-19 21:42:17 +08:00
hotelbe 87635e7fc6 feat(copilot): add GitHub Enterprise Server support (#2175)
* feat(copilot): add GitHub Enterprise Server support

* fix(copilot): address GHES PR review findings (P1 + 2×P2)

- P1: Use composite account ID (domain:user_id) for GHES to prevent
  cross-instance ID collisions; github.com keeps plain numeric ID for
  backward compatibilit
- P2-a: Use get_api_endpoint() for model list URL with automatic
  fallback to static URL when dynamic endpoint resolution fails
- P2-b: Add normalize_github_domain() as backend SSOT for domain
  normalization (lowercase, strip protocol/path/query, reject userinfo)

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

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 20:29:46 +08:00
YaoguoHH 9871d3d1eb fix(skills): sync imported skills to app directories after import (#2101)
`import_from_apps()` saves skills to the database but does not create
symlinks/copies in the target app directories (e.g. `~/.claude/skills/`).
This causes skills to appear as "installed" in the UI while the actual
files are missing from the app directories.

Add `sync_to_app_dir()` calls after `db.save_skill()` in the import
loop, matching the pattern used by `install()` and `toggle_app()`.
2026-04-19 15:25:25 +08:00
Coconut-Fish 1126c7459d Style/add provider.notes (#2138)
* style(FailoverQueueManager): 显示供应商备注信息

* style(FailoverQueueItem): 添加供应商备注字段以支持备注信息显示

* style(FailoverQueueManager): 显示供应商备注信息

* style(FailoverQueueItem): 添加供应商备注字段以支持备注信息显示

* style(FailoverQueueManager): 更新供应商备注信息的显示样式

* style(FailoverQueueItem): 添加条件序列化以优化供应商备注字段
2026-04-18 17:48:58 +08:00
Dex Miller 03a0f9661b feat(proxy): Gemini Native API proxy integration (#1918)
* refactor(proxy): extract take_sse_block helper with CRLF delimiter support

Replace inline `buffer.find("\n\n")` SSE splitting logic across streaming,
streaming_responses, response_handler, and response_processor with a shared
`take_sse_block` function that handles both `\n\n` and `\r\n\r\n` delimiters.

* feat(proxy): add Gemini Native URL builder and full-URL resolver

Introduce gemini_url module that normalizes legacy Gemini/OpenAI-compatible
base URLs into canonical models/*:generateContent endpoints. Supports both
structured Gemini URLs (auto-normalized) and opaque relay URLs (pass-through
with query params only).

* feat(proxy): add Gemini Native schema, shadow store, transform, and streaming

- gemini_schema: Gemini generateContent request/response type definitions
- gemini_shadow: session-scoped shadow store for thinking signature and
  tool-call state replay across streaming chunks
- transform_gemini: bidirectional Anthropic Messages ↔ Gemini Native
  request/response conversion with thinking block and tool-use support
- streaming_gemini: Gemini SSE → Anthropic SSE streaming adapter with
  incremental thinking/text/tool_use delta emission

* feat(proxy): wire Gemini Native format into proxy core and Claude adapter

Integrate gemini_native api_format throughout the proxy pipeline:
- ClaudeAdapter: detect Gemini provider type, Google/GoogleOAuth auth
  strategies, and suppress Anthropic-specific headers for Gemini targets
- Forwarder: Gemini URL resolution, shadow store threading, endpoint
  rewriting to models/*:generateContent with stream/non-stream variants
- Handlers: route Gemini streaming through streaming_gemini adapter and
  non-streaming through transform_gemini converter
- Server/State: add GeminiShadowStore to shared ProxyState
- StreamCheck: support gemini_native health check with proper auth headers

* feat(ui): add Gemini Native provider preset and api format option

- Add gemini_native to ClaudeApiFormat type and ProviderMeta.apiFormat
- Add "Gemini Native" provider preset with default Google AI endpoints
- Show Gemini-specific endpoint hints and full-URL mode guidance
- Add gemini_native option to API format selector in ClaudeFormFields
- Add i18n strings for zh/en/ja

* feat(proxy): add Gemini Native tool argument rectification

* feat(proxy): update Gemini streaming and transformation logic

* fix(proxy): align shadow turns to tail on client history truncation

* fix: revert unrelated cache_key change in claude proxy transform

Restore .unwrap_or(&provider.id) fallback for cache_key to match main
branch behavior. Only gemini_native related changes should be in this branch.

* Prevent Gemini review regressions in streaming and tool rectification

PR #1918 review feedback exposed two correctness issues in the Gemini Native adapter path. Gemini SSE buffering was still using lossy UTF-8 decoding, which could corrupt split multibyte payloads and drop streamed output. Tool arg rectification also removed top-level parameters eagerly, which broke tools that legitimately define a parameters field.

This change moves Gemini SSE buffering onto the existing append_utf8_safe path and makes parameters flattening conditional on the schema actually expecting nested extraction. The old Skill rectification path stays intact, and new regression tests cover both the preserved parameters case and UTF-8-split JSON payloads.

Constraint: Existing PR #1918 review feedback must be fixed without staging unrelated local docs and artifact files
Rejected: Keep String::from_utf8_lossy in Gemini SSE buffering | corrupts split multibyte payloads and can drop JSON chunks
Rejected: Always preserve the parameters wrapper | regresses the existing nested-parameters rectification path for Skill-style tools
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep Gemini SSE buffering on the UTF-8-safe accumulator path and only unwrap parameters when the target schema does not declare it as a legitimate field
Tested: cargo fmt --manifest-path src-tauri/Cargo.toml --all; cargo test --manifest-path src-tauri/Cargo.toml preserves_utf8_boundaries_when_json_payload_spans_chunks; cargo test --manifest-path src-tauri/Cargo.toml gemini_to_anthropic_rectifies_tool_args_from_schema_hints; cargo test --manifest-path src-tauri/Cargo.toml rectifies_streamed_skill_args_from_nested_parameters; cargo test --manifest-path src-tauri/Cargo.toml gemini_to_anthropic_preserves_legitimate_parameters_arg
Not-tested: Full src-tauri test suite; live end-to-end Gemini relay traffic against upstream services

* Keep Gemini tool replay stable across Claude request boundaries

Claude Code follow-up requests were still falling back to locally reconstructed functionCall parts, which dropped Gemini thought signatures and triggered INVALID_ARGUMENT errors from the official Gemini API. The replay path needed to survive real Claude request boundaries, not just idealized in-process test flows.

This change makes Claude requests reuse X-Claude-Code-Session-Id as the shadow session key, records streamed Gemini tool turns before tool_use events are fully drained, and matches assistant tool_use turns to shadow state by tool_use id and normalized tool name before positional fallback. Together these fixes keep thoughtSignature-bearing Gemini tool calls available for the next request in the loop.

Constraint: Claude Code sends a stable X-Claude-Code-Session-Id header while metadata.session_id may be absent on follow-up requests
Rejected: Rely on metadata-only Claude session extraction | generated fresh session ids and broke cross-request shadow replay
Rejected: Record Gemini shadow only after streaming completes | loses the race when the client sends the next request immediately after tool_use
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Preserve Gemini shadow continuity across requests by keying Claude sessions from the header first and persisting tool-call shadow before yielding tool_use events downstream
Tested: cargo fmt --manifest-path src-tauri/Cargo.toml --all; cargo test --manifest-path src-tauri/Cargo.toml test_extract_session_from_claude_header; cargo test --manifest-path src-tauri/Cargo.toml test_extract_session_from_claude_header_precedes_metadata; cargo test --manifest-path src-tauri/Cargo.toml stores_tool_shadow_before_tool_use_events_are_fully_drained; cargo test --manifest-path src-tauri/Cargo.toml shadow_replay_matches_tool_use_turn_by_id_when_position_drifts; cargo test --manifest-path src-tauri/Cargo.toml shadow_replay_aligns_to_latest_turns_after_client_truncation
Not-tested: Full src-tauri test suite without test filters; live end-to-end Gemini relay after this exact commit hash

* style: apply cargo fmt to pass Backend Checks CI

Wrap prompt_cache_key chained call across lines per rustfmt default
formatting. Pure formatting change, no behavior difference.

* fix(proxy/gemini): synthesize unique ids for no-id tool calls + enforce object params schema

P1 — Parallel tool calls without Gemini-assigned ids no longer collapse.
Gemini 2.x native parallel `functionCall` entries may omit the `id` field.
The previous `merge_tool_call_snapshots` fell back to matching by `name`,
which silently merged two parallel calls to the same function into one
entry — dropping the first call's args. The non-streaming path and shadow
store further bottlenecked on empty-string ids: multiple `tool_use` blocks
shared the same id, and `tool_name_by_id.get("")` could only return one
mapping, causing later `tool_result` round-trips to fail with
`Unable to resolve Gemini functionResponse.name` or bind to the wrong tool.

Fix: introduce `synthesize_tool_call_id()` producing `gemini_synth_<uuid>`.
Both streaming and non-streaming response paths now guarantee every
Anthropic-visible tool_use carries a unique id. `merge_tool_call_snapshots`
matches by id first, falling back to the `parts` array position (for the
cumulative-streaming case) while preserving the synthesized id across
chunks. `convert_message_content_to_parts` detects the synthetic prefix
and strips the id from outbound `functionCall`/`functionResponse` so the
internal identifier never leaks upstream. `shadow_parts` performs the
same strip when replaying a recorded assistant turn.

P2 — Vertex AI rejects empty `parameters` schemas. When an Anthropic tool
arrives with missing or empty `input_schema`, the proxy used to emit
`"parameters": {}` (no `type`), which fails Vertex AI validation with
`functionDeclaration parameters schema should be of type OBJECT`.
Contrary to the automated-review suggestion, the fix is not to omit
`parameters` (that too is rejected) but to normalize to the canonical
empty-object form `{type: "object", properties: {}}`.
Refs: google-gemini/generative-ai-python#423, BerriAI/litellm#5055.

Fix: new `ensure_object_schema` helper in `gemini_schema` promotes
missing `type` to `"object"` and adds empty `properties` when absent,
while leaving atomic (non-object) schemas untouched.

Tests: seven new regressions covering parallel no-id calls, cumulative
chunk id reuse, synthetic-id round-trip both directions, shadow replay
id stripping, and the three Vertex-AI schema shapes.

The two existing wrapper functions (`gemini_to_anthropic` and
`gemini_to_anthropic_with_shadow`) gain `#[allow(dead_code)]` to clear
a pre-existing clippy -D warnings failure — they are part of the public
transform API surface and intentionally kept for future callers.

Addresses Codex review P1/P2 on #1918.

* fix(proxy/gemini): narrow URL normalization + guard empty OAuth access_token

P2a — Preserve opaque relay URLs that contain `/v1/models/` prefixes.

`should_normalize_gemini_full_url` previously flagged any full URL whose
path merely contained `/v1beta/models/` or `/v1/models/` as a structured
Gemini endpoint, forcing rewrite to `.../v1beta/models/{model}:method`.
This silently dropped legitimate relay route segments (e.g.
`https://relay.example/v1/models/invoke` → `.../v1beta/models/...:generateContent`,
losing `/invoke`) and sent traffic to the wrong upstream path.

Replace the bare `contains(...)` checks with
`matches_structured_gemini_models_path`, which requires the
`/models/` segment to be followed by a canonical Gemini method call
(`*:generateContent` or `*:streamGenerateContent`). The
`matches_bare_gemini_models_path` helper is generalized (and renamed) to
handle both `/v1beta/models/` and `/v1/models/` alongside the original
bare `/models/` shape.

P2b — Reject empty Gemini OAuth access_tokens before they reach the
bearer header.

`GeminiAdapter::parse_oauth_credentials` accepts refresh-token-only JSON
(and surfaces `{"access_token": "", ...}` for expired credentials) with
`access_token` defaulting to `""`. The Claude adapter's GeminiCli branch
then called `AuthInfo::with_access_token(key, creds.access_token)`
unconditionally, so the bearer-header builder at
`AuthStrategy::GoogleOAuth` resolved to `Authorization: Bearer ` — a
deterministic 401 from upstream.

CC Switch does not currently exchange the refresh_token for a fresh
access_token (`OAuthCredentials::needs_refresh` / `can_refresh` are
annotated `#[allow(dead_code)]`). Until that exists, only attach
`access_token` when it is non-empty; fall back to plain GoogleOAuth
strategy with the raw key and log a warn pointing users at
`~/.gemini/oauth_creds.json` so the failure mode is observable.

Tests:
- gemini_url.rs: three new regressions — opaque `/v1/models/invoke`,
  opaque `/v1beta/models/route`, and the positive counter-case where a
  structured `/v1/models/...:generateContent` path still normalizes.
- claude.rs: three new `test_extract_auth_gemini_cli_*` tests covering
  refresh-only JSON, empty-string access_token JSON, and the valid-JSON
  pass-through.

All 839 lib tests pass; cargo fmt + clippy -D warnings clean.

Addresses Codex review P2 findings on #1918.

* fix(proxy/gemini): treat empty-string functionCall id as missing in streaming path

Follow-up to the earlier P1 fix: some Gemini relays serialize an absent
functionCall id as `"id": ""` instead of omitting the field. The
non-streaming `extract_tool_call_meta` already filters these via
`.filter(|s| !s.is_empty())`, but the streaming counterpart
`extract_tool_calls` passed the empty string straight through
`function_call.get("id").and_then(|v| v.as_str())` into
`GeminiToolCallMeta::new`, producing a `Some("")` id.

Downstream, `merge_tool_call_snapshots` would then match two parallel
no-id calls against each other on their shared empty-string id,
collapsing them into a single snapshot (silent data loss for the first
call) and emitting an Anthropic `tool_use.id: ""` that breaks tool_result
correlation on the Claude Code client.

Fix:
- `extract_tool_calls`: apply the same `filter(|s| !s.is_empty())` guard
  used in the non-streaming path so empty strings become `None` before
  reaching the shadow meta.
- `merge_tool_call_snapshots`: defensively collapse any incoming
  `Some("")` to `None` up front — keeps the "missing vs present" invariant
  local to the merge step for future callers that might build
  `GeminiToolCallMeta` by hand.

Tests (2 new, both in streaming_gemini):
- `parallel_empty_string_id_calls_are_treated_as_missing_and_preserved`
  covers two parallel calls with explicit `"id": ""` — asserts both
  surface, no empty tool_use id leaks, and each gets a unique
  `gemini_synth_` id.
- `single_empty_string_id_tool_call_gets_synthesized_id` covers the
  non-parallel degraded-relay case.

All 841 lib tests pass; cargo fmt + clippy -D warnings clean.

Addresses Codex follow-up P1 on #1918.

* fix(proxy/gemini): gate generic REST path suffixes behind Google host whitelist

`should_normalize_gemini_full_url` previously treated any full URL whose
path ends with `/v1`, `/v1/models`, `/models`, `/v1/openai`, or `/openai`
as a structured Gemini endpoint and rewrote it to
`/v1beta/models/{model}:generateContent`. These are ubiquitous REST
conventions — opaque relays such as `https://relay.example/custom/v1`
legitimately use them for fixed endpoints — so the rewrite silently
routed traffic to the wrong upstream path.

Split the predicate into two layers:

- **Unconditional**: `matches_structured_gemini_models_path` (i.e. a
  `/models/...:generateContent` method call anywhere in the path), the
  Google-specific `/v1beta*` family, and the deep OpenAI-compat paths
  (`/v1beta/openai/chat/completions`, `/openai/chat/completions`, and
  their `responses` siblings). These remain host-agnostic because the
  path grammar itself is Gemini-specific.
- **Google-host gated**: `/v1`, `/v1/models`, `/models`, `/v1/openai`,
  `/openai`. Only normalized when the host is one of
  `generativelanguage.googleapis.com`, `aiplatform.googleapis.com`, or a
  real `*-aiplatform.googleapis.com` Vertex regional endpoint. The match
  is exact/suffix (not `contains`), so lookalike hosts like
  `aiplatform.example.com` are correctly treated as opaque relays.

Tests (8 new in `gemini_url::tests`):
- Four opaque-relay cases: `/custom/v1`, `/custom/models`,
  `/custom/v1/models`, `/custom/openai` — all preserved as-is.
- Three Google-host counter-cases: `/v1`, `/models`, and
  `us-central1-aiplatform.googleapis.com/v1` still normalize.
- One lookalike safety case: `aiplatform.example.com/v1` is NOT
  treated as Google.

All 849 lib tests pass; cargo fmt + clippy -D warnings clean.

Addresses Codex review P2 on #1918.

* fix(proxy/gemini): align shadow id with client-visible id in non-streaming path

When Gemini returns a `functionCall` without an id (common in 2.x
parallel calls), `gemini_to_anthropic_with_shadow_and_hints` previously
generated TWO independent synthesized UUIDs:

  1. Line 186-197 — synthesized id `A` used for the Anthropic-visible
     `content[tool_use].id` returned to the client.
  2. Line 850-881 — `extract_tool_call_meta` independently synthesized
     id `B ≠ A`, which populated `shadow_turn.tool_calls[i].id`.

`shadow_content` (line 225-228, cloned from `rectified_parts`) retained
the original missing/empty id. Result: the client sees id `A`, the
shadow store holds id `B`.

On the next turn, `convert_messages_to_contents` builds
`tool_name_by_id` from `build_tool_name_map_from_shadow_turns`, which
uses `tool_calls[i].id` — so the map contains `B → name` but not
`A → name`. When the client sends back `tool_result(tool_use_id=A)`,
resolution fails with:

  Unable to resolve Gemini functionResponse.name for tool_use_id `A`

This affects both truncated histories (client sends only the
tool_result) and full histories (shadow-replay branch at line 342-354
skips `convert_message_content_to_parts`, so the assistant tool_use
block never registers id `A` itself).

Fix: make `rectified_parts` the single source of truth. After
`rectify_tool_call_parts`, run a pre-pass that writes
`synthesize_tool_call_id()` back into any `functionCall` that lacks a
non-empty id. All three readers — the content builder (186-197), the
shadow_content clone (225-228), and `extract_tool_call_meta` — then
observe the same id. `shadow_parts()` already strips synthesized ids on
replay (line 616-628), so the internal identifier never leaks to
Gemini upstream.

This mirrors the streaming path, which already has single-source-of-
truth semantics via `tool_call_snapshots` in `streaming_gemini.rs` —
no change needed there.

Tests (5 new in `transform_gemini::tests`):
- `non_stream_shadow_id_matches_client_visible_id`: asserts
  `response.content[0].id == shadow.tool_calls[0].id ==
  shadow.assistant_content.parts[0].functionCall.id`.
- `non_stream_missing_id_scenario_a_truncated_history_resolves`: turn 2
  sends only `[tool_result(id=A)]`; resolution must succeed.
- `non_stream_missing_id_scenario_b_full_history_replay_resolves`: turn 2
  sends `[assistant(tool_use=A), tool_result(A)]`; shadow-replay branch
  strips the synth id from outgoing `functionCall` while still
  resolving the subsequent `tool_result`.
- `non_stream_preserves_original_gemini_id_when_present`: regression —
  genuine Gemini ids flow through unchanged.
- `non_stream_synthesized_id_not_leaked_to_gemini_via_shadow_replay`:
  defensive — shadow-replay path must strip synth ids from both
  `functionCall.id` and `functionResponse.id`.

All 854 lib tests pass; cargo fmt + clippy -D warnings clean.

Addresses Codex follow-up P1 on #1918.

* refactor(proxy/gemini): share build_anthropic_usage between stream and non-stream paths

`streaming_gemini::anthropic_usage_from_gemini` and
`transform_gemini::build_anthropic_usage` were byte-for-byte identical
(32 lines each) — both converting Gemini `usageMetadata` into the
Anthropic `usage` shape including `cache_read_input_tokens` mapping.

Promote the non-streaming version to `pub(crate)` and reuse it from the
streaming SSE converter. Removes ~30 lines of duplication and guarantees
the two paths cannot drift apart.

No behavioral change; all 854 lib tests pass; cargo fmt + clippy -D
warnings clean.

* fix(proxy/gemini): gate /v1beta behind Google host + normalize models/ model id prefix

Two related P2 corrections to the Gemini Native URL surface, both
folding into the existing Google-host-whitelist architecture.

## P2a — `/v1beta` suffix should not unconditionally trigger rewrite

`should_normalize_gemini_full_url` placed `/v1beta` and `/v1beta/models`
in the unconditional layer on the reasoning that `/v1beta` is
Google-specific. In practice an opaque relay fronting a non-Gemini
service at `https://relay.example/custom/v1beta` would still be
silently rewritten to `/v1beta/models/{model}:generateContent`,
breaking the deployment.

Move `/v1beta`, `/v1beta/models`, and `/v1beta/openai` into the
Google-host gated layer alongside `/v1`, `/models`, and friends. The
unconditional layer now only accepts paths whose grammar is
intrinsically Gemini — `/models/...:generateContent` method calls and
the deep OpenAI-compat endpoints like `/openai/chat/completions` and
`/openai/responses`. Pasted AI-Studio URLs such as
`https://generativelanguage.googleapis.com/v1beta` still normalize
because the host matches the whitelist.

## P2b — `model: "models/gemini-2.5-pro"` produced doubled path prefix

Gemini SDKs (and the official `list_models` response) commonly surface
model ids in resource-name form `models/gemini-2.5-pro`. Raw
interpolation into `format!("/v1beta/models/{model}:...")` produced
`/v1beta/models/models/gemini-2.5-pro:streamGenerateContent` which
upstream rejects — yielding false-negative health checks for otherwise
valid provider configs.

Introduce `normalize_gemini_model_id(&str) -> &str` in `gemini_url`
as the single source of truth: strips an optional leading `/` then an
optional `models/` prefix, leaving bare ids untouched. Apply in the
three call sites that build a Gemini method URL:
- `services/stream_check.rs::resolve_claude_stream_url` (unified path)
- `services/stream_check.rs::check_gemini_stream` (Gemini-only path)
- `proxy/forwarder.rs::rewrite_claude_transform_endpoint` (production)

Tests (9 new):
- `gemini_url`: 3 regressions for opaque vs Google-host `/v1beta*`
  handling + 5 unit tests pinning `normalize_gemini_model_id` behavior
  (strip prefix, leave bare id, preserve nested slashes past the one
  stripped prefix, tolerate leading slash, pass through empty input).
- `stream_check`: one end-to-end regression confirming
  `models/gemini-2.5-pro` collapses to the expected single-prefix URL.
- `forwarder`: one end-to-end regression on the production rewrite
  path.

All 864 lib tests pass; cargo fmt + clippy -D warnings clean.

Addresses Codex P2 feedback on #1918.

* fix(proxy/gemini): trim API key before provider-type detection and OAuth parsing

Leading whitespace on a copied oauth_creds.json (e.g. trailing newline
when the user copies the file content as-is) would slip past the
`starts_with("ya29.") || starts_with('{')` prefix check in
`ClaudeAdapter::provider_type`, causing the provider to be misclassified
as raw-API-key Gemini and fall back to `x-goog-api-key` with the raw
JSON as the key — which upstream rejects with 401.

The frontend's `handleApiKeyChange` already trims on keystrokes but
deep-link imports, the JSON editor, and live-config backfill all bypass
that path. Trim at every backend extraction point so the coverage is
uniform:

- `ClaudeAdapter::extract_key` (5 env / fallback branches) gets
  `.map(str::trim)` before `.filter(|s| !s.is_empty())` so that
  whitespace-only values are also treated as missing.
- `GeminiAdapter::extract_key_raw` gets the same chain (including
  the `.filter` it was missing before).
- `GeminiAdapter::parse_oauth_credentials` gets a defensive
  `let key = key.trim();` at the entry as a belt-and-suspenders guard.

Adds two regression tests covering JSON and bare `ya29.` keys with
leading newline/space.

* fix(proxy/gemini): gate generic REST suffix stripping behind Google host in non-full-URL mode

`build_gemini_native_url` unconditionally stripped `/v1`, `/v1beta`,
`/models`, and `/openai` suffixes from the base path regardless of
host. This worked for Google's own endpoints but silently rewrote
third-party relay URLs like `https://relay.example/custom/v1` to
`.../custom/v1beta/models/...`, breaking any relay that mounts its
Gemini-compatible namespace under a versioned prefix.

The result was also asymmetric with the previously-fixed full-URL
branch: toggling the "full URL" switch changed the outbound URL for
the same base_url, which is exactly the kind of invisible behavior
that makes debugging proxy deployments painful.

Align `normalize_gemini_base_path` with
`should_normalize_gemini_full_url`'s layered model:

- Unconditional: `/models/...:method` structured paths and deep
  OpenAI-compat endpoints (`/openai/chat/completions`,
  `/openai/responses` and their versioned variants) — these are
  unambiguous Gemini-specific grammar on any host.
- Google-host gated: generic `/v1`, `/v1beta`, `/models`, `/openai`
  suffixes only get stripped on `generativelanguage.googleapis.com`,
  `aiplatform.googleapis.com`, or `*-aiplatform.googleapis.com`.
  Other hosts preserve the prefix verbatim so relays keep their
  intended routing.

Adds seven regression tests for the non-full-URL flow: opaque relay
preservation (v1 / v1beta / models / openai suffix variants), Google
host normalization (counter-case), and boundary cases (structured
method path and deep OpenAI-compat endpoint stripped regardless of
host).

Test count: 864 -> 873.

* Revert "fix(proxy/gemini): gate generic REST suffix stripping behind Google host in non-full-URL mode"

This reverts commit d19ff09cb7.

* test(proxy/gemini): pin non-full-URL versioned relay base stripping

Adds two regression tests that lock in the intentional asymmetry
between full-URL and non-full-URL modes:

- Full-URL mode: opaque base path (e.g. `https://relay.example/custom/v1beta`)
  is preserved verbatim. Already covered by
  `preserves_opaque_full_url_with_bare_v1beta_suffix`.
- Non-full-URL mode: base path MUST strip `/v1`, `/v1beta`, etc. so the
  standard `/v1beta/models/{model}:method` endpoint can be appended
  without producing a doubled `/v1beta/v1beta/models/...` path.

The non-full-URL contract is "base URL + cc-switch appends the
canonical Gemini endpoint". A user who needs a relay's custom
namespace (e.g. `/v1/models/...`) must use full-URL mode and paste
the complete method path. This commit adds regression coverage so a
future attempt to mirror full-URL's host-whitelist gating into
`normalize_gemini_base_path` will fail the test suite immediately.

* chore(lint): address clippy 1.95 findings in existing modules

CI upgraded to Rust 1.95 and flagged ten pre-existing warnings that
older toolchains did not enforce. None relate to the Gemini proxy
integration PR itself but they block CI on the feature branch, so
clean them up here as a separate commit for easy review:

collapsible_match:
- proxy/providers/gemini_schema.rs: `"items" if value.is_object()`
  match guard instead of nested if.
- proxy/providers/transform_responses.rs: fold
  `map_responses_stop_reason`'s `"completed"` / `"incomplete"` arms
  into match guards, relying on the existing `_ => "end_turn"` fall-
  through for non-matching guard conditions (semantics preserved).
- services/session_usage_codex.rs: fold
  `"session_meta" if state.session_id.is_none()` guard, relying on
  the existing `_ => {}` fall-through.

unnecessary_sort_by:
- services/provider/endpoints.rs: `sort_by_key(|ep| Reverse(ep.added_at))`.
- services/skill.rs (backup list): same Reverse idiom on `created_at`.
- services/skill.rs (skill listings x2): `sort_by_key(|s| s.name.to_lowercase())`.

useless_conversion:
- services/skill.rs: drop the explicit `.into_iter()` on `zip`'s argument.

while_let_loop:
- services/webdav_auto_sync.rs: `while let Some(wait_for) = ...`
  instead of `loop { let Some(...) = ... else { break }; ... }`.

All changes are mechanical and preserve behavior. `cargo test --lib`
remains green (868 passed).

* fix(proxy/gemini): reconcile synthesized tool-call ids with later real ids + preserve thoughtSignature

Three related findings on `streaming_gemini.rs` for Gemini's cumulative
`streamGenerateContent` stream, all centered on `merge_tool_call_snapshots`:

1. (P1) Match upgraded tool-call IDs by position.
   When Gemini delivers a `functionCall` without an id on chunk 1
   (cc-switch synthesizes `gemini_synth_*`) and then upgrades it to a
   real id on chunk 2, the `Some(incoming_id)` branch only matched by
   id and missed the existing synthesized snapshot. A second entry
   would be pushed, yielding duplicate `tool_use` content blocks at
   stream end — one with the synthesized id, one with the real id —
   which could trigger duplicate tool execution and break tool_result
   correlation. Add a positional fallback: when no id match exists but
   the same-position slot holds a synthesized id, merge into it.
   `or(preserved_id)` already lets the real id win the merge.

2. (P2) Preserve prior thoughtSignature when merging snapshots.
   `tool_call_snapshots[index] = tool_call` overwrote the slot
   entirely, dropping any `thoughtSignature` captured on an earlier
   chunk if the current cumulative snapshot omitted it. Since
   `build_shadow_assistant_parts` writes `thoughtSignature` into the
   shadow turn from `tool_call.thought_signature`, a dropped signature
   would cause later replay requests to Gemini to be rejected with
   invalid-signature errors. Preserve the existing signature when the
   incoming chunk does not carry one.

3. (P2) Document the part-order streaming trade-off.
   All `tool_use` content blocks are emitted after the final text
   `content_block_stop`, so interleaved [text, functionCall, text,
   functionCall] parts arrive at the Anthropic client as [text(concat),
   tool_use, tool_use] — different from the non-streaming transformer,
   which preserves part order. This is intentional given the cumulative
   snapshot model and the consumers we target (claude-code-like clients
   don't depend on strict interleaving for tool execution correctness).
   Add a block comment at the flush site describing the trade-off and
   what a strict-order fix would entail, so this isn't rediscovered as
   a bug later.

Regression tests:
- upgraded_real_id_merges_into_existing_synthesized_snapshot
- thought_signature_preserved_when_later_chunk_omits_it

Test count: 868 -> 870. clippy 1.95 clean. fmt clean.

* fix(proxy/gemini): prefer exact tool-call id over normalized-name fallback

The shadow-turn matcher used a three-branch `||` chain (id / full name /
normalized name). When two tools share a suffix (e.g. `server_a:search`
and `server_b:search`), the normalized-name clause could short-circuit
on an earlier turn whose id is actually wrong for the incoming tool_use,
mis-routing replay state (functionCall id / thoughtSignature) for later
tool_result resolution.

Split matching into two layers: when the incoming message carries any
tool_use ids, run id-based lookup first and return on the earliest hit.
Only fall back to full-name / normalized-name matching when the incoming
ids are absent or none of them resolve.

Add two regressions:

- shadow_replay_prefers_exact_id_match_over_normalized_name_collision
  Two shadow turns with colliding normalized names and two assistant
  messages whose ids cross the positional order; asserts each message
  replays the id-correct shadow turn (including thoughtSignature).

- shadow_replay_falls_back_to_name_when_ids_absent
  Shadow turn with no id and incoming tool_use with an empty id;
  asserts the name fallback still populates the replayed part.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-04-16 22:42:49 +08:00
Dex Miller de23216e49 feat(usage): refine usage dashboard UI and date range picker (#2002)
* feat(usage): enhance usage stats backend and query hooks

* feat(usage): redesign calendar date range picker with auto-switch and simplified layout

* refactor(usage): streamline dashboard layout and stats components

* refactor(usage): compact request log table with merged cache/multiplier columns and centered layout

* feat(i18n): add cache short labels and usage stats translations for zh/en/ja

* Align usage dashboard stats with range boundaries

The usage dashboard mixed second-precision detail rows with day-level rollups, which caused custom half-day ranges to overcount historical rollup data and left the request log paginator on stale pages after top-level filter changes.

This change limits rollups to fully covered local days, aligns multi-day trend buckets with natural local days, and resets request log pagination when the dashboard range or app filter changes.

Constraint: usage_daily_rollups stores only daily aggregates after pruning old detail rows
Rejected: Include partial boundary rollups proportionally | historical intra-day detail is unavailable after pruning
Rejected: Force RequestLogTable remount on range change | would discard local draft filters unnecessarily
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep summary, trends, provider stats, and model stats on the same rollup-boundary rules
Tested: cargo test --manifest-path src-tauri/Cargo.toml usage_stats
Tested: pnpm exec vitest run tests/components/RequestLogTable.test.tsx
Tested: pnpm typecheck
Not-tested: Manual UI validation in the Tauri app

* Preserve full-day usage filters at minute precision

The latest review surfaced two interaction bugs in the usage dashboard: rollup-backed stats undercounted end days selected via the minute-precision picker, and immediate select changes accidentally applied unsubmitted text drafts from the request log filters.

This change treats 23:59 as a fully selected local end day for rollup inclusion and narrows select-side state syncing so app/status updates do not commit provider/model drafts.

Constraint: The custom range picker emits minute-precision timestamps, while rollups are stored at day granularity
Rejected: Require exact 23:59:59 end timestamps | unreachable from the current picker UI
Rejected: Rebuild applied filters from the full draft state on select changes | silently commits unsaved text input
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep request-log text fields on explicit apply semantics even when select filters remain immediate
Tested: cargo test --manifest-path src-tauri/Cargo.toml usage_stats
Tested: pnpm exec vitest run tests/components/RequestLogTable.test.tsx
Tested: pnpm typecheck
Not-tested: Manual Tauri dashboard interaction

* refactor(usage): move range presets into date picker, single-row layout

- UsageDateRangePicker: add preset shortcuts (今天/1d/7d/14d/30d) inside
  popover top; clicking a preset applies immediately and closes popover
- UsageDashboard: collapse to single row (app filters + refresh + picker);
  remove standalone preset buttons and summary stats bar
- RequestLogTable: replace static Calendar badge with interactive
  UsageDateRangePicker via onRangeChange prop; single filter row

* Keep usage pagination regression coverage aligned with the rendered UI

The new regression test was asserting a non-existent pagination label and page summary text, so it failed before it could verify the real page-reset behavior. This commit switches the assertions to the numbered pagination buttons that the component actually renders and validates the reset through the query hook arguments.

Constraint: RequestLogTable exposes numbered pagination buttons, not a "Next page" label or "2 / 6" summary text
Rejected: Add synthetic pagination labels solely for the test | would couple production markup to a test-only assumption
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Prefer pagination assertions that follow the rendered controls or hook inputs instead of invented summary text
Tested: pnpm vitest run tests/components/RequestLogTable.test.tsx; pnpm typecheck; pnpm test:unit

* refactor(usage): clean up dead code and polish date range picker

- Remove unused exports MAX_CUSTOM_USAGE_RANGE_SECONDS,
  timestampToLocalDatetime, and localDatetimeToTimestamp from
  usageRange.ts (replaced by the calendar picker)
- Deduplicate getPresetLabel from UsageDashboard and
  UsageDateRangePicker into shared getUsageRangePresetLabel helper
- Add aria-label, aria-current and aria-pressed to calendar day
  buttons so screen readers can disambiguate same-numbered days
  across adjacent months
- Drop unused cacheReadShort and cacheWriteShort i18n keys (zh/en/ja);
  the request log table renders R/W prefixes inline
- Align customRangeHint copy with the removed 30-day limit by
  dropping "up to 30 days" wording (zh/en/ja)

* fix(usage): align rollup cutoff to local midnight to keep days complete

`rollup_and_prune` previously used `Utc::now() - retain_days * 86400`
as the cutoff. Because rollups are bucketed by *local* date and detail
rows below the cutoff are pruned, an unaligned cutoff left the youngest
rolled-up day half-rolled-up and half-pruned. Combined with the new
`compute_rollup_date_bounds` boundary trimming (which excludes any
rollup day not fully covered by the requested range), custom range
queries that touch that day silently under-count summary, trend,
provider, and model stats.

Fix the invariant at the source: snap the cutoff to the next local
midnight after `(now - retain_days)`. Every rollup row now reflects a
complete local day, so the boundary trimmer's all-or-nothing assumption
holds.

Includes unit tests for the cutoff math (typical case + already-on-
midnight case). DST gap is handled defensively by bumping forward by
an hour.

Addresses Codex P2 review finding on PR #2002.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-04-16 17:00:28 +08:00
Jason Young 507bf038a9 feat(stream-check): refresh default models and detect model-not-found errors (#2099)
* chore(stream-check): update default health check models to latest

Replaces deprecated gpt-5.1-codex@low with gpt-5.4@low and switches
the Gemini default from gemini-3-pro-preview to gemini-3-flash-preview
to pick the lightest variant of the latest series for fast, low-cost
health checks.

https://claude.ai/code/session_01NGWLchcTP76rJHjiP5Ehte

* feat(stream-check): detect model-not-found errors with dedicated toast

Health check previously classified failures purely by HTTP status code,
which meant deprecated/invalid models showed up as a generic "Not found
(404)" error pointing users to check the Base URL — misleading when the
URL is fine and only the test model is wrong (e.g. gpt-5.1-codex after
it was retired).

Backend: add detect_error_category() that inspects 4xx response bodies
for model-not-found indicators (model_not_found, does not exist,
invalid model, not_found_error, etc.) and returns a "modelNotFound"
category. Thread the resolved test model through build_stream_check_result
so the failed result carries it in model_used. Add StreamCheckResult
.error_category field (serde-skipped when None).

Frontend: useStreamCheck branches on errorCategory === "modelNotFound"
before the HTTP-status fallback and renders a toast.error with the model
name and a description pointing to Model Test Config. Add i18n keys
(modelNotFound / modelNotFoundHint) for zh/en/ja.

Tests: unit-test detect_error_category against real OpenAI/Anthropic
error shapes, 5xx false-positive avoidance, and plain 401 auth errors.

https://claude.ai/code/session_01NGWLchcTP76rJHjiP5Ehte

* fix(stream-check): add missing error_category field in fallback

The error_category field was added to StreamCheckResult in this branch
but the fallback constructor in stream_check_all_providers was not
updated, which broke cargo build.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-15 15:25:32 +08:00
Dex Miller ef41e4da46 fix(proxy): strip hop-by-hop response headers per RFC 7230 (#2060) 2026-04-15 11:28:56 +08:00
wwminger 78198e262b fix(opencode): use json5 parser for trailing comma tolerance (#2023)
* fix(opencode): use json5 parser for trailing comma tolerance

OpenCode CLI writes opencode.json with trailing commas (valid JSONC),
but CC Switch parsed it with serde_json (strict JSON), causing errors
like 'trailing comma at line 35 column 3'.

Switch to json5::from_str which accepts both JSON and JSONC. The json5
crate is already a project dependency. Change error type from
AppError::json() to AppError::Config() since json5::Error differs from
serde_json::Error.

* style(opencode): apply rustfmt to satisfy cargo fmt --check

The previous commit's .map_err(...) chain exceeded rustfmt's default
100-char max_width, breaking CI's `cargo fmt --check`. Let rustfmt
wrap the closure body as a multi-line block. No behavior change.

---------

Co-authored-by: 18067889926 <ming.flute@outlook.com>
Co-authored-by: Jason <farion1231@gmail.com>
2026-04-15 11:11:48 +08:00
Jason 79eb773195 fix: remove unused mut to pass clippy -D warnings 2026-04-15 09:16:22 +08:00
Jason 6092a87b40 fix: preserve env vars when saving Google Official Gemini provider (#2087)
write_gemini_live() unconditionally cleared env_map for GoogleOfficial
auth type, discarding user-configured env vars (e.g. GEMINI_MODEL).
Remove the env_map.clear() call so the user's settings_config.env is
written as-is, and merge identical Packycode/Generic match arms.
2026-04-15 09:05:45 +08:00
Jason 689ca08409 feat: classify stream check errors with color-coded toasts
Distinguish between "provider rejects probe" (yellow warning) and
"genuinely broken" (red error) in health check results.

Backend: add AppError::HttpStatus variant to carry structured HTTP
status codes, populate http_status on error results, classify codes
into short labels (e.g. "Auth rejected (401)"), and truncate overly
long response bodies.

Frontend: route 401/403/400/429/5xx to toast.warning with localized
hints explaining the error may not indicate actual unusability; route
404/402/connection errors to toast.error. Add i18n keys for all three
locales (zh/en/ja).

Also deduplicate check_once by reusing build_stream_check_result.
2026-04-14 17:11:13 +08:00
Jason 8b851dc602 fix: auto-expand collapsed messages when search matches hidden content
When a search query matches text beyond the collapse point, the message
automatically expands to show the highlighted match. Also adds
aria-expanded for accessibility.
2026-04-14 16:50:22 +08:00
Jason 0383c13e66 perf: collapse long session messages to reduce text layout cost
Messages over 3000 characters are now truncated to 1500 characters by
default, with an expand/collapse toggle. This avoids expensive browser
text layout for large AI responses containing code or tool output.
2026-04-14 16:16:57 +08:00
Jason 7ae89e9106 perf: virtualize session message list for long conversations
Replace full DOM rendering with @tanstack/react-virtual to only render
visible messages (~25 DOM nodes instead of N). Wrap SessionMessageItem
in React.memo to prevent unnecessary re-renders on state changes.
2026-04-14 16:12:48 +08:00
Jason 04508801ef fix: handle root-level skill repos during installation
When a repo itself is a single skill (SKILL.md at repo root), the
discovery phase sets directory to the repo name, but after ZIP
extraction (which strips the root folder), no matching subdirectory
exists. Add a fallback to check if SKILL.md exists directly in the
extracted temp directory before reporting SKILL_DIR_NOT_FOUND.

Fixes installation of repos like zlbigger/Google-SEOs.skill.
2026-04-14 15:56:31 +08:00
Jason 57343432da fix: remove duplicate usage summary from app filter bar
The request count and total cost were displayed both in the app filter
bar and in the UsageSummaryCards below it. Remove the redundant inline
summary and its unused imports.
2026-04-14 15:47:55 +08:00
Jason 5e412d2c30 refactor: remove per-provider proxy config feature
Replace all remaining "代理服务/Proxy Service/プロキシサービス" references
in the local routing feature context with "路由服务/Routing Service/
ルーティングサービス". This covers service settings, status messages,
tooltips, field descriptions, and tab labels.

Global Proxy, HTTP proxy hints, and AI Agent references are unchanged.
2026-04-14 15:39:23 +08:00
Jason 36f2d6cccb docs: clarify global proxy hint about local routing across all locales 2026-04-14 15:26:08 +08:00
Jason 989c445828 docs: rename takeover docs to routing across all languages
Rename 4.2-takeover.md to 4.2-routing.md in zh/en/ja user manuals,
replacing all "接管/takeover" terminology with "路由/routing" to match
the rebranded feature name. Update README index links accordingly.
2026-04-14 15:15:39 +08:00
Jason 7ec92c32a5 rename: rebrand "Local Proxy Takeover" to "Local Routing" in all locales
Replace all user-facing references to "本地代理接管/Local Proxy/Takeover"
with "本地路由/Local Routing/ローカルルーティング" across zh/en/ja to
eliminate naming confusion with the separate "Global Proxy" feature.

Only i18n string values are changed; keys, code identifiers, and
database schema remain untouched.
2026-04-14 15:13:59 +08:00
Jason 4a0b5c3dec refactor: remove per-provider proxy config feature
The per-provider proxy configuration (meta.proxyConfig) is removed
because its scope is too narrow and covered by global proxy settings
and proxy takeover mode. Users can achieve the same result via the
global proxy panel.

Changes:
- Remove ProviderProxyConfig type (frontend TS + backend Rust)
- Remove ProviderAdvancedConfig proxy UI block, keep testConfig/pricingConfig
- Simplify http_client: delete build_proxy_url_from_config,
  build_client_for_provider, get_for_provider
- Simplify forwarder/stream_check/model_fetch to use global client
- Remove i18n keys (en/zh/ja)
- Fix pre-existing test bug in transform.rs (extra None arg)
2026-04-14 14:26:55 +08:00
Jason 449a171238 Add LemonData sponsor and update partner logo formats
Add new sponsor LemonData to partner section. Update Crazyrouter logo
from JPG to PNG format.
2026-04-14 11:15:25 +08:00
Jason c60f204808 Update partner logos and sync across languages
Synchronize Crazyrouter logo format and partner section updates across
EN/JA/ZH README files.
2026-04-14 10:58:36 +08:00
Jason d13a8d7353 fix(clippy): remove redundant closure in session ID parsing
Replace `|uid| parse_session_from_user_id(uid)` with direct
function reference to satisfy clippy::redundant_closure.
2026-04-14 10:34:58 +08:00
Jason 0739b60341 fix(proxy): reduce unnecessary Copilot premium interaction consumption
- Fix request classification: treat messages containing tool_result as
  agent continuation instead of user-initiated, preventing false premium
  charges on every tool call
- Add subagent detection via __SUBAGENT_MARKER__ and metadata._agent_
  fallback, setting x-interaction-type=conversation-subagent
- Add deterministic x-interaction-id derived from session ID to group
  requests into a single billing interaction
- Add orphan tool_result sanitization to prevent upstream API errors
  that could cause retries and duplicate billing
- Reorder pipeline: classify (on original body) → sanitize → merge →
  warmup, ensuring classification sees raw tool_result semantics
- Enable warmup downgrade by default with gpt-5-mini model
- Enhance session ID extraction priority chain for Copilot cache keys
- Detect infinite whitespace bug in streaming tool call arguments
2026-04-14 10:34:58 +08:00
Jason c01338ac33 fix(usage): remove unnecessary private IP restrictions from usage script
SSRF protection (private IP blocking, suspicious hostname detection) was
originally added for web-server threat models but is unnecessary for a
local desktop app where the user already has full network access. This
removal unblocks legitimate use cases like enterprise intranet APIs,
Docker container addresses, and self-hosted services.

Retained: HTTPS enforcement and same-origin checks which still provide
meaningful security (protecting API keys in transit and preventing
scripts from leaking keys to unrelated domains).
2026-04-14 10:33:41 +08:00
Jason 8c94c23c3c chore: update PIPELLM website URL to code.pipellm.ai 2026-04-14 10:33:41 +08:00
Jason d6fa611833 chore: remove X-Code API (XCodeAPI) provider preset and sponsorship 2026-04-14 10:33:41 +08:00
Jason 5c1b457520 fix(usage): sync request log time range with dashboard 1d/7d/30d selector
The RequestLogTable had a hardcoded 24-hour rolling window, ignoring the
dashboard's time range selector. Now it accepts a timeRange prop and
dynamically adjusts the query window, so users can view logs beyond just
the last day.
2026-04-14 10:33:41 +08:00
Jason 3c8f9d1287 feat(usage): improve pagination with first/last 3 pages and page jump input
Show first 3 and last 3 page buttons instead of just first/last, with
Set-based deduplication for clean edge merging. Add a page number input
field with Go button for direct page navigation.
2026-04-14 10:33:41 +08:00
Jason 420f4c8c23 fix(sessions): strip OpenClaw message_id suffix and allow 2-line titles
OpenClaw gateway injects `[message_id: UUID]` metadata at the end of
every message, wasting display space. Strip this suffix from both title
and summary fields.

Also change session title display from single-line truncate to
line-clamp-2, so longer titles (e.g. OpenClaw's timestamp-prefixed
messages) can show more meaningful content across two lines.
2026-04-14 10:33:41 +08:00
Jason ed269cc20e feat(sessions): extract meaningful titles for Codex and OpenClaw sessions
Previously Codex and OpenClaw sessions only showed the working directory
basename as the title, making it hard to distinguish sessions in the same
project. Now both providers extract the first real user message as the
session title, matching the existing Claude Code behavior.

- Codex: first user message → dir basename (skips AGENTS.md injection)
- OpenClaw: displayName (sessions.json) → first user message → dir basename
- Move TITLE_MAX_CHARS constant to shared utils.rs
- Use Option<&HashMap> for OpenClaw parse_session to avoid leaky abstraction
2026-04-14 10:33:41 +08:00
Jason 8669b408e9 fix(usage): deduplicate proxy and session log usage records
Extract message_id from Claude API responses (msg_xxx) and use it to
generate a shared request_id format (session:{msg_xxx}) between the
proxy logger and session log sync. When session sync encounters the
same request_id via INSERT OR IGNORE, it skips the duplicate.

- Add message_id field to TokenUsage, extracted from Claude responses
- Add TokenUsage::dedup_request_id() to generate shared request IDs
- Define SESSION_REQUEST_ID_PREFIX constant to eliminate magic strings
- Change proxy logger to INSERT OR REPLACE for richer-data-wins semantics
2026-04-14 10:33:41 +08:00
Jason bb7c83c214 feat(pricing): add ~50 new model pricing entries and fix outdated prices
Add pricing data for 4 new providers (Qwen, xAI Grok, Mistral, Cohere)
and supplement existing providers (MiniMax M2.5/M2.7, GLM-5/5.1,
Doubao Seed 2.0, MiMo V2 Pro, OpenAI o1/o3/codex-mini/gpt-5-mini/nano).

Fix outdated prices for deepseek-chat, deepseek-reasoner, and kimi-k2.5.
Fix display_name casing "Mimo" → "MiMo" for consistency.

Use prepared statement in seed_model_pricing() to avoid recompiling SQL
on each of ~130 INSERT iterations.

Schema migration v8→v9: DELETE + re-seed model_pricing for existing users.
2026-04-14 10:33:41 +08:00
Jason a514f27937 feat: block official provider switching during proxy takeover
Prevent users from switching to official providers (Anthropic/OpenAI/Google)
when proxy takeover is active, as using a proxy with official APIs may cause
account bans.

Defense-in-depth across 4 layers:
- Backend: ProviderService::switch(), hot_switch_provider(), switch_proxy_provider command
- Frontend: useProviderActions soft guard with error toast
- UI: ProviderActions button disabled with ShieldAlert icon
- Tray menu: official provider items disabled with  indicator

Also warns when enabling proxy takeover while current provider is official.
2026-04-14 10:33:41 +08:00
zerone0x 2937eb6766 fix(proxy): remove permissive CORS layer (#1915) 2026-04-13 12:26:19 +08:00
Dex Miller 313a6e3f6c [codex] Preserve cache_control when merging system prompts (#1946)
* Preserve cache hints when collapsing system prompts

Strict OpenAI-compatible chat backends still need fragmented Claude\nsystem prompts collapsed into one leading system message, but that\nnormalization should not silently drop stable cache hints. Preserve\nmessage-level cache_control when the merged system fragments agree,\nand fall back to omitting it when the fragments conflict.\n\nConstraint: Must keep single-system normalization for Nvidia/Qwen-style chat backends\nRejected: Always copy the first cache_control | could misrepresent conflicting cache boundaries\nConfidence: high\nScope-risk: narrow\nReversibility: clean\nDirective: If system prompt merging changes again, preserve cache_control whenever the merged metadata is unambiguous\nTested: cargo test proxy::providers::transform --manifest-path src-tauri/Cargo.toml\nNot-tested: End-to-end prompt caching behavior against cache-aware OpenAI-compatible upstreams\nRelated: #1881

* Tighten cache hint inheritance for merged system prompts

The follow-up cache hint fix still treated mixed present/absent\ncache_control across fragmented system prompts as inheritable, which\nexpanded the cache scope after prompt collapse. Treat that mix as\nambiguous and only preserve cache_control when every merged fragment\nexplicitly agrees on the same value.\n\nConstraint: Must preserve strict-backend system prompt normalization from #1942\nRejected: Inherit first present cache_control | widens cache scope when later fragments were intentionally uncached\nConfidence: high\nScope-risk: narrow\nReversibility: clean\nDirective: Any future merged-system cache hint logic should treat missing cache_control as semantically significant\nTested: cargo test proxy::providers::transform --manifest-path src-tauri/Cargo.toml\nNot-tested: End-to-end upstream caching behavior against cache-aware relays\nRelated: #1881\nRelated: #1946

* Keep cache-control merge regressions easy to review

Reflow the two long cache-control regression assertions in transform.rs so the neighboring merge cases stay rustfmt-aligned and easier to scan.

This keeps the preserved code change separate from the untracked Markdown design notes the user did not want committed.

Constraint: Exclude Markdown design files from the commit while preserving the local code change
Rejected: Include docs in the same commit | user explicitly asked to leave Markdown files out
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Treat this as a readability-only test change; do not infer runtime behavior changes from it
Tested: cargo test --manifest-path src-tauri/Cargo.toml test_anthropic_to_openai_drops_ --lib
Tested: cargo check --manifest-path src-tauri/Cargo.toml --tests
Tested: pnpm format:check
Tested: pnpm typecheck
Not-tested: Full application integration and manual flows
2026-04-13 10:42:29 +08:00
Dex Miller 5566be2b4b Stop sending prompt cache keys on Claude chat conversions (#2003)
Responses conversions still use promptCacheKey, but chat completions now stay a pure shape transform. This keeps Claude -> chat requests aligned with providers that do not understand the field and keeps stream checks consistent with production behavior.

Constraint: Issue #1919 requires removing prompt_cache_key from Claude -> OpenAI Chat requests
Rejected: Add a runtime toggle for chat injection | requested behavior is unconditional removal
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep promptCacheKey limited to Claude -> Responses conversions unless a provider-specific contract is proven
Tested: cargo test anthropic_to_openai
Tested: cargo test anthropic_to_responses_with_cache_key
Tested: cargo test transform_claude_request_for_api_format_responses
Not-tested: Full src-tauri test suite
Related: #1919
2026-04-13 10:22:55 +08:00
v2v cfcf9452d0 添加应用级别窗口按钮,以改善linux wayland下系统窗口按钮失效的问题 (#1119)
* feat(window): add app-level window controls with settings toggle

Add a persistent settings toggle to enable app-level minimize/maximize/close controls and hide system decorations when enabled, providing a Wayland-friendly fallback for broken native titlebar interactions.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(window): restrict app-level window controls to Linux only and fix startup flicker

- Guard useAppWindowControls with isLinux() in App.tsx so it's always
  false on macOS/Windows even if persisted as true
- Wrap set_decorations call in lib.rs with #[cfg(target_os = "linux")]
- Only show the toggle in WindowSettings on Linux
- Skip setDecorations effect while settingsData is still loading to
  prevent the Rust-side decoration state from being overridden by the
  undefined->false fallback, which caused a brief title bar flicker

---------

Co-authored-by: wzk <wx13571681304@outlook.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Jason <farion1231@gmail.com>
2026-04-12 20:59:04 +08:00
Jason df01755328 docs(release-notes): sync user edits across en/zh/ja and add PR credits
- Simplify "ChatGPT Plus / Pro" → "ChatGPT" across all three languages
- Clarify Codex OAuth description to highlight Claude Code usage
- Add "requires manual activation" note for Token Plan and third-party balances
- Add Copilot API consumption caveat to the interaction optimizer section
- Update overview with skills.sh search, usage tracking, and onboarding mentions
- Add PR credits for TheRouter (@cmzz), Kaku/OMO Slim/Thinking fallback/auth tab (@yovinchen)
2026-04-10 23:44:06 +08:00
Jason 74b9f52d90 chore(release): bump version to v3.13.0 and sync changelog/release notes
Backfill post-draft changes into CHANGELOG and three-language release
notes (en/zh/ja): 16 new Added entries, 6 Fixed entries, 1 Docs entry,
and updated header stats (139 commits, 280 files, +31627/-3042).
2026-04-10 23:20:57 +08:00
Jason 8838317087 chore: simplify Codex provider preset name 2026-04-10 22:40:29 +08:00
Jason 4d570691e1 chore: add missing Shengsuanyun icon SVG file 2026-04-10 22:40:29 +08:00
Jason 337224546c feat: update PIPELLM preset with full config, add Codex support and icon
Update base URL to cc-api.pipellm.ai, add complete model definitions
(Opus/Sonnet/Haiku), add Codex preset with custom TOML config, add
pipellm PNG icon, and set apiKeyUrl to referral link.
2026-04-10 22:40:29 +08:00
Jason 7d21663e6d feat: add E-FlowCode provider preset across all five apps
Multi-protocol provider: Anthropic for Claude, OpenAI Responses for
Codex/OpenClaw, OpenAI for OpenCode, custom Gemini config. Includes
PNG icon via URL import and provider-specific settings like effortLevel,
enabledPlugins, and custom TOML config for Codex.
2026-04-10 22:40:29 +08:00
Jason 926e69b8c9 feat: add PIPELLM provider preset for Claude, OpenCode, and OpenClaw 2026-04-10 22:40:29 +08:00
Jason a03ad4f47f feat: add Shengsuanyun provider preset with partner promotion
Add Shengsuanyun (胜算云) as an aggregator partner across all five apps,
positioned right after official providers. Uses anthropic-messages
protocol for OpenCode/OpenClaw. Includes URL-based icon import (217KB
SVG), partner promotion i18n for zh/en/ja, and localized display name.
2026-04-10 22:40:29 +08:00
Jason c38bef517a fix: capitalize DDSHub provider display name 2026-04-10 22:40:29 +08:00
Jason 7526a031a7 chore: remove generate-icon-index.js to prevent accidental regeneration
The icon index (index.ts) is hand-curated with optimized SVG content
and custom name mappings. Running the generation script destroys these
optimizations. Remove the script entirely to eliminate the risk.
2026-04-10 22:40:29 +08:00
Jason 84bc98cf83 feat: add LionCCAPI provider preset with partner promotion
Add LionCCAPI as a third-party partner provider across all five apps
(Claude, Codex, Gemini, OpenCode, OpenClaw) with anthropic-messages
protocol for OpenCode and OpenClaw. Include partner promotion i18n
entries for zh/en/ja locales and lioncc icon.
2026-04-10 22:40:29 +08:00
Jason af679cda25 fix: map adaptive thinking to xhigh reasoning_effort instead of high
When thinking.type is "adaptive" (Claude's maximum thinking mode) and
output_config.effort is absent, resolve_reasoning_effort() incorrectly
mapped it to "high" instead of "xhigh" in OpenAI format conversions.
2026-04-10 22:40:29 +08:00
Jason a83bd90fa9 feat: replace x-code icon with high-res xcode icon via URL import
Replace the old low-res x-code inline SVG (7.6KB) with a new high-res
xcode.svg (286KB) loaded via Vite URL import. Update all three provider
preset files to reference the new icon name.
2026-04-10 22:40:29 +08:00
Jason 794795cad4 feat: support URL-based icons for large SVGs and raster images
Add dual rendering mode to the icon system: small optimized SVGs
continue to be inlined via dangerouslySetInnerHTML, while large SVGs
and raster images (png/jpg/webp/etc) use Vite URL imports rendered
as <img> tags. Added dds.svg (1.4MB) as the first URL-based icon.

Updated generate-icon-index.js to support multi-format icons with
a manual URL_ICONS control list. Updated ProviderIcon to handle
both inline SVG and URL-based rendering paths.
2026-04-10 22:40:29 +08:00
Jason eff85dc66d feat: add ddshub provider preset with partner promotion
Add ddshub as a third-party partner provider for Claude, including
SVG icon and i18n promotion text in zh/en/ja locales.
2026-04-10 22:40:29 +08:00
Dex Miller 3aef5217cb Restore first-class OMO Slim council support (#1981) (#1982)
cc-switch could already persist arbitrary OMO Slim agent keys and top-level fields, but the built-in metadata and UI copy still reflected the pre-council agent set. This made the upstream council feature look unsupported and pushed users toward manual JSON-only setup.

Promote council to a built-in OMO Slim agent, add copy that points top-level plugin settings at Other Fields, and lock the behavior with regression tests.

Constraint: oh-my-opencode-slim exposes council through both agents.council and top-level council config
Rejected: Add a dedicated council editor UI now | too much surface area for issue #1981
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep OMO Slim built-in agent metadata aligned with upstream agent additions before shipping UI support
Tested: pnpm exec vitest run tests/utils/omoConfig.test.ts tests/components/OmoFormFields.mergeCustomModelsIntoStore.test.ts
Tested: pnpm typecheck
Not-tested: End-to-end validation against a live oh-my-opencode-slim installation
Related: farion1231/cc-switch#1981
2026-04-10 22:36:32 +08:00
Dex Miller e4b58c7206 Let Kaku users launch sessions from their chosen terminal (#1954) (#1983)
Kaku is a WezTerm-derived macOS terminal, so reusing the existing WezTerm-compatible launch path keeps the change small while making it selectable in settings and session resume flows.

Constraint: Kaku support should stay macOS-only and avoid introducing a separate launcher model
Rejected: Treat Kaku as a silent WezTerm fallback | users could not explicitly choose it in settings
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep Kaku on the shared WezTerm-compatible launch path unless upstream drops the start-compatible CLI
Tested: pnpm typecheck; pnpm format:check; cargo check --manifest-path src-tauri/Cargo.toml; cargo fmt --manifest-path src-tauri/Cargo.toml --check; cargo test --manifest-path src-tauri/Cargo.toml --lib session_manager::terminal::tests
Not-tested: End-to-end launch against a locally installed Kaku.app
Related: #1954
2026-04-10 22:35:16 +08:00
Dex Miller 8c32610a7d Align Thinking fallback with main-model-only Claude mappings (#1984)
The Claude provider form reopened with an empty Thinking model after users saved only a main model. This updates model-state hydration to mirror the existing Haiku-style fallback semantics: read ANTHROPIC_REASONING_MODEL when present, otherwise display ANTHROPIC_MODEL, without writing a synthetic reasoning field back into config.

Constraint: Existing Haiku, Sonnet, and Opus selectors already rely on read-time fallback behavior
Rejected: Persist ANTHROPIC_REASONING_MODEL from ANTHROPIC_MODEL automatically | would diverge from Haiku behavior and silently rewrite saved config
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep Thinking fallback read-only unless all model-mapping fields are intentionally migrated to write-through semantics
Tested: pnpm typecheck
Tested: pnpm test:unit (1 unrelated pre-existing failure in tests/components/UnifiedSkillsPanel.test.tsx mock setup)
Not-tested: Manual add-provider reopen flow in the desktop UI
2026-04-10 22:34:18 +08:00
Dex Miller afdda27bd5 Restore auth tab localization in settings (#1985)
The settings page already routes the auth tab label through the shared i18n key, but the locale bundles never defined that key. Adding the missing entries fixes the label with the same simple pattern used by the other tabs.

Constraint: Keep the fix aligned with the existing settings-tab i18n flow
Rejected: Add component-level bilingual rendering | unnecessary for a missing translation key
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: When adding settings tabs, define locale keys in every bundled language before relying on fallback text
Tested: pnpm format:check; pnpm typecheck
Not-tested: Manual verification in the desktop UI
2026-04-10 22:24:25 +08:00
Max 7f1963ab49 feat(provider): add TheRouter presets for Claude, Codex, and Gemini (#1891)
* feat(provider): add TheRouter presets for Claude and Codex

* feat(provider): add TheRouter Gemini preset

---------

Co-authored-by: max <me19@qq.com>
2026-04-10 21:48:14 +08:00
Max 68df60bd4a feat(provider): add TheRouter presets for OpenCode and OpenClaw (#1892)
Co-authored-by: max <me19@qq.com>
2026-04-10 21:47:18 +08:00
Jason 489c7c75ea style: apply cargo fmt to schema migration code 2026-04-10 11:23:08 +08:00
Jason b85e449949 fix: guard migrations against missing tables and fix highlighted text assertion
- Make migrate_v6_to_v7 check skills table existence before ALTER
- Make migrate_v7_to_v8 check model_pricing table existence before UPDATE
- Fix SessionManagerPage test: use getByRole heading instead of getAllByText
  which breaks when highlightText splits text across <mark> elements
2026-04-10 11:20:47 +08:00
Jason c4458cf280 fix: update tests for InstalledSkill new fields and missing hook mocks
- Add content_hash and updated_at fields to 4 InstalledSkill literals in skill_sync.rs
- Add useCheckSkillUpdates and useUpdateSkill to UnifiedSkillsPanel test mock
- Suppress unused import warning in auto_launch.rs test module
2026-04-10 11:08:09 +08:00
Jason cc1530f997 docs: add working directory feature implementation plan
Design document for per-directory state switching (providers, MCP,
skills, prompts). Not yet implemented - saved for future reference.
2026-04-10 08:33:13 +08:00
Jason f9fb9085ac feat(session-manager): highlight search keywords in session titles and messages 2026-04-10 08:30:37 +08:00
Jason 308314baac fix(session-manager): improve session search accuracy and Chinese support
- Pre-filter sessions by provider before indexing to prevent result
  truncation when FlexSearch limit cuts across providers
- Switch tokenizer from "forward" to "full" for Chinese substring matching
- Preserve FlexSearch relevance ranking when search query is present
2026-04-10 00:14:50 +08:00
Jason 5ac6fb5315 feat(session-manager): extract meaningful titles for Claude sessions
Instead of showing directory basenames for all Claude sessions, extract
titles from JSONL content with a priority chain:
1. custom-title metadata (set via /rename in Claude Code)
2. First real user message (skipping /clear, /compact caveats)
3. Directory basename (fallback)
2026-04-09 23:18:06 +08:00
Jason a5a5207f74 style: fix prettier formatting in ProviderCard and ProviderForm 2026-04-09 21:13:32 +08:00
Jason accdacf94d docs: add DDS as sponsor in all README languages 2026-04-09 17:40:46 +08:00
Jason 97152c0f21 docs: add LionCC as sponsor in all README languages 2026-04-09 17:25:15 +08:00
Jason 129b1b45b0 docs: add Shengsuanyun as sponsor in all README languages 2026-04-09 17:13:19 +08:00
Jason fa4297f4d3 feat(common-config): show first-run notice dialog when editing providers
Display a one-time informational dialog explaining the Common Config
Snippet feature when users first open the add/edit provider form.
Uses a derived isOpen state from settings to avoid race conditions.
Adds commonConfigConfirmed flag to both TS and Rust settings types.
2026-04-09 16:49:14 +08:00
Jason ecb1fed5db feat(common-config): add guide info and empty state to common config editor
Add an informational alert block at the top of the common config snippet
editor modal (Claude/Codex/Gemini) explaining what the feature is, why
it exists, and how to use it. Also add an empty state prompt when no
snippet has been extracted yet, guiding users to click "Extract from
Editor". Includes i18n support for zh/en/ja.
2026-04-09 16:49:14 +08:00
Jason 521571c4ca fix(usage): only show CLI subscription quota for active provider
CLI-credential-based subscriptions (Claude/Codex/Gemini) read from a
single global credential file, so the quota always reflects the last
CLI login rather than a specific provider. Showing it on non-current
cards is misleading when multiple official subscriptions exist.

Apply the same isCurrent + autoQuery pattern already used by Copilot
and Codex OAuth: only query and render the quota footer when the
provider is the currently active one.
2026-04-09 16:49:14 +08:00
Jason bafe9e820d fix(notifications): remove duplicate toast when switching to proxy providers
When switching to Copilot/ChatGPT/OpenAI-format providers with the proxy
not running, two toasts appeared: a "proxy required" warning followed by
a "switch success" toast. Unify the post-switch toast logic so that all
provider types show a single success toast, and skip it entirely when
a proxy-required warning was already shown.
2026-04-09 16:49:14 +08:00
Jason 8669879ad0 feat(welcome): show first-run welcome dialog on fresh install
Introduce a one-time welcome dialog that explains CC Switch's workflow
to new users: how their existing config is preserved as a "default"
provider and how the bundled "Official" preset enables one-click revert.
Upgrade users are excluded by checking is_providers_empty() at startup
and never see the dialog.

Persistence follows the existing *_confirmed convention in AppSettings
(proxy/usage/stream_check/failover), stored in settings.json. The field
is only written when the user explicitly clicks the confirm button,
keeping its semantics strictly about user acknowledgement.

Also adds two reusable DAO helpers:
- Database::is_providers_empty for fresh-install detection, using
  EXISTS(SELECT 1) for a short-circuit query.
- Database::get_bool_flag accepting "true" | "1", with
  init_default_official_providers migrated to use it.

Dialog copy in zh/en/ja uses conditional phrasing so it stays
accurate whether or not existing live config was found.
2026-04-09 16:49:14 +08:00
Jason a058ebeafc docs(user-manual): update to v3.13.0 across en/zh/ja
Refresh the user manual to cover the v3.13.0 feature set so users can
discover and correctly use new functionality without cross-referencing
the release notes. All three language versions are updated
line-by-line symmetric.

Highlights:

- Lightweight Mode: tray-only running state added in 1.5-settings,
  with a comparison table against "Minimize to tray" and a new OAuth
  Auth Center (Beta) section
- Quota & Balance display restructured in 2.5-usage-query: split into
  auto-query (Claude/Codex/Gemini official, Copilot, Codex OAuth) vs
  manual-enable (Token Plan, third-party balances). Explains why
  manual enabling is required: the same API URL may expose both
  plan-quota and balance query modes
- Codex OAuth reverse proxy: full usage guide in 2.1-add with two
  entry points (Add Provider panel / OAuth Auth Center), Device Code
  login flow, token auto-refresh, multi-account management, quota
  display, common failures, and risk notice
- Full URL Endpoint Mode: new advanced option in 2.1-add
- Per-app tray submenus: 2.2-switch refactored to reflect the 5-app
  submenu structure and cross-link to Lightweight Mode
- Skills workflow: remove obsolete "automatic update not supported"
  section in 3.3-skills, add SHA-256 update detection, single/batch
  update, storage location switch, and skills.sh registry search
- Directory picker for Claude terminal resume in 3.4-sessions
- Usage stats in 4.4-usage: document the new CLI session log source
  (no proxy required) and per-app filtering for Claude/Codex/Gemini;
  note CNY->USD pricing corrections and MiniMax quota fixes
- Stream Check coverage extended to OpenCode/OpenClaw in 4.5-model-test
- New FAQs in 5.2-questions: quota visibility (auto vs manual),
  Codex OAuth risks and login flow, deep link wake in Lightweight Mode
- v3.13.0 highlights navigation block added to top-level README and
  each per-language README; version bumped to v3.13.0 / 2026-04-08
2026-04-09 16:49:14 +08:00
Jason 24bf3e810b feat(providers): auto-import OpenCode/OpenClaw live providers on startup
Drops the friction of clicking the manual "Import current config" button
for OpenCode and OpenClaw — they now match the auto-import behavior the
previous commit added for Claude/Codex/Gemini.

- New "1.6." startup block in lib.rs runs both
  import_opencode_providers_from_live and import_openclaw_providers_from_live
  on every launch. The functions are id-keyed and idempotent, so re-running
  just picks up new providers added externally to the live JSON files.
- Both functions now use a new Database::get_provider_ids() helper
  (HashSet<String> from a single SELECT id-only query) instead of
  get_all_providers(), avoiding the N+1 endpoint sub-queries that would
  otherwise hit the startup hot path on every launch.
2026-04-09 16:49:14 +08:00
Jason 5dbea70eb1 feat(providers): seed an official preset on startup for Claude/Codex/Gemini
New and existing users now see a built-in "Claude Official" / "OpenAI
Official" / "Google Official" entry in their provider list, so switching
back to the official endpoint is one click away instead of buried in the
README.

- New providers_seed.rs holds the three seeds (id, name, settings_config,
  icon) keyed by AppType, with a single is_official_seed_id() helper that
  scans OFFICIAL_SEEDS so the id list has one source of truth.
- Database::init_default_official_providers() runs once per database
  (gated by an official_providers_seeded setting flag), appends each seed
  to the end of the sort order, and never touches is_current.
- Startup also auto-imports the live config (settings.json / auth.json /
  .env) as a "default" provider before seeding, so users with an existing
  manual config don't lose it when they click the official preset.
- Database::has_non_official_seed_provider() replaces the get_all_providers
  call in import_default_config's gating check with an id-only scan,
  dropping the N+1 endpoint sub-queries from every startup.
2026-04-09 16:49:14 +08:00
Jason df5cb6d771 fix(usage): only auto-poll Copilot/ChatGPT quota for current provider
CopilotQuotaFooter and CodexOauthQuotaFooter called their hooks with a
hardcoded `enabled: true` plus an unconditional 5-minute refetch and
refetchOnWindowFocus, so non-current reverse-proxy cards kept polling
in violation of the project's "only the active provider auto-queries
on cooldown" rule. With multiple Copilot or ChatGPT accounts bound to
different cards, every card kept hitting its own usage endpoint.

Adopt the same pattern as useUsageQuery: keep `enabled` independent of
isCurrent so first-fetch and manual refresh still work, but gate
refetchInterval / refetchIntervalInBackground / refetchOnWindowFocus on
a new `autoQuery` option, and thread `isCurrent` from ProviderCard
through the footers into the hooks.
2026-04-09 16:49:14 +08:00
Jason 62fc1d9151 docs(release-notes): add v3.13.0 release notes (en/zh/ja)
Draft trilingual release notes for the upcoming v3.13.0 feature release
covering lightweight mode, quota and balance visibility, provider model
auto-fetch, Codex OAuth reverse proxy, tray per-app submenus, the
Hyper-based proxy forwarding stack, Skills discovery and batch updates,
session workflow upgrades, OpenCode/OpenClaw Stream Check coverage, the
full URL endpoint mode, and the Copilot interaction optimizer, plus the
accompanying Copilot auth, UTF-8 streaming boundary, system prompt
normalization, WebDAV password, and Linux startup fixes. Contributor
attribution follows industry convention using ASCII punctuation inside
PR references across all three locales, and the Codex OAuth reverse
proxy carries its own risk notice alongside a backward link to the
v3.12.3 Copilot risk notice.
2026-04-09 16:49:14 +08:00
Jason 87b1792eba docs(changelog): cover UTF-8 boundary and system prompt fixes
Document two additional Fixed entries for the Unreleased section after
rebasing onto the latest origin/main: the SSE streaming UTF-8 chunk
boundary fix that prevents U+FFFD replacement characters in multi-byte
output via the Copilot reverse proxy, and the OpenAI-compatible chat
transform fix that normalizes fragmented Claude system prompts into a
single leading system message for strict backends like Nvidia and
Qwen-style providers.
2026-04-09 16:49:14 +08:00
Jason 16ed738048 docs(changelog): add Unreleased section for upcoming release
Catalog all user-visible changes since v3.12.3: lightweight mode,
provider model auto-fetch, quota and balance visibility, skills
discovery and batch updates, session workflow upgrades, Codex OAuth
reverse proxy, OpenCode/OpenClaw stream check coverage, tray submenus,
Hyper-based proxy stack, provider key lifecycle, OAuth Auth Center UI
polish, and the accompanying Copilot auth, WebDAV, usage pricing,
Linux UI, and Skills i18n fixes.
2026-04-09 16:49:14 +08:00
Jason 50cbb3be12 refactor(stream-check): rename helper and drop phase markers
Post-merge cleanup from a simplify review pass on the phase 1-4
OpenCode/OpenClaw changes.

- Rename check_once_opencode_like → check_once_without_adapter. The
  new name directly expresses the intent (bypass get_adapter) instead
  of suggesting the function is somehow "like" OpenCode.
- Drop two "Phase 4 会美化错误消息" phase-history markers from
  docstrings; git history is the right place for them.
- Document in resolve_opencode_base_url why its default endpoints
  cannot be merged with ProviderType::default_endpoint(): the former
  encode AI SDK package defaults (e.g. @ai-sdk/openai ships with the
  /v1 suffix) while the latter encode proxy upstream hosts. They
  happen to overlap but are two independent truth sources.
2026-04-09 16:49:14 +08:00
Jason 5a61f01cfc feat(stream-check): handle edge cases for OpenCode/OpenClaw
Phase 4: polish the four remaining edge cases uncovered by Phase 1-3.

Custom headers passthrough
- check_claude_stream and check_gemini_stream now accept an optional
  extra_headers map which is appended after all built-in headers so it
  can override defaults (e.g. a custom User-Agent).
- OpenClaw reads from settings_config.headers.
- OpenCode reads from settings_config.options.headers.
- All pre-existing Claude/Codex/Gemini call sites pass None.

OpenClaw custom auth header (Longcat-style)
- When settings_config.authHeader is true, the provider expects a
  custom auth header whose name is only known to the OpenClaw gateway
  itself. Return a dedicated openclaw_auth_header_not_supported error
  so the user sees a meaningful explanation instead of a 401.

Bedrock error polish
- The bedrock-converse-stream (OpenClaw) and @ai-sdk/amazon-bedrock
  (OpenCode) branches now explain why (SigV4 signing) and point to
  the official consoles as an alternative test path.

OpenCode baseURL fallback
- resolve_opencode_base_url: when options.baseURL is empty and the
  npm package has a canonical default endpoint (@ai-sdk/openai,
  @ai-sdk/anthropic, @ai-sdk/google), fall back to that endpoint.
  @ai-sdk/openai-compatible still requires an explicit baseURL
  because its whole purpose is to point at a custom OpenAI clone.

Tests
- 8 new unit tests covering authHeader detection, baseURL resolution
  (explicit / fallback / error), and header map extraction on both
  apps. Total stream_check tests: 18 → 26.
2026-04-09 16:49:14 +08:00
Jason c02b8c58cb feat(stream-check): support OpenCode via npm package mapping
Phase 3: implement stream check for OpenCode providers by mapping the
`settings_config.npm` (AI SDK package name) to the corresponding API
protocol and delegating to the existing stream checkers.

Package mapping:
- @ai-sdk/openai-compatible → openai_chat
- @ai-sdk/openai            → openai_responses
- @ai-sdk/anthropic         → anthropic (ClaudeAuth strategy)
- @ai-sdk/google            → gemini (Google strategy)
- @ai-sdk/amazon-bedrock    → not supported (phase 4 message polish)

Note: OpenCode nests baseURL/apiKey under `settings_config.options`
(different from OpenClaw's root-level fields) and uses `baseURL` with
a capital L. Three new extractors (base_url / api_key / npm) encode
these shape differences so check_opencode_stream stays symmetric with
check_openclaw_stream.

Frontend: drop the remaining `appId !== "opencode"` filter in
ProviderList.tsx — both apps can now test providers.
2026-04-09 16:49:14 +08:00
Jason 7b3cfc683a feat(stream-check): support remaining 3 OpenClaw protocols
Phase 2: extend check_openclaw_stream to cover the full non-Bedrock
protocol set declared by openclawApiProtocols.

- openai-responses   → check_claude_stream(api_format="openai_responses")
- anthropic-messages → check_claude_stream(api_format="anthropic"),
  using AuthStrategy::ClaudeAuth (Bearer-only) so Claude relay
  services that reject a simultaneous x-api-key still work. Official
  Anthropic also accepts pure Bearer on /v1/messages.
- google-generative-ai → check_gemini_stream with AuthStrategy::Google.

bedrock-converse-stream still errors out but with a dedicated
openclaw_bedrock_not_supported key; its user-facing message will be
polished in phase 4.

Each protocol now builds its own AuthInfo inside the match arm because
the auth strategy is protocol-specific.
2026-04-09 16:49:13 +08:00
Jason 516fcdf6bf feat(stream-check): support OpenClaw openai-completions protocol
Phase 1 of extending stream health check to OpenCode/OpenClaw apps.

- Add early-dispatch path for OpenCode/OpenClaw in check_once so they
  bypass the adapter layer (which only knows Claude/Codex/Gemini
  settings_config shapes).
- Introduce check_openclaw_stream dispatcher that reads the `api` field
  from settings_config and routes to the existing check_claude_stream
  with api_format="openai_chat" for "openai-completions". Other
  protocols return localized errors to be lit up in phases 2 and 4.
- Extract build_stream_check_result helper to avoid duplicating the
  StreamCheckResult construction logic between the two code paths.
- Unblock the test button for OpenClaw providers in ProviderList.tsx.

OpenCode still returns the "not yet supported" error; it will be
enabled in phase 3.
2026-04-09 16:49:13 +08:00
Jason 34c6696baa fix(providers): disable test/usage buttons for Copilot and Codex OAuth cards
These OAuth providers ship with non-empty ANTHROPIC_BASE_URL, so the
isOfficialProvider() heuristic (which checks for a missing base URL)
returned false and left the health-check and usage-config buttons
enabled — inconsistent with other official OAuth cards. Extend the
button disabling logic at the call site with isCopilot / isCodexOauth,
matching the pattern already used for the quota footer branch above.
2026-04-09 16:49:13 +08:00
Jason 641c2fc2c7 chore(presets): bump Codex OAuth preset to GPT-5.4 family
Update the "Codex (ChatGPT Plus/Pro)" entry in Claude Code presets to
the new GPT-5.4 naming, which drops the legacy `-codex` suffix. Map the
Haiku tier to `gpt-5.4-mini` for lower-cost lightweight calls while
keeping Sonnet/Opus on the standard `gpt-5.4`.
2026-04-09 16:49:13 +08:00
Jason 64c068415e fix(linux): repair unresponsive UI on startup and full-screen panels
Linux users reported the window UI (including native title bar buttons)
couldn't receive clicks until manually maximizing and restoring the
window. Root causes: (1) Tauri webview did not acquire focus on startup
so first clicks were consumed by X11/Wayland click-to-activate
(Tauri #10746, wry #637); (2) GTK surface input region failed to
renegotiate on the visible:false + show() path under some
WebKitGTK/compositor combinations.

- Add linux_fix::nudge_main_window helper that performs set_focus plus
  a ±1px no-op resize after window show, with a 500ms reconciliation
  readback to compensate for dropped resize requests on slow
  compositors.
- Wire the helper into every window re-show path: normal startup,
  deeplink, single_instance, tray show_main, and lightweight exit.
- Set WEBKIT_DISABLE_COMPOSITING_MODE=1 at startup to avoid resize
  crashes and Wayland surface negotiation issues.
- Remove data-tauri-drag-region on Linux from App.tsx header and the
  shared FullScreenPanel (used by all provider/MCP/workspace forms)
  to avoid Tauri #13440 in Wayland sessions. Extract drag-region
  constants to src/lib/platform.ts for reuse.

All Rust changes are gated by #[cfg(target_os = "linux")]; frontend
changes preserve macOS/Windows behavior via runtime isLinux() checks.
Known limitation: tiling Wayland compositors ignore set_size, so
GDK_BACKEND=x11 remains the user-side workaround.
2026-04-09 16:49:13 +08:00
Jason 3a16462261 i18n(zh): unify Skills terminology in settings labels
Use "Skills" consistently in skillStorage title/description and
skillSync title to match the upstream Agent Skills wording and the
existing English label style used elsewhere on the settings page.
2026-04-09 16:49:13 +08:00
Jason 5288238694 refactor: tighten OAuth Auth Center copy, layout, and icon
- Trim Auth Center section descriptions to focus on user intent
- Remove duplicate outer heading on the auth settings tab
- Swap Sparkles glyph for CodexIcon on the ChatGPT card
- Generalize codexOauth.authStatus to a neutral "Auth status"
- Register settings.authCenter.* keys across zh/en/ja locales
2026-04-09 16:49:13 +08:00
Jason d164191bd1 feat: display subscription quota for Codex OAuth provider cards
Codex OAuth (ChatGPT Plus/Pro) providers previously fell through to the
default UsageFooter branch and showed no quota at all, while Copilot and
official Codex providers already had a wham/usage-backed quota footer.

This wires up the same five-hour / seven-day tier badges for codex_oauth
provider cards by reusing the existing query_codex_quota function and
SubscriptionQuotaFooter rendering, parameterized to keep both the CLI
credential path ("codex") and the cc-switch managed OAuth path
("codex_oauth") working from a single source of truth.

- Parameterize services::subscription::query_codex_quota with tool_label
  and expired_message; promote SubscriptionQuota constructors to
  pub(crate). The CLI path keeps its existing "codex" label and the
  "re-login with Codex CLI" message; the new path passes "codex_oauth"
  and a cc-switch-specific re-login hint.
- Add a new get_codex_oauth_quota Tauri command in commands/codex_oauth.rs
  that resolves the ChatGPT account (explicit binding > default account
  > not_found), pulls a valid access_token from CodexOAuthManager
  (auto-refresh handled), and delegates to query_codex_quota.
- Extract SubscriptionQuotaFooter's render body into a pure
  SubscriptionQuotaView component (props: quota / loading / refetch /
  appIdForExpiredHint / inline). The existing SubscriptionQuotaFooter
  becomes a thin wrapper with identical props and behavior, so
  CopilotQuotaFooter and the official Claude/Codex/Gemini paths are
  untouched. This avoids duplicating ~280 lines of five-state rendering.
- Add CodexOauthQuotaFooter, a 38-line wrapper that calls the new
  useCodexOauthQuota hook and forwards to SubscriptionQuotaView.
- ProviderCard inserts an isCodexOauth branch between isCopilot and
  isOfficial, keyed off PROVIDER_TYPES.CODEX_OAUTH (newly added to
  config/constants.ts to centralize the previously scattered string).
- Frontend hook caches per (codex_oauth, accountId) so multiple cards
  bound to the same ChatGPT account share one fetch via react-query
  dedup; cards bound to different accounts get independent fetches.
- No new i18n keys: existing subscription.fiveHour / sevenDay / expired /
  refresh / queryFailed / expiredHint are reused.
2026-04-09 16:49:13 +08:00
Jason 6a34253934 feat: add Codex OAuth (ChatGPT Plus/Pro) reverse proxy support
Adds a new managed OAuth provider that lets Claude Code route requests
through a user's ChatGPT Plus/Pro subscription via the chatgpt.com
backend-api/codex endpoint.

- CodexOAuthManager: OpenAI Device Code flow with multi-account support,
  JWT-based account identification, and automatic access_token refresh.
- Reuses the generic managed-auth command surface (auth_start_login,
  auth_poll_for_account, etc.) via provider dispatch in commands/auth.rs.
- ClaudeAdapter detects codex_oauth providers, forces the base URL to
  the ChatGPT backend, pins api_format to openai_responses, and emits
  Authorization + originator headers; the forwarder injects the dynamic
  access_token and ChatGPT-Account-Id per request.
- transform_responses gains an is_codex_oauth path that aligns the body
  with OpenAI's codex-rs ResponsesApiRequest contract: sets store:false,
  appends reasoning.encrypted_content to include, strips max_output_tokens
  / temperature / top_p, injects default instructions/tools/parallel_tool_calls,
  and forces stream:true. Covered by 9 new unit tests plus regression
  guards for the non-Codex path.
- Stream check reuses the same transform flag so detection matches the
  production request shape.
- Frontend adds CodexOAuthSection + useCodexOauth hook, integrates it
  into ClaudeFormFields / ProviderForm / AuthCenterPanel, ships a new
  "Codex (ChatGPT Plus/Pro)" preset, and adds zh/en/ja i18n strings.
2026-04-09 16:49:13 +08:00
Jason 697d0dd6e1 fix: resolve rustfmt formatting and clippy warnings
- Apply cargo fmt across schema.rs, session_usage*.rs, skill.rs, usage_stats.rs
- Fix clippy::for_kv_map: use messages.values() instead of (_, msg) pattern
- Suppress clippy::only_used_in_recursion for intentional recursive base path
- Fix prettier formatting in UsageScriptModal.tsx
2026-04-09 16:49:13 +08:00
Jason d33d63e4df feat: display Copilot premium interactions quota on provider card
Copilot usage query API was implemented but never surfaced on the main
provider list. Add CopilotQuotaFooter component that auto-detects
github_copilot providers and displays premium interaction utilization
inline, reusing the existing TierBadge UI from SubscriptionQuotaFooter.
2026-04-09 16:49:13 +08:00
Jason eb41e1052c fix: resolve session-based usage showing as unknown provider
Session logs use placeholder provider_ids (_session, _codex_session,
_gemini_session) that don't exist in the providers table, causing LEFT
JOIN to return NULL and display "Unknown". Add COALESCE fallback in all
4 usage queries to show meaningful names like "Claude (Session)".
2026-04-09 16:49:13 +08:00
Jason 687ffc237d feat: add per-app usage filtering (Claude/Codex/Gemini)
Add dashboard-level app type filter to usage statistics, replacing the
DataSourceBar with a more useful segmented control. All components
(summary cards, trend chart, provider stats, model stats, request logs)
now respond to the selected app filter.

Backend: add optional app_type parameter to get_usage_summary,
get_daily_trends, get_provider_stats, and get_model_stats queries.
Frontend: new AppTypeFilter type, updated query keys with appType
dimension for proper cache separation, and RequestLogTable local
filter auto-locks when dashboard filter is active.
2026-04-09 16:49:13 +08:00
Jason c0bcd19d44 fix: correct Gemini session sync accuracy issues
- Use UPSERT with WHERE guard instead of INSERT OR IGNORE, so updated
  token values on existing messages are properly synced without
  unnecessary rewrites of unchanged rows
- Include cached tokens in the skip-zero filter to stop silently
  discarding pure cache-hit records
- Restrict file collection to session-*.json to match documented scope
  and prevent ingesting non-session JSON files
2026-04-09 16:49:13 +08:00
Jason f5d7064d57 feat: add Gemini CLI session log usage tracking
Parse ~/.gemini/tmp/*/chats/session-*.json for precise per-message
token data (input/output/cached/thoughts). Integrates with existing
background sync and manual sync button alongside Claude and Codex.
2026-04-09 16:49:13 +08:00
Jason 8ad1bb7924 feat: add Codex model name normalization for consistent pricing lookup
Normalize model names from JSONL session logs before storage and pricing
lookup: lowercase, strip provider prefix (openai/), strip date suffixes
(-YYYY-MM-DD, -YYYYMMDD). Also clamp cached tokens to not exceed input.
2026-04-09 16:49:13 +08:00
Jason 2ea6a307fc feat: replace Codex estimated usage with precise JSONL session log parsing
Replace the 70/30 input/output token estimation from state_5.sqlite
with precise parsing of Codex CLI JSONL session logs (~/.codex/sessions/).

- Parse event_msg (token_count), turn_context, and session_meta events
- Compute exact input/output/cached token deltas from cumulative totals
- Reuse session_log_sync table for incremental file scanning
- Pre-filter lines with string contains() before JSON deserialization
- Add codex_session data source to DataSourceBar with i18n (zh/en/ja)
2026-04-09 16:49:13 +08:00
Jason 46051317da fix: correct model pricing CNY→USD and add missing models
- Fix 13 Chinese model prices that were stored as CNY values in USD
  fields (DeepSeek, Kimi, MiniMax, GLM, Doubao, Mimo)
- Add 12 new models: GPT-5.4/mini/nano, o3, o4-mini, GPT-4.1/mini/nano,
  Gemini 3.1 Pro/Flash Lite, Gemini 2.5 Flash Lite, Gemini 2.0 Flash,
  DeepSeek Chat/Reasoner, Kimi K2.5
- Merge pricing migration into existing v7→v8 to avoid extra version bump
2026-04-09 16:49:13 +08:00
Jason 154342ca00 feat: add session log usage tracking without proxy
Parse Claude Code JSONL session files (~/.claude/projects/) and Codex
SQLite database (~/.codex/state_5.sqlite) to track API usage without
requiring proxy interception. This enables usage statistics for users
who don't use the proxy feature.

Key changes:
- Add session_usage.rs: incremental JSONL parser with message.id dedup
- Add session_usage_codex.rs: import thread-level token data from Codex
- Add data_source column to proxy_request_logs (proxy/session_log/codex_db)
- Add session_log_sync table for tracking parse offsets
- Background sync every 60s + manual sync via DataSourceBar UI
- Schema migration v7→v8
- i18n support for zh/en/ja
2026-04-09 16:49:13 +08:00
Jason 2d581bce91 fix: hide empty description and fix broken skill link for skills.sh results
- Hide "暂无描述" text when skill has no description (skills.sh API
  doesn't return descriptions), show empty spacer instead
- Change skills.sh result link from guessed subdirectory path to repo
  root URL, since skillId doesn't reflect the actual nested path
2026-04-09 16:49:13 +08:00
Jason d51e774b20 feat: integrate skills.sh search for discovering skills from public registry
Add skills.sh API integration allowing users to search and install from
a catalog of 91K+ agent skills directly within CC Switch. The search
results are converted to DiscoverableSkill objects and reuse the existing
install pipeline. Includes fallback directory search for repos where
skills are nested in subdirectories, and filters out non-GitHub sources.
2026-04-09 16:49:13 +08:00
Jason 33f5d56afd fix: move skill settings above window settings in general tab 2026-04-09 16:49:13 +08:00
Jason 8cfce8abfc feat: add skill storage location toggle between CC Switch and ~/.agents/skills
Allow users to choose between storing skills in CC Switch's managed
directory (~/.cc-switch/skills/) or the Agent Skills open standard
directory (~/.agents/skills/). Includes migration logic that safely
moves files before updating settings, with confirmation dialog for
non-empty installations.
2026-04-09 16:49:13 +08:00
Jason 6d220b2528 fix: animate "Update All" button sliding in from the left of "Check Updates"
Use max-width + opacity CSS transition so the button smoothly expands
into view instead of popping in abruptly.
2026-04-09 16:49:13 +08:00
Jason b7e99014c9 feat: add "Update All" button for batch skill updates
Show an "Update All (N)" button next to "Check Updates" when updates
are available. Sequentially updates each skill and reports results.
2026-04-09 16:49:13 +08:00
Jason e3179ad9e4 feat: add skill update detection via SHA-256 content hashing
- Add content_hash and updated_at fields to skills table (DB migration v6→v7)
- Compute directory content hash on install/import/restore for version tracking
- Add check_updates command: downloads repos, compares hashes, returns update list
- Add update_skill command: backs up old files, re-downloads and replaces SSOT
- Backfill content_hash for existing skills on first update check
- Add "Check Updates" button and per-skill update badge/button in UnifiedSkillsPanel
- Add i18n keys for zh/en/ja
2026-04-09 16:49:13 +08:00
Jason 46488ecd93 fix: set default auto-query interval to 5min and fix number input clearing
- Change default autoQueryInterval from 0 (disabled) to 5 minutes for
  new usage scripts (Token Plan, Balance, and general templates)
- Fix controlled number inputs (timeout & interval) that couldn't be
  cleared: defer validation to onBlur so users can delete and retype
2026-04-09 16:49:13 +08:00
Jason 9192b6f988 fix: align usage display across provider cards by always rendering action buttons
Test and ConfigureUsage buttons are now always rendered instead of
conditionally, with a disabled style for providers that don't support
them (e.g. official subscriptions). This ensures consistent button
container width so the usage display aligns uniformly across all cards.
2026-04-09 16:49:13 +08:00
Jason f1fb3351c1 feat: add official balance query for DeepSeek, StepFun, SiliconFlow, OpenRouter, Novita AI
Add a new "Official" (官方) template type in the usage query panel that
queries account balance via each provider's native API endpoint.
Follows the same zero-script pattern as Token Plan — Rust handles the
HTTP call, frontend auto-detects the provider from base URL.

Supported providers and endpoints:
- DeepSeek: GET /user/balance
- StepFun: GET /v1/accounts
- SiliconFlow: GET /v1/user/info (cn + com)
- OpenRouter: GET /api/v1/credits
- Novita AI: GET /v3/user/balance
2026-04-09 16:49:13 +08:00
Satoru 24555275bb fix: add padding to toolbar container to prevent add button shadow clipping (#1951)
The orange add button's circular shadow appeared square because the
parent overflow-x-hidden container was clipping it at the edges.
2026-04-08 21:17:19 +08:00
Cod1ng dc4524e960 fix: handle UTF-8 multi-byte characters split across stream chunk boundaries (#1923)
* fix: handle UTF-8 multi-byte characters split across stream chunk boundaries

Replace String::from_utf8_lossy with append_utf8_safe in all four SSE
streaming paths. When a multi-byte UTF-8 character (e.g. Chinese, emoji)
is split across TCP chunk boundaries, from_utf8_lossy silently replaces
the incomplete halves with U+FFFD (�). This caused intermittent garbled
output in Claude Code when using the Copilot reverse proxy, because the
format conversion streams reconstruct SSE events from the corrupted buffer.

The new append_utf8_safe function preserves incomplete trailing bytes in
a remainder buffer and merges them with the next chunk before decoding,
ensuring characters are never split during UTF-8 conversion.

Fixes: intermittent U+FFFD replacement characters in Claude Code output
via Copilot proxy (not reproducible with direct Copilot connections like
opencode because they pass through raw bytes without format conversion).

* style: fix cargo fmt formatting in UTF-8 boundary tests

---------

Co-authored-by: Cod1ng <codingts@gmail.com>
Co-authored-by: encodets <encodets@gmail.com>
2026-04-08 10:02:35 +08:00
Dex Miller 34f16886a2 Normalize fragmented system prompts for strict chat backends (#1942)
Some OpenAI-compatible chat providers reject requests when Claude-side\nsystem fragments arrive as multiple system messages. Normalize the\nconverted OpenAI chat payload so system content becomes a single\nleading system message while leaving the rest of the message stream\nunchanged.\n\nConstraint: Nvidia/Qwen-style chat completions require a single leading system prompt\nRejected: Reorder system messages only | still leaves fragmented system prompts for strict backends\nConfidence: high\nScope-risk: narrow\nReversibility: clean\nDirective: Keep OpenAI chat system prompts normalized unless a provider explicitly requires fragmented system messages\nTested: cargo test proxy::providers::transform --manifest-path src-tauri/Cargo.toml\nNot-tested: Full end-to-end proxy capture against Nvidia upstream in this session\nRelated: #1881
2026-04-08 09:41:20 +08:00
Jason 602c5717b2 fix: gate parse_gemini_keychain_json with cfg(target_os = "macos")
The function is only called from read_gemini_credentials_from_keychain
which is already macOS-only. Without the gate, non-macOS CI fails with
dead-code error due to -D warnings.
2026-04-05 16:04:20 +08:00
Jason 4685e5b597 fix: invert MiniMax usage_count to match 0%→100% convention
usage_count is remaining quota (starts at total, decreases to 0),
not used count. Invert calculation so all providers consistently
show 0% when fresh and 100% when exhausted.
2026-04-05 13:41:52 +08:00
Jason ca6a187745 fix: correct MiniMax quota calculation and improve Token Plan display
- Fix MiniMax usage_count being treated as remaining (was inverted)
- Add MiniMax weekly quota tier extraction
- Remove Zhipu TIME_LIMIT (tools usage), keep only TOKENS_LIMIT
- Improve Kimi parsing with extract_reset_time and parse_f64 helpers
- Reuse TierBadge for Token Plan inline rendering
- Clean up unused i18n keys and debug println
2026-04-05 13:35:54 +08:00
Jason bfdac2a22a feat: add Token Plan quota query for Kimi, Zhipu GLM, and MiniMax
Add a new "Token Plan" template type in the usage query panel that
natively queries quota/usage from Chinese coding plan providers
(Kimi For Coding, Zhipu GLM, MiniMax) without requiring custom scripts.

- Rust backend: new coding_plan service with provider-specific API
  queries (Kimi /v1/usages, Zhipu /api/monitor/usage/quota/limit,
  MiniMax /coding_plan/remains) normalized into UsageResult
- Frontend: Token Plan template in UsageScriptModal with auto-detection
  of provider based on ANTHROPIC_BASE_URL pattern matching
- Follows the same pattern as GitHub Copilot template (dedicated API
  path in queryProviderUsage, no JS script needed)
2026-04-05 11:39:29 +08:00
Jason 8d38f0ee4f fix: allow provider switch without proxy, show warning instead of blocking
Remove the hard block that prevented switching to providers requiring
proxy (OpenAI format, Copilot, full URL mode) when the proxy is not
running. Now the switch proceeds with a warning toast. Also deduplicate
the proxy hint info toast so it doesn't appear alongside the warning.
2026-04-05 09:39:51 +08:00
Jason 159279bf44 feat: restore Copilot preset and auth center tab in settings
Re-enable GitHub Copilot provider preset and the OAuth auth center tab
that were temporarily hidden due to abnormal consumption rates. The
Copilot optimizer introduced in the previous commit addresses the
underlying issue.
2026-04-05 08:34:16 +08:00
Jason 2513687184 feat: add Copilot optimizer to reduce premium interaction consumption
Implement request classification, tool result merging, compact detection,
deterministic request IDs, and warmup downgrade for Copilot proxy.

The root cause was x-initiator being hardcoded to "user", making Copilot
count every API request (including tool callbacks and agent continuations)
as a separate premium interaction. The optimizer dynamically classifies
requests as "user" or "agent" based on message content analysis.

Closes #1813
2026-04-05 08:34:10 +08:00
Jason bcc14bd07d fix: remove hover push animation on provider cards
Keep usage display fixed in place and show action buttons with
a simple opacity fade instead of sliding in and pushing content.
2026-04-04 22:53:20 +08:00
Jason b31bf43e15 fix: hide usage config and health check buttons for official providers
Official providers use built-in subscription quota display instead of
custom usage scripts, and stream check is not applicable. Hide both
action buttons when isOfficialProvider is true.
2026-04-04 22:53:20 +08:00
Jason 98230c3970 feat: add official subscription quota display for Gemini
- Read Gemini OAuth credentials from macOS Keychain (gemini-cli-oauth)
  or legacy file (~/.gemini/oauth_creds.json)
- Auto-refresh expired access tokens using refresh_token (Google OAuth
  tokens expire in ~1h, unlike Claude/Codex)
- Two-step API: loadCodeAssist for project ID, then retrieveUserQuota
  for per-model quota buckets
- Classify models into Pro/Flash/Flash Lite categories, show min
  remaining fraction as utilization percentage
- Extend isOfficialProvider() for Gemini (no API key + no base URL)
- Parameterize expiredHint i18n key with tool name for all three apps
2026-04-04 22:53:20 +08:00
Jason 0200fe79ae feat: add official subscription quota display for Codex
Read Codex OAuth credentials from ~/.codex/auth.json (with macOS
Keychain fallback) and query chatgpt.com/backend-api/wham/usage to
show rate limit utilization on official Codex provider cards. Reuses
the same tier naming (five_hour, seven_day) for frontend i18n compat.
2026-04-04 22:53:20 +08:00
Jason b30f3c27ad feat: display official subscription quota on Claude provider cards
Read Claude OAuth credentials from macOS Keychain (with file fallback)
and query the Anthropic usage API to show quota utilization inline on
official provider cards. Includes compact countdown timer for reset
windows and hides the rarely-used seven_day_sonnet tier in inline mode.
2026-04-04 22:53:20 +08:00
Jason d9c0e4c452 docs: update user manual to v3.12.3 with new features coverage (en/zh/ja)
Add documentation for features introduced since v3.12.0:

New docs:
- 3.4 Session Manager: browse, search, resume, delete sessions
- 3.5 Workspace & Daily Memory: OpenClaw workspace file editing

Updated docs:
- Add Lightweight Mode to interface overview and FAQ
- Add tray submenu structure (providers grouped by app)
- Add API Format selection (Anthropic/OpenAI Chat/OpenAI Responses)
- Add Auto-Fetch Models button documentation
- Add Claude Common Config quick toggles
- Add Codex 1M Context Window toggle
- Add Skill backup/restore lifecycle
- Expand Backup Management panel documentation
- Update WebDAV sync to v2 protocol with dual-layer versioning
- Add OpenCode/OpenClaw to quickstart activation table
- Update README version to v3.12.3

All changes synced across en, zh, and ja locales.
2026-04-04 22:53:20 +08:00
Jason fe525891d4 feat(tray): collapse providers into submenus to prevent menu overflow
Each app type (Claude/Codex/Gemini) now renders as a submenu instead
of flat items, keeping the top-level tray menu compact regardless of
provider count. The submenu label shows the current provider name
(e.g. "Claude · OpenRouter") for at-a-glance visibility.
2026-04-04 22:53:20 +08:00
Jason 84998aa217 feat: differentiate fetch models error messages by failure type
Distinguish between missing API key, missing endpoint, auth failure,
unsupported provider (404/405), and timeout errors instead of showing
a generic failure toast for all cases.
2026-04-04 22:53:20 +08:00
Jason f200feebe4 fix(i18n): move fetchModels keys from copilot to providerForm namespace 2026-04-04 22:53:20 +08:00
Jason 5017002938 feat: add auto-fetch models from provider's /v1/models endpoint
Add ability to fetch available models from third-party aggregation
providers (SiliconFlow, OpenRouter, etc.) via OpenAI-compatible
GET /v1/models endpoint. Users can click "Fetch Models" button in
the provider form, then select models from a dropdown on each
model input field.

- Backend: new model_fetch service + Tauri command (Rust)
- Frontend: ModelInputWithFetch shared component
- Integrated into all 5 app forms (Claude/Codex/Gemini/OpenCode/OpenClaw)
- i18n support for zh/en/ja
2026-04-04 22:53:20 +08:00
Zhou Mengze de49f6fbbe fix(copilot): 修复 GitHub Copilot 认证和代理问题 (#1854)
* fix(copilot): 修复 GitHub Copilot 400 认证错误

问题:使用 GitHub Copilot provider 时报错 400 bad request

根因:与 copilot-api 项目对比发现多处差异

修复内容:
- 更新版本号 0.26.7 到 0.38.2
- 更新 API 版本 2025-04-01 到 2025-10-01
- 添加缺失的关键 headers
- 修正 openai-intent 值
- 添加动态 API endpoint 支持
- 同步更新 stream_check.rs headers

Closes #1777

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: flush stream after write_all in hyper_client proxy

Add explicit flush() calls after write_all() for TLS stream, plain TCP
stream, and CONNECT tunnel requests to ensure buffered data is sent
immediately, preventing connection hangs in Copilot auth header flow.

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

* 修复登录时的剪切板在mac与linux端可能没复制验证码

* fix: flush stream after write_all in hyper_client proxy

Add explicit flush() calls after write_all() for TLS stream, plain TCP
stream, and CONNECT tunnel requests to ensure buffered data is sent
immediately, preventing connection hangs in Copilot auth header flow.

* 修复登录时的剪切板在mac与linux端可能没复制验证码

* 1、修复不同类型的个人商业等不同类型的copilot账号问题
2、将验证码复制改为异步操作

* fix: address PR review comments for Copilot auth                                                      │
│                                                                                                                      │
│ - Fix clipboard blocking by using spawn_blocking for arboard ops                                                     │
│ - Implement dynamic endpoint routing for enterprise Copilot users                                                    │
│ - Add api_endpoints cache cleanup in remove_account() and clear_auth()                                               │
│ - Change API endpoint log level from info to debug                                                                   │
│ - Fix clear_auth() to continue cleanup even if file deletion fails                                                   │
│ - Add 9 unit tests for Copilot detection and api_endpoints cachin

* style: fix cargo fmt formatting

* Fix Copilot dynamic endpoint handling

* fix: restore clear_auth() memory-first cleanup order and fix cache leaks

- Restore clear_auth() to clean memory state before deleting the storage
  file. The previous order (file deletion first) caused a regression where
  users could get stuck in a "cannot log out" state if file removal failed.

- Add missing copilot_models.clear() in clear_auth() — this cache was
  cleaned in remove_account() but never in the full clear path.

- Add endpoint_locks cleanup in both remove_account() and clear_auth()
  to prevent minor in-process memory leaks.

- Update test to assert the correct behavior: memory should be cleaned
  even when file deletion fails.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: 周梦泽 <mengze.zhou@dafeng-tech.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Jason <farion1231@gmail.com>
2026-04-04 22:52:23 +08:00
Jason Young e4fe2763cd chore(deps): bump actions/cache from 4 to 5 in ci.yml (#1860)
Sync ci.yml with release.yml after dependabot updates.
2026-04-03 16:24:55 +08:00
dependabot[bot] 3e1de466db chore(deps): bump actions/download-artifact from 4 to 8
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 8.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4...v8)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-03 08:40:29 +08:00
dependabot[bot] 1abe474e75 chore(deps): bump actions/upload-artifact from 4 to 7
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-03 08:40:22 +08:00
dependabot[bot] 74d7e86b7a chore(deps): bump pnpm/action-setup from 2 to 5
Bumps [pnpm/action-setup](https://github.com/pnpm/action-setup) from 2 to 5.
- [Release notes](https://github.com/pnpm/action-setup/releases)
- [Commits](https://github.com/pnpm/action-setup/compare/v2...v5)

---
updated-dependencies:
- dependency-name: pnpm/action-setup
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-03 08:40:14 +08:00
dependabot[bot] b9297e42f5 chore(deps): bump actions/setup-node from 4 to 6
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-03 08:40:09 +08:00
dependabot[bot] 7de2db9ee8 chore(deps): bump actions/cache from 4 to 5
Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-03 08:32:17 +08:00
Jason 1b4c3cbcaa ci: add stale bot to auto-close inactive issues after 60 days
- Mark issues as stale after 60 days of inactivity
- Auto-close after 14 more days without response
- Bilingual (zh/en) stale and close messages
- Exempt security and performance labeled issues
- Runs daily at UTC 00:00, processes up to 100 issues per run
- Only affects issues, not pull requests
2026-04-03 00:01:13 +08:00
Jason 2b9b5b0bc3 docs: fix outdated README content and sync across languages
- Fix JA README macOS FAQ still claiming app is unsigned (now code-signed & notarized)
- Update SessionManager description from "Claude Code only" to "all supported apps" (EN/ZH/JA)
- Replace non-existent Flatpak download entry with self-build reference (EN/ZH/JA)
- Add OpenCode and OpenClaw filesystem paths to Flatpak minimal permissions
- Bump user manual version to v3.12.3
2026-04-02 22:38:42 +08:00
Jason 2af38a63b5 docs: point FUNDING.yml to Chinese README sponsor section 2026-04-02 22:22:12 +08:00
Jason 3388cba1dc docs: add sponsor call-to-action to READMEs and fix FUNDING.yml 2026-04-02 22:15:49 +08:00
Jason 8b44d9f54d fix(test): resolve HOME env race condition in parallel tests
- Use get_home_dir() instead of dirs::home_dir() in get_opencode_dir()
  and get_openclaw_dir() to respect CC_SWITCH_TEST_HOME override
- Add CC_SWITCH_TEST_HOME to all TempHome implementations
- Add #[serial] to all with_test_home tests to share serialization
  with other env-mutating tests
- Remove --test-threads=1 workaround from CI
2026-04-02 22:08:12 +08:00
Jason 8cdc07c860 ci: run cargo tests single-threaded to fix HOME env race 2026-04-02 20:38:31 +08:00
Jason 9a44245b73 style: use to_vec() instead of iter().copied().collect() 2026-04-02 17:46:14 +08:00
Jason 1b2885c335 style: use iter().copied() instead of iter().map(|s| *s) 2026-04-02 17:37:04 +08:00
Jason 447a1da7b2 ci: remove nonexistent pnpm lint step 2026-04-02 17:36:26 +08:00
Jason bfe238f301 style: fix formatting issues caught by CI 2026-04-02 17:32:33 +08:00
Jason 0c9a20ca68 ci: add PR and push quality checks workflow 2026-04-02 17:28:01 +08:00
Jason fee8577032 feat: hide GitHub Copilot provider preset and auth tab
Users reported that Copilot support causes excessively fast token
consumption. Temporarily hide the feature by adding a `hidden` field
to ProviderPreset interface and commenting out the auth center tab
in settings. Existing Copilot providers in DB still work via proxy.
2026-04-02 17:15:11 +08:00
Jason bae369b0dc docs: add SUPPORT.md and FUNDING.yml 2026-04-02 16:51:33 +08:00
Jason 6e2baaefa6 docs: add CONTRIBUTING.md, SECURITY.md, and CODE_OF_CONDUCT.md
Add three community health files with bilingual (EN/ZH) support:
- CODE_OF_CONDUCT.md: Contributor Covenant v2.1 with official Chinese translation
- SECURITY.md: security policy pointing to GitHub Security Advisories
- CONTRIBUTING.md: contribution guide with dev setup, code style, PR guidelines,
  i18n rules, and AI-assisted contribution policy
2026-04-02 16:26:26 +08:00
Jason 0001438586 ci: add emoji to issue template names 2026-04-02 15:44:01 +08:00
Jason 6e9e47ceb9 ci: add issue and PR templates with bilingual support
Add GitHub issue templates (bug report, feature request, documentation
issue, question) and PR template. All templates use bilingual format
(English + Chinese) to support the international community.
2026-04-02 15:40:06 +08:00
Bengbengbalabalabeng 14a3799f41 ci: add dependabot.yml config (#1829)
* ci: add dependabot.yml config

* chore: replace `rust` label with `backend` and fix missing newline

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-04-02 11:10:06 +08:00
ifNil 2f5bf1cea9 fix: avoid resetting usage query fields when editing extractor code (#1771) 2026-04-02 09:25:33 +08:00
Roy Li ba0b57f014 fix(claude): sync takeover live config during provider changes (#1828)
Keep Claude's live settings aligned with the latest provider state while proxy takeover is active, without breaking takeover fields or restore behavior.

Co-authored-by: Jason <farion1231@gmail.com>
2026-04-01 22:21:59 +08:00
Dex Miller 3553d05bf0 feat(provider): additive provider key lifecycle & fix openclaw serializer panic (#1724)
* feat(provider): support additive provider key lifecycle management

Add `addToLive` parameter to add_provider so callers can opt out of
writing to the live config (e.g. when duplicating an inactive provider).
Add `originalId` parameter to update_provider to support provider key
renames — the old key is removed from live config before the new one
is written.

Frontend: ProviderForm now exposes provider-key input for openclaw app
type, and EditProviderDialog forwards originalId on save. Deep-link
import passes addToLive=true to preserve existing behavior.

* test(provider): add integration tests for additive provider key flows

Cover openclaw provider duplication scenario to verify that a generated
provider key is assigned automatically. Add MSW handlers for
get_openclaw_live_provider_ids, get_openclaw_default_model,
scan_openclaw_config_health, and check_env_conflicts endpoints.
Update EditProviderDialog mock to pass originalId alongside provider.

* fix(openclaw): replace json-five serializer to prevent panic on empty collections

json-five 0.3.1 panics when pretty-printing nested empty maps/arrays.
Switch value_to_rt_value() to serde_json::to_string_pretty() which
produces valid JSON5 output without the panic. Add regression test for
removing the last provider (empty providers map).

* style: apply rustfmt formatting to proxy and provider modules

Reformat chained .header() calls in ClaudeAdapter and StreamCheckService
for consistent alignment. Reorder imports alphabetically in stream_check.
Fix trailing whitespace in transform.rs and merge import lines in
provider/mod.rs.

* style: fix clippy warnings in live.rs and tray.rs

* refactor(provider): simplify live_config_managed and deduplicate tolerant live config checks

- Change live_config_managed from Option<bool> to bool with #[serde(default)]
- Extract repeated tolerant live config query into check_live_config_exists helper
- Fix duplicate key generation to also check live-only provider IDs
- Fix updateProvider test to match new { provider, originalId } call signature
- Add streaming_responses test type annotation for compiler inference

* fix(provider): distinguish legacy providers from db-only when tolerating live config errors

Change `ProviderMeta.live_config_managed` from `bool` to `Option<bool>`
to introduce a three-state semantic:
- `Some(true)`: provider has been written to live config
- `Some(false)`: explicitly db-only, never written to live config
- `None`: legacy data or unknown state (pre-existing providers)

Previously, legacy providers defaulted to `live_config_managed = false`
via `#[serde(default)]`, which silently swallowed live config parse
errors. This could mask genuine configuration issues for providers that
had actually been synced to live config before the field was introduced.

Now, only providers with an explicit `Some(false)` marker tolerate parse
errors; legacy `None` providers surface errors as before, preserving
safety for already-managed configurations.

Also wrap the `ensureQueryData` call for live provider IDs during
duplication in a try/catch so that a malformed config file shows a
user-facing toast instead of silently failing.

Add tests for both the legacy error propagation path and the frontend
duplication failure scenario.

* refactor(provider): unify OMO variant updates with atomic file-then-db writes and rollback

Consolidate the duplicated omo/omo-slim update branches into a single
match on the variant. Write the OMO config file from the in-memory
provider state *before* persisting to the database, so a file-write or
plugin-sync failure leaves the database unchanged. If `add_plugin`
fails after the config file is already written, roll back to the
previous on-disk contents via snapshot/restore.

Also:
- `sync_all_providers_to_live` now skips db-only providers
  (`live_config_managed == Some(false)`) instead of attempting to write
  them to live config.
- `import_{opencode,openclaw}_providers_from_live` mark imported
  providers as `live_config_managed: Some(true)` so they are correctly
  recognized during subsequent syncs.
- Extract OmoService helpers: `profile_data_from_provider`,
  `snapshot_config_file`, `restore_config_file`, `write_profile_config`,
  and the new public `write_provider_config_to_file`.
- Add 9 new tests covering sync skip, legacy restore, import marking,
  OMO persistence, file-write failure, and plugin-sync rollback.

* fix(provider): fix additive provider delete/switch regressions and redundancy

- fix(delete): replace stale live_config_managed flag check with
  check_live_config_exists so providers written to live before the
  flag-flip logic was introduced are still cleaned up on delete
- fix(switch): make write_live_with_common_config return Err instead of
  silently returning Ok when config structure is invalid, preventing
  live_config_managed from being incorrectly flipped to true
- fix(update): block provider key rename for OMO/OMO Slim categories to
  prevent orphaned current-state markers breaking OMO file syncs
- fix(switch): flip live_config_managed to true after successful live
  write for DB-only additive providers so sync_all_providers_to_live
  includes them on future syncs; roll back live write if DB update fails
- refactor(delete): merge symmetric OMO/OMO-Slim blocks into single
  match-on-variant path; hoist DB read to top of additive branch
- refactor(remove_from_live_config): merge OMO/OMO-Slim if/else-if
  into single match-on-variant path
- refactor(switch_normal): merge two OMO/OMO-Slim if blocks into one
  OpenCode guard with (enable, disable) variant pair
- fix(update): remove redundant duplicate return Ok(true) after OMO
  current-state write

* fix(test): use preferred_filename after OMO field rename

The merge from main brought in #1746 which renamed
OmoVariant.filename → preferred_filename, but the test helper
omo_config_path() was not updated, breaking compilation of all
new provider tests.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-04-01 21:16:41 +08:00
Bengbengbalabalabeng 72f3610ac0 docs(readme): use dynamic badges (#1806) 2026-04-01 16:09:19 +08:00
Jason 854266e3c4 docs: add ChefShop AI sponsor to all README versions
Add ChefShop AI as a new sponsor with logo and descriptions in Chinese, English, and Japanese README files.
2026-03-31 23:07:51 +08:00
Jason af8f907467 fix(proxy): serialize per-app provider switches to prevent state corruption
Concurrent failover switches for the same app could cause is_current,
local settings, and Live backup to point at different providers.

- Add SwitchLockManager with per-app mutexes (different apps still parallel)
- Unify scattered switch logic into ProxyService::hot_switch_provider
- Fix TOCTOU in set_current_provider via mutate_settings
- Add logical_target_changed to skip redundant UI refreshes
- Add tests for serialization and restore-waits-for-switch scenarios
2026-03-31 22:46:42 +08:00
Dex Miller 6a083cdd1c fix(omo): adapt to oh-my-openagent rename with backward compatibility (#1746)
* fix(omo): adapt to oh-my-openagent rename with backward compatibility

Closes https://github.com/farion1231/cc-switch/issues/1733

* fix(omo): prioritize oh-my-openagent config over legacy oh-my-opencode
2026-03-31 16:32:49 +08:00
Dex Miller c68476d0ea fix(provider): show persistent config highlight for additive-mode providers (#1747)
* fix(provider): show persistent config highlight for additive-mode providers

Closes https://github.com/farion1231/cc-switch/issues/1692

* fix(provider): limit persistent config highlight to opencode only
2026-03-31 16:21:04 +08:00
Dex Miller 96a0a37331 feat(terminal): add directory picker before launching Claude terminal (#1752)
* Add directory picker before launching Claude terminal

* fix(terminal): preserve cwd path and strip Windows verbatim prefix

- Stop trimming non-empty paths so directories with leading/trailing
  spaces on Unix are handled correctly
- Strip \\?\ extended-length prefix from canonicalized paths on Windows
  to prevent batch script cd failures

* fix(terminal): restore UNC paths when stripping Windows verbatim prefix

Handle \\?\UNC\server\share form separately from regular \\?\ prefix,
converting it back to \\server\share so network/WSL directory paths
remain valid in batch cd commands.

* fix(terminal): use pushd for UNC paths in Windows batch launcher

`cmd.exe` cannot set a UNC path (e.g. `\\wsl$\...`) as the current
directory via `cd /d`; it errors with "CMD does not support UNC paths
as current directories". Switch to `pushd` which temporarily maps the
UNC share to a drive letter.

Rename `build_windows_cd_command` → `build_windows_cwd_command` to
reflect the broader semantics. Extract `build_windows_cwd_command_str`
and `is_windows_unc_path` helpers for testability, and add unit tests
covering drive paths, UNC paths, and batch metacharacter escaping.

Also fix minor style issues: sort mod declarations alphabetically,
add missing EOF newline in lightweight.rs, add explicit type annotation
in streaming_responses test, and reformat tray menu builder chain.
2026-03-31 15:10:08 +08:00
Alexlangl 8e2ffbc845 feat: add bulk delete for session manager (#1693)
* feat: add bulk delete for session manager

* fix: address batch delete review issues

* fix: keep session list in sync after batch delete
2026-03-30 22:15:57 +08:00
Alexlangl 4f7ea76347 fix: preserve WebDAV password display and validate MKCOL 405 (#1685)
* fix: preserve WebDAV password display and validate MKCOL 405

* fix: scope WebDAV password preservation to post-save refresh
2026-03-30 22:13:21 +08:00
Dex Miller 67e074c0a7 refactor(proxy): transparent header forwarding via hyper client (#1714)
* style(frontend): reformat provider forms, constants and hooks

Apply prettier formatting across 5 frontend files. No logic changes.

Changed files:
- AddProviderDialog.tsx: reformat generic type annotation and callback
- ClaudeFormFields.tsx: consolidate multi-line useState and Collapsible props
- CodexConfigSections.tsx: expand single-line React imports to multi-line,
  collapse removeCodexTopLevelField() call
- constants.ts: merge TemplateType into single line
- useSkills.ts: expand single-line TanStack Query imports to multi-line,
  reformat uninstallSkill mutationFn chain

* deps(proxy): add hyper ecosystem crates and manual decompression libs

reqwest internally normalizes all header names to lowercase and does not
preserve insertion order, causing proxied requests to differ from the
original client requests. To achieve transparent header forwarding with
original casing and order, introduce lower-level hyper HTTP client libs.

New dependencies:
- hyper-util 0.1: TokioExecutor + legacy Client with
  preserve_header_case support for HTTP/1.1
- hyper-rustls 0.27: rustls-based TLS connector for hyper
- http 1 / http-body 1 / http-body-util 0.1: HTTP type crates for
  hyper 1.x request/response construction
- flate2 1: manual gzip/deflate decompression (replaces reqwest auto)
- brotli 7: manual brotli decompression

Changed dependencies:
- serde_json: enable preserve_order feature to keep JSON field order
- reqwest: drop gzip feature to prevent reqwest from overriding the
  client's original accept-encoding header

* refactor(proxy): use hyper client for header-case preserving forwarding

Previously the proxy used reqwest for all upstream requests. reqwest
normalizes header names to lowercase and reorders them internally,
making proxied requests distinguishable from direct CLI requests.
Some upstream providers are sensitive to these differences.

This commit replaces reqwest with a hyper-based HTTP client on the
default (non-proxy) path, achieving wire-level header fidelity:

Server layer (server.rs):
- Replace axum::serve with a manual hyper HTTP/1.1 accept loop
- Enable preserve_header_case(true) so incoming header casing is
  captured in a HeaderCaseMap extension on each request
- Bridge hyper requests to axum Router via tower::Service

New hyper client module (hyper_client.rs):
- Lazy-initialized hyper-util Client with preserve_header_case
- ProxyResponse enum wrapping both hyper::Response and reqwest::Response
  behind a unified interface (status, headers, bytes, bytes_stream)
- send_request() builds requests with ordered HeaderMap + case map

Request handlers (handlers.rs):
- Switch from (HeaderMap, Json<Value>) extractors to raw
  axum::extract::Request to preserve Extensions (containing the
  HeaderCaseMap from the accept loop)
- Pass extensions through the forwarding chain

Forwarder (forwarder.rs):
- Remove HEADER_BLACKLIST array; replace with ordered header iteration
  that preserves original header sequence and casing
- Build ordered_headers by iterating client headers, skipping only
  auth/host/content-length, and inserting auth headers at the original
  authorization position to maintain order
- Handle anthropic-beta (ensure claude-code-20250219 tag) and
  anthropic-version (passthrough or default) inline during iteration
- Remove should_force_identity_encoding() — accept-encoding is now
  transparently forwarded to upstream
- Use hyper client by default; fall back to reqwest only when an
  HTTP/SOCKS5 proxy tunnel is configured

Provider adapters (adapter.rs, claude.rs, codex.rs, gemini.rs):
- Replace add_auth_headers(RequestBuilder) -> RequestBuilder with
  get_auth_headers(AuthInfo) -> Vec<(HeaderName, HeaderValue)>
- Adapters now return header pairs instead of mutating a reqwest builder
- Claude adapter: merge Anthropic/ClaudeAuth/Bearer into single branch;
  move Copilot fingerprint headers into get_auth_headers

Response processing (response_processor.rs):
- Add manual decompression (gzip/deflate/brotli via flate2 + brotli)
  for non-streaming responses, since reqwest auto-decompression is now
  disabled to allow accept-encoding passthrough
- Add compressed-SSE warning log for streaming responses
- Accept ProxyResponse instead of reqwest::Response

HTTP client (http_client.rs):
- Disable reqwest auto-decompression (.no_gzip/.no_brotli/.no_deflate)
  on both global and per-provider clients

Streaming adapters (streaming.rs, streaming_responses.rs):
- Generalize stream error type from reqwest::Error to generic E: Error

Misc:
- log_codes.rs: add SRV-005 (ACCEPT_ERR) and SRV-006 (CONN_ERR)
- stream_check.rs: reformat copilot header lines
- transform.rs: fix trailing whitespace alignment

* fix(lint): resolve 35 clippy warnings across Rust codebase

Fix all clippy warnings reported by `cargo clippy --lib`:

- codex_config.rs: fix doc_overindented_list_items (3 spaces -> 2)
- commands/copilot.rs: inline format args in 2 log::error! calls
- commands/provider.rs: inline format args in 3 map_err closures
- proxy/hyper_client.rs: inline format arg in log::debug! call
- proxy/providers/copilot_auth.rs: inline format args in 16 locations
  (log macros, format! in headers, error constructors)
- proxy/thinking_optimizer.rs: inline format args in 2 log::info! calls
- services/skill.rs: inline format args in log::debug! call
- services/webdav_sync.rs: inline format args in 6 format! calls
  (version compat messages, download limit messages)
- services/webdav_sync/archive.rs: inline format args in 2 format! calls
- session_manager/providers/opencode.rs: inline format args in
  source_path format!

All fixes use the clippy::uninlined_format_args suggestion pattern:
  format!("msg: {}", var)  ->  format!("msg: {var}")

* deps(proxy): add raw HTTP write and native TLS cert dependencies

Add crates required for the raw TCP/TLS write path that bypasses
hyper's header encoder to preserve original header name casing:

- httparse: parse raw TCP peek bytes to capture header casings
- tokio-rustls + rustls: direct TLS connections for raw write path
- webpki-roots: Mozilla CA bundle baseline
- rustls-native-certs: load system keychain CAs (trusts proxy MITM
  certificates from Clash, mitmproxy, etc.)

* fix(proxy): address code review feedback on response handling

Fixes from PR #1714 code review:

- Extract `read_decoded_body()` and `strip_entity_headers_for_rebuilt_body()`
  in response_processor to properly clean content-encoding/content-length
  headers after decompression
- Reuse `read_decoded_body()` in handlers.rs for Claude transform path,
  ensuring compressed responses are decoded before format conversion
- Make `build_proxy_url_from_config()` public so forwarder can pass proxy
  URL to the hyper raw write path
- Add `has_system_proxy_env()` utility with test coverage
- Add 50ms backoff after accept() failures in server.rs to prevent
  tight-loop CPU spin on transient socket errors

* feat(proxy): implement raw TCP/TLS write with HTTP CONNECT tunnel

Rewrite hyper_client with a two-tier strategy for header case preservation:

Primary path (raw write):
- Peek raw TCP bytes in server.rs to capture OriginalHeaderCases before
  hyper lowercases them
- Build raw HTTP/1.1 request bytes with exact original header name casing
- Write directly to TLS stream, then use WriteFilter to let hyper parse
  the response while discarding its duplicate request writes
- Support HTTP CONNECT tunneling through upstream proxies, so header case
  is preserved even when a proxy (Clash, V2Ray) is configured

Fallback path (hyper-util Client):
- Used when OriginalHeaderCases is empty or raw write fails
- Configured with title_case_headers(true) for best-effort casing

TLS improvements:
- Load native system certificates alongside webpki roots so proxy MITM
  CAs (installed in system keychain) are trusted through CONNECT tunnels

Key types added:
- OriginalHeaderCases: maps lowercase name → original wire-casing bytes
- WriteFilter<S>: AsyncRead+AsyncWrite wrapper that discards writes
- connect_via_proxy(): HTTP CONNECT tunnel establishment
- ExtensionDebugMarker: diagnostic marker for extension chain debugging

* refactor(proxy): route requests through hyper with proxy-aware forwarding

Rework forwarder request dispatch to always prefer the hyper raw write
path (header case preservation) over reqwest:

Request routing:
- HTTP/HTTPS proxy: hyper raw write through CONNECT tunnel (case preserved)
- SOCKS5 proxy: reqwest fallback (CONNECT not supported for SOCKS5)
- No proxy: hyper raw write direct connection

Header handling improvements:
- Replace host header in-place at original position instead of
  skip-and-append, preserving client's header ordering
- Preserve client's original accept-encoding for transparent passthrough;
  only force identity encoding when transform path needs decompression
- Add should_force_identity_encoding() to centralize the decision
- Remove hardcoded 'br, gzip, deflate' override that masked client values

Proxy URL resolution (priority order):
1. Provider-specific proxy config (if enabled)
2. Global proxy URL configured in CC Switch
3. Direct connection (no proxy)

* chore(proxy): remove dead code, redundant tests and debug scaffolding

- Inline should_force_identity_encoding() (was just `needs_transform`)
  and delete its 5 test cases
- Remove ExtensionDebugMarker diagnostic type
- Remove unused has_system_proxy_env() and its test
- Remove strip_entity_headers test
- Simplify hyper path: remove redundant is_socks_proxy ternary
- Update hyper_client module doc to reflect CONNECT tunnel support

* fix(proxy): block direct-connect fallback and complete CONNECT tunnel support

* feat(hooks): improve proxy requirement warnings with specific reasons

- Remove redundant OpenAI format hint toast messages
- Add detailed reason detection for proxy requirements (OpenAI Chat, OpenAI Responses, full URL mode)
- Update i18n files with new reason-specific keys

* style(*): format code with prettier

- Remove extra whitespace in http_client.rs
- Fix formatting issues in useProviderActions.ts

* fix(proxy): post-merge fixes for forward return type and clippy warnings

- Restore forward() return type to (ProxyResponse, Option<String>)
  to pass claude_api_format through to callers
- Inline format args in log::warn! macro (clippy::uninlined_format_args)
- Suppress too_many_arguments for check_claude_stream

* refactor(proxy): preserve original header wire order and add non-streaming body timeout

- Rewrite build_raw_request to emit headers in original
  client-sent sequence instead of hash-map order
- Remove unused OriginalHeaderCases::get_all method
- Add body_timeout to read_decoded_body to prevent
  requests hanging when upstream stalls after headers
2026-03-29 20:26:15 +08:00
ruokeqx b1c7fe5563 feat: add lightweight mode (#1739) 2026-03-29 18:35:23 +08:00
makoMakoGo 210bff96c2 fix(env): detect bun global bin paths in CLI scan (#1742) 2026-03-29 15:52:37 +08:00
makoMakoGo 3b33e6921b fix: correct opencode kimi-for-coding preset (#1738) 2026-03-29 10:31:23 +08:00
Zhou Mengze 8d5f72757e fix: 修复 Copilot 作为 Claude 时 OpenAI 模型的 Responses 分流 (#1735)
* fix: route copilot claude openai models to responses

* fix(i18n): add copilotProxyHint translation key for all locales

The copilotProxyHint message was using inline defaultValue with Chinese
text, which would show Chinese to English and Japanese users. Added
proper translation keys in zh/en/ja locale files and removed the
hardcoded defaultValue fallback.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-03-29 10:29:54 +08:00
Dex Miller 8cae7b7b73 feat(proxy): add full URL mode and refactor endpoint rewriting (#1561)
* feat(proxy): add full URL mode and refactor endpoint rewriting

- Add `isFullUrl` provider meta to treat base_url as complete API endpoint
- Remove hardcoded `?beta=true` from Claude adapter, pass through from client
- Refactor forwarder endpoint rewriting with proper query string handling
- Block provider switching when proxy is required but not running
- Add full URL toggle UI in endpoint field with i18n (zh/en/ja)

* refactor(proxy): remove beta query handling

* fix(proxy): strip beta query when rewriting Claude endpoints

* feat(codex): complete full URL support

* refactor(ui): refine full URL endpoint hint
2026-03-28 15:52:02 +08:00
tgbdhs eaf83f4fbe fix(proxy): parse SSE fields with optional spaces in streaming handlers (#1664)
* fix(proxy): handle SSE fields with or without spaces

* refactor(proxy): deduplicate SSE field parsing
2026-03-25 22:06:21 +08:00
Sky 90812e7f3a feat(opencode): add StepFun Step Plan provider preset (#1668)
Add StepFun Step Plan (阶跃星辰编程计划) as an OpenCode provider preset.

StepFun Step Plan is a subscription-based coding AI service that uses a
dedicated API endpoint separate from the standard StepFun provider.

- Base URL: https://api.stepfun.com/step_plan/v1
- Model: step-3.5-flash (196B MoE, optimized for agent and coding tasks)
- Category: cn_official
- Supports tool_call, reasoning, temperature control

Ref: https://platform.stepfun.com/docs/zh/step-plan/overview
Made-with: Cursor

Co-authored-by: sky-wang-salvation <sky-wang-salvation@users.noreply.github.com>
2026-03-25 21:22:05 +08:00
Jason 8c42ec48ef docs(release): add risk notice anchor links in v3.12.3 highlights section 2026-03-24 17:53:07 +08:00
Jason 761038f0ea docs(release): add Copilot reverse proxy risk notice to v3.12.3 release notes
Add risk disclaimer section in all three languages (EN/ZH/JA) warning
users about potential GitHub ToS violations, account suspension risks,
and no long-term availability guarantee for the Copilot reverse proxy.
2026-03-24 17:46:32 +08:00
Jason 155a226e6a chore(release): consolidate v3.12.3 release notes, changelog and test fixes
Merge previously unreleased v3.12.4 content into v3.12.3:
- CHANGELOG: combine [Unreleased] into [3.12.3], clear [Unreleased]
- Release notes (zh/en/ja): add Copilot proxy, macOS signing,
  Reasoning Effort, OpenCode SQLite, Codex 1M toggle, Disable
  Auto-Upgrade toggle, and contributor thanks
- Fix test mocks for skill backup/restore hooks
- Fix schema migration test missing providers table
- Fix TempHome to save/restore CC_SWITCH_TEST_HOME env var
2026-03-24 15:26:17 +08:00
Jason 10be929f33 feat(claude): add "Disable Auto-Upgrade" checkbox to provider config editor
Add a toggle for DISABLE_AUTOUPDATER env var in CommonConfigEditor,
following the same pattern as the existing Teammates mode toggle.
2026-03-24 15:17:09 +08:00
Jason 141010332b feat(dmg): use create-dmg for styled macOS DMG installer
Tauri's built-in DMG styling relies on AppleScript/Finder access which
silently fails on CI (tauri-apps/tauri#1731). Switch to create-dmg tool
which works on GitHub Actions macOS runners.

- Replace Tauri DMG with create-dmg: background image, icon positions,
  app-drop-link, codesign, hide-extension
- Regenerate background image at 2x Retina resolution (1320x800)
- Revert tauri.conf.json dmg config (ineffective on CI)
- Reorder steps: Prepare → Notarize DMG → Verify
- Notarize and Verify now use release-assets/ path for DMG
2026-03-24 10:33:18 +08:00
Jason 15989effb4 feat(dmg): customize macOS DMG installer appearance
- Add DMG background image with drag-to-install arrow guide
- Configure window size (660x400), app and Applications icon positions
- Center icons horizontally with visual arrow between them
2026-03-24 09:51:23 +08:00
Jason d4edf30747 fix(ci): add separate DMG notarization step and build retry for macOS
Tauri only notarizes the .app bundle, not the DMG container. This caused
stapler staple to fail with "Record not found" for the DMG.

- Add "Notarize macOS DMG" step using xcrun notarytool with retry logic
- Add retry logic (3 attempts) to macOS build step for transient network failures
- Add hdiutil verify before DMG notarization submission
2026-03-24 08:45:56 +08:00
Jason 44b6eacf87 feat(ci): add macOS code signing and Apple notarization to release workflow
- Import Developer ID Application certificate into temporary keychain
- Inject APPLE_SIGNING_IDENTITY/APPLE_ID/APPLE_PASSWORD/APPLE_TEAM_ID
  into Tauri build step for automatic signing and notarization
- Staple notarization tickets to both .app and .dmg (hard-fail)
- Add verification step: codesign --verify + spctl -a + stapler validate
  for both .app and .dmg, gating the release on success
- Collect .dmg alongside .tar.gz and .zip in release assets
- Clean up temporary keychain with original default restored
- Update release notes to recommend .dmg and note Apple notarization
- Remove all xattr workarounds and "unidentified developer" warnings
  from README, README_ZH, installation guides, and FAQ (EN/ZH/JA)
2026-03-23 22:43:41 +08:00
Jason 0a301a497c fix: prevent WebDAV password from being silently cleared by unrelated saves
Two components (ProviderList, UsageScriptModal) directly spread the full
settings object from the query into settingsApi.save(), which includes
webdavSync with an empty password (cleared by get_settings_for_frontend
for security). The backend merge_settings_for_save only preserved
existing WebDAV config when the incoming field was None, not when it was
present with an empty password.

Frontend fix: strip webdavSync before saving in both components, matching
the pattern already used by useSettings hook.

Backend defense-in-depth: merge_settings_for_save now backfills the
existing password when the incoming one is empty, preventing future
regressions from similar oversights.
2026-03-23 16:47:17 +08:00
TangZhiZzz 8aa6ec784b feat(skills): 优化技能安装/卸载的缓存更新策略 (#1573)
- 修改安装、卸载、导入、ZIP安装等操作的缓存更新逻辑,从invalidateQueries改为直接setQueryData
- 为已安装和可发现技能查询添加keepPreviousData和staleTime: Infinity配置
- 修复会话管理页面布局滚动问题,添加min-h-0防止内容溢出
2026-03-23 16:05:13 +08:00
BlueOcean bd3cfb7741 fix: parse tool_use/tool_result messages and add OpenCode SQLite backend (#1401)
* fix: parse tool_use/tool_result messages and add OpenCode SQLite backend

  - Claude: reclassify user messages containing tool_result as "tool" role
  - Codex: handle function_call and function_call_output payload types
  - Gemini: support array content and toolCalls extraction, filter info/error types
  - OpenCode: add SQLite session scan, load and delete alongside legacy JSON
  - utils: extend parse_timestamp_to_ms for integer timestamps, extract tool_use/tool_result in shared extract_text

* fix: address remaining issues from tool_use/tool_result parsing commit
  - Claude: fix role misclassification for mixed user+tool_result messages (any → all)
  - OpenCode: extract duplicate part text logic into extract_part_text()
  - OpenCode: add path validation for SQLite delete to prevent foreign DB access
  - OpenCode: wrap SQLite deletion in transaction for atomicity
  - openclaw_config: remove redundant as_deref() on Option<&str>
2026-03-22 22:02:35 +08:00
makoMakoGo 117dbf1386 docs(usage): clarify pricing model ID normalization rules (#1591) 2026-03-21 22:59:28 +08:00
Jianan 72f570b99e fix: change darkMode selector to use .dark class (#1596) 2026-03-21 22:55:21 +08:00
Jason 2296c41497 chore: update MiniMax partner description from M2.5 to M2.7 2026-03-21 09:18:53 +08:00
Jason fe3f9b60de feat(proxy): resolve reasoning_effort from explicit effort with budget fallback
Replace map_thinking_to_reasoning_effort() with resolve_reasoning_effort()
that uses a two-tier priority system:

1. Explicit output_config.effort: low/medium/high map 1:1, max → xhigh
2. Fallback: thinking.type + budget_tokens thresholds (<4k → low,
   4k-16k → medium, ≥16k → high, adaptive → high)

Both Chat Completions and Responses API paths share the same helper,
ensuring consistent mapping across all OpenAI-compatible endpoints.
2026-03-20 23:36:47 +08:00
Jason 3e78fe8305 chore: update MiniMax preset model from M2.5 to M2.7 2026-03-20 21:05:56 +08:00
Jason 6f170305b8 chore: update Claude 4.6 context window to 1M (GA)
Claude Opus 4.6 and Sonnet 4.6 1M context window is now GA and no
longer requires a beta header. Update contextWindow from 200k to 1M
for all OpenClaw/OpenCode presets (27 entries in OpenClaw, 1 in
OpenCode Bedrock). Also add claude-sonnet-4-6 model pricing seed.
2026-03-20 21:00:22 +08:00
Jason 552f7abee4 refactor(ui): remove duplicate OAuth tab from AddProviderDialog
- Remove AuthCenterPanel import and OAuth TabsContent
- Narrow activeTab type from three values to "app-specific" | "universal"
- Simplify footer by removing oauth branch, reducing to two-way conditional
- Change TabsList from grid-cols-3 to grid-cols-2
- OAuth authentication remains available in settings page and CopilotAuthSection
2026-03-20 15:23:18 +08:00
Jason fd2b232f1c chore: update Xiaomi MiMo preset model from mimo-v2-flash to mimo-v2-pro 2026-03-20 08:59:41 +08:00
Jason 82c75de51c fix(copilot): unify request fingerprint across all Copilot API calls
- Make header constants in copilot_auth.rs public, add COPILOT_INTEGRATION_ID
- Unify User-Agent across 4 internal methods (eliminate "CC-Switch" leakage) and version string
- claude.rs add_auth_headers now references shared constants, adds user-agent / api-version / openai-intent
- forwarder.rs filters all 6 fixed fingerprint headers for Copilot requests to prevent reqwest append duplication
- stream_check.rs health check pipeline aligned with new fingerprint
2026-03-19 17:29:04 +08:00
Zhou Mengze 8ccfbd36d6 feat(copilot): add GitHub Copilot reverse proxy support (#930)
* refactor(toolsearch): replace binary patch with ENABLE_TOOL_SEARCH env var toggle

- Remove toolsearch_patch.rs binary patching mechanism (~590 lines)
  - Delete `toolsearch_patch.rs` and `commands/toolsearch.rs`
  - Remove auto-patch startup logic and command registration from lib.rs
  - Remove `tool_search_bypass` field from settings.rs
  - Remove frontend settings ToggleRow, useSettings hook sync logic, and API methods
  - Clean up zh/en/ja i18n keys (notifications + settings)

- Add ENABLE_TOOL_SEARCH toggle to Claude provider form
  - Add checkbox in CommonConfigEditor.tsx (alongside teammates toggle)
  - When enabled, writes `"env": { "ENABLE_TOOL_SEARCH": "true" }`
  - When disabled, removes the key; takes effect on provider switch
  - Add zh/en/ja i18n key: `claudeConfig.enableToolSearch`

Claude Code 2.1.76+ natively supports this env var, eliminating the need for binary patching.

* feat(claude): add effortLevel high toggle to provider form

- Add "high-effort thinking" checkbox to Claude provider config form
- When checked, writes `"effortLevel": "high"`; when unchecked, removes the field
- Add zh/en/ja i18n translations

* refactor(claude): remove deprecated alwaysThinking toggle

- Claude Code now enables extended thinking by default; alwaysThinkingEnabled is a no-op
- Thinking control is now handled via effortLevel (added in prior commit)
- Remove state, switch case, and checkbox UI from CommonConfigEditor
- Clean up alwaysThinking i18n keys across zh/en/ja locales

* feat(opencode): add setCacheKey: true to all provider presets

- Add setCacheKey: true to options in all 33 regular presets
- Add setCacheKey: true to OPENCODE_DEFAULT_CONFIG for custom providers
- Exclude 2 OMO presets (Oh My OpenCode / Slim) which have their own config mechanism

Closes #1523

* fix(codex): resolve 1M context window toggle causing MCP editor flicker

- Add localValueRef to short-circuit duplicate CodeMirror updateListener callbacks,
  breaking the React state → CodeMirror → stale onChange → React state feedback loop
- Use localValueRef.current in handleContextWindowToggle and handleCompactLimitChange
  to avoid stale closure reads
- Change compact limit input from type="number" to type="text" with inputMode="numeric"
  to remove unnecessary spinner buttons

* feat(codex): add 1M context window toggle utilities and i18n keys

- Add extractCodexTopLevelInt, setCodexTopLevelInt, removeCodexTopLevelField
  TOML helpers in providerConfigUtils.ts
- Add i18n keys for contextWindow1M, autoCompactLimit in zh/en/ja locales

* feat(claude): collapse model mapping fields by default

- Wrap 5 model mapping inputs in a Collapsible, collapsed by default
- Auto-expand when any model value is present (including preset-filled)
- Show hint text when collapsed explaining most users need no config
- Add zh/en/ja i18n keys for toggle label and collapsed hint
- Use variant={null} to avoid ghost button hover style clash in dark mode

* feat(claude): merge advanced fields into single collapsible section

- Merge API format, auth field, and model mapping into a unified "Advanced Options" collapsible
- Extend smart-expand logic to detect non-default values across all advanced fields
- Preserve model mapping sub-header and hint with a separator line
- Update zh/en/ja i18n keys (advancedOptionsToggle, advancedOptionsHint, modelMappingLabel, modelMappingHint)

* feat(copilot): add GitHub Copilot reverse proxy support

Add GitHub Copilot as a Claude provider variant with OAuth device code
authentication and Anthropic ↔ OpenAI format transformation.

Backend:
- Add CopilotAuthManager for GitHub OAuth device code flow
- Implement Copilot token auto-refresh (60s before expiry)
- Persist GitHub token to ~/.cc-switch/copilot_auth.json
- Add ProviderType::GitHubCopilot and AuthStrategy::GitHubCopilot
- Modify forwarder to use /chat/completions for Copilot
- Add Copilot-specific headers (Editor-Version, Editor-Plugin-Version)

Frontend:
- Add CopilotAuthSection component for OAuth UI
- Add useCopilotAuth hook for OAuth state management
- Auto-copy user code to clipboard and open browser
- Use 8-second polling interval to avoid GitHub rate limits
- Skip API Key validation for Copilot providers
- Add GitHub Copilot preset with claude-sonnet-4 model

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* fix(copilot): remove is_expired() calls from tests

Remove references to deleted is_expired() method in test code.
Only is_expiring_soon() is needed for token refresh logic.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* feat(copilot): add real-time model listing from Copilot API

- Add fetch_models() to CopilotAuthManager calling GET /models endpoint
- Add copilot_get_models Tauri command
- Add copilotGetModels() frontend API wrapper
- Modify ClaudeFormFields to show model dropdown for Copilot providers
  - Fetches available models on component mount when isCopilotPreset
  - Groups models by vendor (Anthropic, OpenAI, Google, etc.)
  - Input + dropdown button combo allows both manual entry and selection
  - Non-Copilot providers keep original plain Input behavior

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

* feat(copilot): add usage query integration

- Add Copilot usage API integration (fetch_usage method)
- Add copilot_get_usage Tauri command
- Add GitHub Copilot template in usage query modal
- Unify naming: copilot → github_copilot
- Add constants management (TEMPLATE_TYPES, PROVIDER_TYPES)
- Improve error handling with detailed error messages
- Add database migration (v5 → v6) for template type update
- Add i18n translations (zh, en, ja)
- Improve type safety with TemplateType
- Apply code formatting (cargo fmt, prettier)

* 修复github 登录和注销问题 ,模型选择问题

* feat(copilot): add multi-account support for GitHub Copilot

- Add multi-account storage structure with v1 to v2 migration
- Add per-account token caching and auto-refresh
- Add new Tauri commands for account management
- Integrate account selection in Proxy forwarder
- Add account selection UI in CopilotAuthSection
- Save githubAccountId to ProviderMeta
- Add i18n translations for multi-account features (zh/en/ja)

* 修复用量查询Reset字段出现多余字符

* refactor(auth-binding): introduce generic provider auth binding primitives

- add shared authBinding types in Rust and TypeScript while keeping githubAccountId as a compatibility field\n- resolve Copilot token, models, and usage through provider-bound account lookup instead of only the implicit default account\n- fix the Unix build regression in settings.rs by restoring std::io::Write for write_all()\n- remove the accidental .github ignore entry and drop leftover Copilot form debug logs\n- keep the first migration step non-breaking by writing both authBinding and the legacy githubAccountId field from the form

* refactor(auth-service): add managed auth command surface and explicit default account state

- introduce generic managed auth commands and frontend auth API wrappers for provider-scoped login, status, account listing, removal, logout, and default-account selection\n- store an explicit Copilot default_account_id instead of relying on HashMap iteration order, and use it consistently for fallback token/model/usage resolution\n- sort managed accounts deterministically and surface default-account state to the UI\n- refactor the Copilot form hook to wrap a generic useManagedAuth implementation while preserving the existing component contract\n- add default-account controls to the Copilot auth section and extend Copilot auth status serialization/tests for the new state

* feat(auth-center): add a dedicated settings entrypoint for managed OAuth accounts

- add an Auth Center tab to Settings so managed OAuth accounts are no longer hidden inside individual provider forms\n- introduce a first AuthCenterPanel that hosts GitHub Copilot account management as the initial managed auth provider\n- keep the provider form experience intact while establishing a global account-management surface for future providers such as OpenAI\n- validate that the new settings tab works cleanly with the generic managed auth hook and existing Copilot account controls

* feat(add-provider): expose managed OAuth sources alongside universal providers

- add an OAuth tab to the Add Provider flow so managed auth sources sit beside app-specific and universal providers\n- reuse the new Auth Center panel inside the dialog, keeping account management discoverable during provider creation\n- make the dialog footer adapt to the OAuth tab so account setup does not pretend to create a provider directly\n- align the add-provider UX with the new architecture where OAuth accounts are global assets and providers bind to them later

* fix(auth-reliability): harden managed auth persistence and refresh behavior

- replace direct Copilot auth store writes with private temp-file writes and atomic rename semantics, and document the local token storage limitation\n- add per-account refresh locks plus a double-check path so concurrent requests do not stampede GitHub token refresh\n- surface legacy migration failures through auth status, expose them in the UI, and add translated copy for the new account-state labels\n- stop writing the legacy githubAccountId field from the provider form while keeping compatibility reads in place\n- add logout error recovery and Copilot model-load toasts so auth failures are no longer silently swallowed

* refactor(copilot-detection): prefer provider type before URL fallbacks

- update forwarder endpoint rewriting to treat providerType as the primary GitHub Copilot signal\n- keep githubcopilot.com string matching only as a compatibility fallback for older provider records without providerType\n- reduce one more path where Copilot behavior depended purely on URL heuristics

* fix(copilot-auth): add cancel button to error state in CopilotAuthSection

- 错误状态下仅有"重试"按钮,用户无法退出(如不可恢复的 403 未订阅错误)
- 新增"取消"按钮,复用已有的 cancelAuth 逻辑重置为 idle 状态

* 修复打包后github账号头像显示异常

* 修复github copilot 来源的模型测试报错

* feat(copilot-preset): add default model presets for GitHub Copilot

- 补充 Copilot 预设的默认模型配置,用户选完预设即可直接使用
- ANTHROPIC_MODEL: claude-opus-4.6
- ANTHROPIC_DEFAULT_HAIKU_MODEL: claude-haiku-4.5
- ANTHROPIC_DEFAULT_SONNET_MODEL: claude-sonnet-4.6
- ANTHROPIC_DEFAULT_OPUS_MODEL: claude-opus-4.6

---------

Co-authored-by: Jason <farion1231@gmail.com>
Co-authored-by: 周梦泽 <mengze.zhou@dafeng-tech.com>
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-17 23:57:58 +08:00
Jason 36bbdc36f5 chore(release): update release notes, changelog and macOS minimum version for v3.12.3
Update CHANGELOG.md with full v3.12.3 entry, create release notes in
three languages (en/zh/ja), bump macOS minimumSystemVersion from 10.15
to 12.0 (Monterey) to match actual runtime requirements, and update
README version badges and links.
2026-03-16 08:32:05 +08:00
Jason fc08a5d364 fix(ui): replace hardcoded height calc with flex-1 to eliminate bottom blank area
All content panels used h-[calc(100vh-8rem)] which didn't match the
actual available space (CONTENT_TOP_OFFSET is 92px on Mac, 64px on
Win/Linux, not 128px), causing a visible gap at the bottom.

Replace with flex-1 min-h-0 to let panels fill the remaining space
after <main> and any sibling elements (e.g. OpenClaw health banner).
2026-03-16 00:19:29 +08:00
Jason 333c9f277b feat(skills): add restore and delete for skill backups
Introduce list/restore/delete commands for skill backups created during
uninstall. Restore copies files back to SSOT, saves the DB record, and
syncs to the current app with rollback on failure. Delete removes the
backup directory after a confirmation dialog. ConfirmDialog gains a
configurable zIndex prop to support nested dialog stacking.
2026-03-16 00:00:31 +08:00
Jason 9336001746 feat(skills): auto-backup skill files before uninstall
Create a local backup under ~/.cc-switch/skill-backups/ before removing
skill directories. The backup includes all skill files and a meta.json
with original skill metadata. Old backups are pruned to keep at most 20.
The backup path is returned to the frontend and shown in the success
toast. Bump version to 3.12.3.
2026-03-15 23:26:50 +08:00
Jason 04254d6ffe fix(skills): add missing TooltipProvider in ImportSkillsDialog to prevent white screen
The AppToggleGroup component added in 7097a0d7 uses Radix UI Tooltip
which requires a TooltipProvider context. Without it, opening the
import dialog crashes with a runtime error and renders a blank page.
2026-03-15 23:02:54 +08:00
Jason 28afbea917 fix(proxy): enable gzip compression for non-streaming proxy requests
Non-streaming requests were forced to use `Accept-Encoding: identity`,
preventing upstream response compression and increasing bandwidth usage.

Now only streaming requests conservatively keep `identity` to avoid
decompression errors on interrupted SSE streams. Non-streaming requests
let reqwest auto-negotiate gzip and transparently decompress responses.
2026-03-15 22:01:57 +08:00
Jason 81897ac17e fix: revert incorrect o-series max_completion_tokens in Responses API path
Responses API uses max_output_tokens for all models including o-series.
The o-series max_completion_tokens fix should only apply to Chat Completions API.
2026-03-15 21:06:08 +08:00
Jason bb23ab918b fix: place OpenCode model variants at top level instead of inside options (#1317)
Split the expanded model panel into two editing areas:
- "Model Properties" for top-level fields (variants, cost, etc.)
- "SDK Options" for model.options fields (provider routing, etc.)

Also guard against renaming extra fields to reserved keys (name, limit,
options) or duplicate names, and fix ModelOptionKeyInput blur desync when
a rename is rejected by the parent handler.
2026-03-15 21:06:08 +08:00
Hemilt0n f38facd430 fix(proxy): use max_completion_tokens for o1/o3 series models (#1451)
* fix(proxy): use max_completion_tokens for o1/o3 series models

When converting Anthropic requests to OpenAI format for o1/o3 series
models (like o1-mini, o3-mini), use max_completion_tokens instead of
max_tokens to avoid unsupported_parameter errors.

Fixes #1448

* fix: revert incorrect o-series max_completion_tokens in Responses API path

Responses API uses max_output_tokens for all models including o-series.
The o-series max_completion_tokens fix should only apply to Chat Completions API.

---------

Co-authored-by: Hajen Teowideo <hajen.teowideo@example.com>
Co-authored-by: Jason Young <44939412+farion1231@users.noreply.github.com>
Co-authored-by: Jason <farion1231@gmail.com>
2026-03-15 20:39:17 +08:00
Hexi 5c03de53f7 fix(provider-form): prevent duplicate submissions on rapid button clicks (#1352)
Make ProviderForm.handleSubmit async and await onSubmit so react-hook-form's
isSubmitting state is tracked. Disable submit buttons in AddProviderDialog and
EditProviderDialog while submission is in flight via onSubmittingChange callback.
2026-03-15 15:24:17 +08:00
osehun d8a7bc32db fix: restore Claude sessions in Ghostty (#1506)
Co-authored-by: SEHUN <canyonsehun@gmail.com>
2026-03-15 11:23:15 +08:00
Jason f1cad25777 chore: touch config files to normalize commit messages 2026-03-15 00:15:07 +08:00
Jason 9439153f05 feat: add Tool Search domain restriction bypass with active-installation patching
Resolve the active `claude` command from PATH and apply an equal-length
byte patch to remove the domain whitelist check. Backups are stored in
~/.cc-switch/toolsearch-backups/ (SHA-256 of path) so they survive
Claude Code version upgrades. The patch auto-reapplies on app startup
when the setting is enabled.

Frontend checks PatchResult.success and rolls back the setting on failure.
2026-03-14 23:41:36 +08:00
Jason 7097a0d710 fix: replace implicit app inference with explicit selection for Skills import and sync
Skills import previously inferred app enablement from filesystem presence,
causing incorrect multi-app activation when the same skill directory existed
under multiple app paths. Now the frontend submits explicit app selections
via ImportSkillSelection, and schema migration preserves a snapshot of
legacy app mappings to avoid lossy reconstruction.

Also adds reconciliation to sync_to_app (removes disabled/orphaned symlinks)
and MCP sync_all_enabled (removes disabled servers from live config).
2026-03-14 23:41:36 +08:00
Dex Miller f1d2c6045b fix(skill): support .skill file extension in ZIP import dialog (#1240) (#1455) 2026-03-14 22:47:07 +08:00
funnytime 9e5a3b2dc9 fix: highlight active OpenClaw provider card (#1419)
closes #1414
2026-03-14 22:45:24 +08:00
King 2466873db3 chore: remove packageManager field from package.json (#1470) 2026-03-14 22:20:41 +08:00
李悠然 3c902b4599 fix: improve the responsive design when toc title exists (#1491) 2026-03-14 21:56:37 +08:00
Jason 1582d33705 chore: bump version to v3.12.2 and add release notes 2026-03-12 23:50:33 +08:00
Jason 305c0f2e08 feat: improve empty state guidance for first-run experience
Show detailed import instructions and conditionally display common
config snippet hint for Claude/Codex/Gemini (not OpenCode/OpenClaw).
2026-03-12 23:42:15 +08:00
Jason 8e1204b1ee fix: merge Codex MCP restore backup entries during takeover
When proxy takeover is active, update_live_backup_from_provider rebuilds the Codex restore snapshot from the current provider and common-config state. We were then replacing the new mcp_servers table with the previous backup's table wholesale, which meant stopping takeover could restore stale MCP entries and silently discard MCP changes made through provider/common-config updates.

Change the backup preservation step to merge MCP entries by server id instead of replacing the entire table. New provider/common-config MCP definitions now win on conflict, while backup-only servers are retained so live-only MCP state still survives a hot-switch.

Add regression coverage for the existing preservation case and for the conflict case where both the old backup and the new provider define the same MCP server.
2026-03-12 23:15:40 +08:00
Jason 3568c98f57 fix: make Codex TOML base_url editing section-aware
Rewrite setCodexBaseUrl/extractCodexBaseUrl to understand TOML section
boundaries, ensuring base_url is written into the correct
[model_providers.<name>] section instead of being appended to file end.

- Add section-aware TOML helpers in providerConfigUtils.ts
- Extract shared update_codex_toml_field/remove_codex_toml_base_url_if
  in codex_config.rs, deduplicate proxy.rs TOML editing logic
- Replace scattered inline base_url regexes with extractCodexBaseUrl()
- Add comprehensive tests for both Rust and TypeScript implementations
2026-03-12 22:20:59 +08:00
Jason 7ca33ff901 fix: prevent common config loss during proxy takeover and stabilize snippet lifecycle
- Make sync_current_provider_for_app takeover-aware: update restore
  backup instead of overwriting live config when proxy is active
- Introduce explicit "cleared" flag for common config snippets to
  prevent auto-extraction from resurrecting user-cleared snippets
- Reorder startup: extract snippets from clean live files before
  restoring proxy takeover state
- Add one-time migration flag to skip legacy commonConfigEnabled
  migration on subsequent startups
- Add regression tests for takeover backup preservation, explicit
  clear semantics, and migration flag roundtrip
2026-03-12 17:16:22 +08:00
Jason e561084f62 Preserve common config during proxy takeover
Update takeover backup generation to rebuild effective provider settings with common config applied before saving restore snapshots.

Keep Codex mcp_servers entries when hot-switching providers under takeover so restore does not drop live-only MCP config.

Migrate legacy providers with inferred common-config usage to explicit commonConfigEnabled=true markers during startup and default imports, and cover the new behavior with proxy and provider regression tests.
2026-03-12 16:06:07 +08:00
Jason 3dad255a2a chore: bump version to v3.12.1 and add release notes 2026-03-12 00:15:05 +08:00
Jason 51825dac20 feat: add authHeader field to OpenClawProviderConfig and reuse type in form state
Add optional `authHeader` boolean to support vendor-specific auth headers
(e.g. Longcat). Refactor `resetOpenclawState` to use the shared
`OpenClawProviderConfig` type instead of an inline duplicate definition.
2026-03-11 23:56:41 +08:00
Jason ce985763f0 fix: rename OpenCode API format label from "OpenAI" to "OpenAI Responses" 2026-03-11 23:51:11 +08:00
Jason 19dca7cd2b feat: add CTok as sponsor and upgrade Gemini model to 3.1-pro 2026-03-11 23:47:08 +08:00
Jason 70632249a8 feat: add SiliconFlow as sponsor and update affiliate links
Replace SDS logos with SiliconFlow logos, add SiliconFlow sponsor entries
to all three README files (en/zh/ja), fix incorrect alt attribute, and
update all SiliconFlow provider preset apiKeyUrl to affiliate link.
2026-03-11 16:25:38 +08:00
Jason 55210d90d2 fix: update Compshare sponsor registration links to coding-plan page 2026-03-11 15:23:04 +08:00
Jason 239c6fb2d7 fix: prevent common config modal infinite reopen loop and add draft editing
The auto-open useEffect in CodexConfigEditor and GeminiConfigEditor
created an inescapable loop: commonConfigError triggered modal open,
closing the modal didn't clear the error, so the effect immediately
reopened it — locking the entire UI.

- Remove auto-open useEffect from both Codex and Gemini config editors
- Convert common config modals to draft editing (edit locally, validate
  before save) instead of persisting on every keystroke
- Add TOML/JSON pre-validation via parseCommonConfigSnippet before any
  merge operation to prevent invalid content from being persisted
- Expose clearCommonConfigError so editors can clear stale errors on
  modal close
2026-03-11 14:40:14 +08:00
Jason 4ac7e28b10 feat: add XCodeAPI as sponsor and fix incorrect alt attributes
- Add XCodeAPI sponsor entry to all three READMEs (zh, en, ja)
- Fix XCodeAPI logo alt from "Micu" to "XCodeAPI" in README_ZH.md
- Fix Crazyrouter logo alt from "AICoding" to "Crazyrouter" in all READMEs
2026-03-11 11:12:29 +08:00
Jason 47e956bb63 feat: add Micu API as sponsor and update affiliate links
Add Micu (米醋API) sponsor entry to all three README files (EN/ZH/JA)
with logo and description. Update apiKeyUrl for Micu provider presets
across claude, codex, opencode, and openclaw to use affiliate
registration link.
2026-03-11 00:14:40 +08:00
Jason 0bcbffb8a0 feat: rename UCloud provider to Compshare/优云智算 with i18n support
Add optional `nameKey` field to all preset interfaces for localized
display names. The preset selector and form now resolve `nameKey` via
i18next, falling back to `name` when unset.

- zh: 优云智算 / en+ja: Compshare
- Update model ID prefix ucloud/ → compshare/ in OpenClaw presets
- Update partner promotion copy and README sponsor descriptions
2026-03-10 23:43:23 +08:00
Jason 273a756869 fix: sync session search index with query data to refresh list after deletion
Replace useRef+useEffect async index rebuild with useMemo so the
FlexSearch index and the sessions array always reference the same data.
This ensures filtered search results update immediately when a session
is deleted via TanStack Query setQueryData.
2026-03-10 23:06:45 +08:00
Jason c2b60623a6 fix: avoid FK constraint failure when restoring provider_health during WebDAV sync
Split LOCAL_ONLY_TABLES into SYNC_SKIP_TABLES (export) and
SYNC_PRESERVE_TABLES (import). provider_health is skipped on export
but no longer restored on import, since it has a foreign key on
providers(id, app_type) that may not match the remote dataset.
Health data is ephemeral and rebuilds automatically at runtime.
2026-03-10 23:06:45 +08:00
Jason f4ad17d314 fix: align stream check toast i18n interpolation keys with translation placeholders 2026-03-10 23:06:45 +08:00
Jason 236f96b583 fix: correct X-Code API URL from www.x-code.cn to x-code.cc 2026-03-10 23:06:45 +08:00
Zhou Mengze 75b4ef2299 fix: interpolate proxy startup toast address and port (#1399)
Co-authored-by: 周梦泽 <mengze.zhou@dafeng-tech.com>
2026-03-10 21:02:13 +08:00
bigsong fab9874b2c fix: align OpenClaw tool permission profiles with upstream schema (#1355)
* fix: align OpenClaw tool permission profiles with upstream schema

* fix: remove dead i18n keys and save-blocking validation

- Remove unused `profiles.*` nested i18n keys (dead code, ToolsPanel uses flat `profileMinimal` etc.)
- Remove `invalidProfile` i18n key no longer referenced
- Remove handleSave validation that blocked saving allow/deny when legacy profile exists
- Keep the profile destructuring cleanup from the original PR

---------

Co-authored-by: Your Name <your.email@example.com>
Co-authored-by: Jason <farion1231@gmail.com>
2026-03-10 17:53:44 +08:00
liuxxxu 84668e2307 feat(openClaw form): add input type selection for models Advanced Options / 为模型高级选项添加输入类型选择 (#1368)
* feat(openClaw form): add input type selection for models Advanced Options / 为模型高级选项添加输入类型选择

* fix(i18n): add missing openclaw.inputTypes key to all locales

The new inputTypes field in OpenClawFormFields used defaultValue fallback,
causing English and Japanese users to see Chinese text.

---------

Co-authored-by: xu.liu2 <xu.liu2@brgroup.com>
Co-authored-by: Jason <farion1231@gmail.com>
2026-03-10 16:53:40 +08:00
wavever b4033fdd29 fix: add missing authHeader: true to Longcat provider preset (#1377)
Fixes issue where Longcat models were failing with 404 error due to missing
authHeader configuration. According to Longcat API documentation, this
setting is required for proper authentication.

Closes: #1376
2026-03-10 16:14:08 +08:00
hengm3467 471c0d9990 feat: add StepFun provider presets and step-3.5-flash (#1369)
* feat: add StepFun provider presets

* docs: regroup StepFun pricing entry

* docs: tweak StepFun zh label

* style: apply prettier fixes

* Revert "style: apply prettier fixes"

This reverts commit cff7bf2e65.
2026-03-10 10:27:50 +08:00
zuoliangyu a9c36381fc fix: toolbar compact mode not triggering on Windows due to left-side overflow (#1375)
The toolbar container used `justify-end` which caused content to overflow
to the left side. Browser `scrollWidth` does not account for left-side
overflow, so `useAutoCompact` could never detect it and compact mode
never activated — resulting in clipped tab labels (e.g. "aude" instead
of "Claude") at minimum window width.

Fix: remove `justify-end` from the toolbar container and use `ml-auto`
on the child element instead. This keeps the right-aligned appearance
but makes overflow go rightward, where `scrollWidth` correctly detects
it and triggers compact mode.

Co-authored-by: zuolan <zuolan1102@qq.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 09:30:52 +08:00
Jason 5c32ec58be chore: upgrade all GPT model references to gpt-5.4
GPT no longer has separate codex variants (gpt-5.x-codex), unified as
gpt-5.4. Updated ~26 references across 8 files:

- Codex provider presets: default param + 12 vendor configs
- Codex custom template default model
- Universal provider default Codex model (gpt-4o → gpt-5.4)
- OpenCode @ai-sdk/openai: consolidated 7 old models into single gpt-5.4
- OpenCode RightCode: removed gpt-5.2-codex entry
- OMO agent/category recommended models (7 references)
- Stream check default Codex model
- Universal form fallback and placeholder
- Codex form placeholder text
2026-03-09 21:26:51 +08:00
Jason 625dea9c62 test: wait for auto-sync toggle state after confirmation dialog 2026-03-09 21:11:31 +08:00
Jason 333b82b4c4 chore: bump version to v3.12.0 and update release references 2026-03-09 21:05:27 +08:00
Jason 92f62e884c docs: add v3.12.0 CHANGELOG and release notes (zh/en/ja) 2026-03-09 21:03:52 +08:00
Jason 44096b0e44 refactor: remove backup path display from OpenClaw save toasts
Backup paths are internal implementation details not actionable by users.
Simplify toast notifications to show only success/failure messages.
2026-03-09 15:00:30 +08:00
Jason 99ef870077 perf: skip backup and atomic write when OpenClaw config is unchanged 2026-03-09 12:27:32 +08:00
Jason 82438decf6 feat: add endpointCandidates for Ucloud/X-Code Claude presets and unify Ucloud apiKeyUrl 2026-03-09 11:44:42 +08:00
Jason e5838e0a10 feat: update Ucloud presets and add OpenClaw defaults for Ucloud/Micu
- Update Ucloud links to coding-plan page across READMEs
- Remove hardcoded model overrides from Claude preset
- Switch Codex model from zai-org/glm-5 to gpt-5.4
- Replace GLM-5/MiniMax models with claude-opus-4-6 in OpenClaw preset
- Add templateValues and suggestedDefaults for Ucloud and Micu OpenClaw presets
2026-03-09 11:37:23 +08:00
Jason cc15d7b1e3 feat: add OpenClaw User-Agent toggle, default off
Add a switch in the OpenClaw provider form to optionally send a browser
User-Agent header. The toggle defaults to off — only providers that
explicitly include headers in their preset or config will have it enabled.

Remove the previous auto-injection logic that force-added User-Agent on
every preset load and new provider creation.
2026-03-09 10:36:11 +08:00
Jason dd971246be feat: restore Claude provider auth field selector (AUTH_TOKEN / API_KEY) 2026-03-09 08:56:58 +08:00
Jason 55509286eb fix: rename X-Code provider to X-Code API 2026-03-09 00:10:01 +08:00
Jason 5014c2a744 feat: add X-Code partner provider preset for Claude, Codex and OpenCode
- Add X-Code provider presets with x-code.cn endpoint
- Fix ANTHROPIC_API_KEY to ANTHROPIC_AUTH_TOKEN in Claude preset
- Register x-code icon SVG in icon index
- Add partnerPromotion.x-code i18n keys for zh, en, ja locales
2026-03-09 00:06:48 +08:00
Jason 9084e1ecc8 feat: add Micu partner provider preset for Claude, Codex, OpenClaw and OpenCode
- Add Micu provider presets with openclaudecode.cn endpoint
- Register micu icon SVG in icon index with namespaced CSS classes
- Rename miku.svg to micu.svg to match icon key
- Add partnerPromotion.micu i18n keys for zh, en, ja locales
2026-03-08 23:27:23 +08:00
Jason 02669cfbac feat: add Ucloud partner provider preset for Claude, Codex and OpenClaw
- Add Ucloud provider presets with modelverse.cn API endpoint
- Register ucloud icon SVG in icon index with namespaced gradient IDs
- Add partnerPromotion.ucloud i18n keys for zh, en, ja locales
2026-03-08 23:01:35 +08:00
Jason 9092e97bc2 style: format Rust code with cargo fmt 2026-03-08 22:27:53 +08:00
Jason 032a8203fd feat: show failover toggle independently on main page with confirm dialog
Add enableFailoverToggle setting to control failover toggle visibility
on the main page, decoupled from proxy takeover state. First-time
enable shows a ConfirmDialog (same pattern as proxy toggle). The toggle
row is placed in the Auto Failover accordion section in settings.
2026-03-08 22:25:48 +08:00
Jason 6d078e7f33 feat: apply common config as runtime overlay instead of materialized merge
Common config snippets are now dynamically overlaid when writing live
files, rather than being pre-merged into provider snapshots at edit time.
This ensures that updating a snippet immediately takes effect for the
current provider and automatically propagates to other providers on
their next switch.

Key changes:
- Add write_live_with_common_config() overlay pipeline
- Strip common config from live before backfilling provider snapshots
- Normalize provider snapshots on save to keep them snippet-free
- Add explicit commonConfigEnabled flag in ProviderMeta (Option<bool>)
- Migrate legacy providers on snippet save (infer flag from subset check)
- Add Codex TOML snippet validation in set_common_config_snippet
- Stabilize onConfigChange callbacks with useCallback in ProviderForm
2026-03-08 21:45:20 +08:00
Jason fc6f2af4c6 style: format code with prettier 2026-03-08 21:45:05 +08:00
Jason c54515742f fix: comprehensive i18n audit - add 69 missing keys and fix hardcoded Chinese
- Add 69 missing translation keys to zh/en/ja (usage, proxy, sessionManager,
  deeplink, codexConfig, openclaw, circuitBreaker, streamCheck, etc.)
- Replace 15 hardcoded Chinese strings in CircuitBreakerConfigPanel with t() calls
- Fix ColorPicker component to use i18n for default label
- Add i18n interpolation params to ProxyToggle tooltip translations
- All three language files synchronized at 1838 keys
2026-03-08 20:41:44 +08:00
Jason 7dbceeafe6 feat: add confirmation dialog for WebDAV auto-sync toggle
Show a one-time traffic warning when users first enable auto-sync,
persisted via autoSyncConfirmed flag in settings.
2026-03-08 20:10:45 +08:00
Jason 31bfecde39 fix: correct i18n key paths for model test panel title and description 2026-03-08 19:54:46 +08:00
Jason 41c3f845cb refactor: consolidate periodic maintenance timer and add vacuum/rollup
Change periodic timer from hourly backup-only to daily maintenance that
includes backup, incremental auto-vacuum, and usage rollup in a single
pass.
2026-03-08 19:42:18 +08:00
Jason c0737f2cfe feat: add dual-layer versioning to WebDAV sync (protocol v2 + db-v6)
Separate protocol version from database compatibility version in WebDAV
sync paths. Upload writes to v2/db-v6/<profile>, download falls back to
legacy v2/<profile> when current path has no data. Extend manifest with
optional dbCompatVersion field and add legacy layout detection to UI.
2026-03-08 19:42:18 +08:00
Jason bf40b0138c feat: add usage daily rollups, incremental auto-vacuum, and sync-aware backup
- Add usage_daily_rollups table (schema v6) to aggregate proxy request
  logs into daily summaries, reducing query overhead for statistics
- Add rollup_and_prune DAO that aggregates old detail logs (>N days)
  into rollup rows and deletes the originals
- Update all usage stats queries to UNION detail logs with rollup data
- Introduce incremental auto-vacuum for SQLite, with startup and
  periodic cleanup of old stream_check_logs and request log rollups
- Split backup export/import into full vs sync variants: WebDAV sync
  now skips local-only table data (proxy_request_logs,
  stream_check_logs, provider_health, proxy_live_backup,
  usage_daily_rollups) while preserving them on import
- Add enable_logging guard to skip request log writes when disabled
- Apply cargo fmt formatting fixes across multiple modules
2026-03-08 19:42:18 +08:00
Jason 3f711d6504 fix: add missing /v1 path to SSSAiCode default endpoint for Codex and OpenCode 2026-03-08 19:42:18 +08:00
Jason 8c3f18a9bd feat: add session deletion with per-provider cleanup and path safety
Add delete_session Tauri command dispatching to provider-specific deletion
logic for all 5 providers (Claude, Codex, Gemini, OpenCode, OpenClaw).
Includes path traversal protection via canonicalize + starts_with validation,
session ID verification against file contents, frontend confirmation dialog
with optimistic cache updates, i18n keys (zh/en/ja), and component tests.
2026-03-08 19:42:18 +08:00
Jason e18db31752 feat: add partner badge for SiliconFlow provider presets 2026-03-08 19:42:18 +08:00
Jason c0fe0d6e07 fix: normalize JSON5 slash escaping and add i18n for OpenClaw panels
- Fix json-five output unescaping forward slashes (\/ → /)
- Add structured error codes for env validation (EMPTY, INVALID_JSON, OBJECT_REQUIRED)
- Add i18n keys (zh/en/ja) for health warnings, tool profiles, env editor hints,
  and agents legacy timeout migration
- Update env validation test to match new error codes
2026-03-08 19:42:18 +08:00
Jason 7e6f803035 feat: overhaul OpenClaw config panels with JSON5 round-trip write engine
- Add json-five crate for JSON5 serialization preserving comments and formatting
- Rewrite openclaw_config.rs with comment-preserving JSON5 read/write engine
- Add Tauri commands: get_openclaw_live_provider, write_openclaw_config_section
- Redesign EnvPanel as full JSON editor with structured error handling
- Add tools.profile selection (minimal/coding/messaging/full) to ToolsPanel
- Add legacy timeout migration support to AgentsDefaultsPanel
- Add OpenClawHealthBanner component for config validation warnings
- Add supporting hooks, mutations, utility functions, and unit tests
2026-03-08 19:42:18 +08:00
Jason b4fdd5fc0d fix: remove www prefix from aicoding.sh provider URLs 2026-03-08 19:42:18 +08:00
Jason 1573474e3a Fix proxy forwarder failure logs 2026-03-08 19:42:18 +08:00
Jason 50a2bd29e6 fix: correct OpenAI ChatCompletion to Anthropic Messages streaming conversion
Rewrite tool call handling in streaming format conversion to properly
track multiple concurrent tool blocks with independent Anthropic content
indices. Fix block interleaving (thinking/text/tool_use) with correct
content_block_start/stop events, buffer tool arguments until both id and
name are available, and add tool result message conversion in transform.
2026-03-08 19:41:29 +08:00
Jason 11f70f676e refactor: deduplicate and improve OpenAI Responses API conversion
- Extract shared map_responses_stop_reason and build_anthropic_usage_from_responses into transform_responses.rs as pub(crate)
- Align cache token extraction priority: OpenAI nested details as fallback, direct Anthropic fields as override
- Extract resolve_content_index helper to eliminate 3x copy-paste in streaming_responses.rs
- Add streaming reasoning/thinking event handlers (response.reasoning.delta/done)
- Add explanatory comment to transform_response heuristic detection
- Add openai_responses to api_format doc comment and needs_transform test
- Add explicit no-op match arms for lifecycle events
- Add promptCacheKey to TS ProviderMeta type
- Update toast i18n key to be generic for both OpenAI formats (zh/en/ja)
2026-03-08 19:41:29 +08:00
Jason a30e2096bb feat: add OpenAI Responses API format conversion (api_format = "openai_responses")
Support Anthropic ↔ OpenAI Responses API format conversion alongside existing
Chat Completions conversion. The Responses API uses a flat input/output structure
with lifted function_call/function_call_output items and named SSE lifecycle events.
2026-03-08 19:41:29 +08:00
wugeer fb8996d19c fix:Add a new vendor page, API endpoint, and model name. (#1155)
* fix:Add a new vendor page, API endpoint, and model name. Fix the bug where, after entering characters, line breaks cannot be fully deleted.

* fix: add missing i18n key codexConfig.modelNameHint for zh/en/ja

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-03-07 22:53:44 +08:00
Fan 33d5f6985d fix: skills count not displaying when adding (#1295)
* fix: skills count not displaying when adding

* fix: get real skill count by awaiting discovery after adding repo

The previous approach computed count before discovery, so it was always 0.
Now we await refetchDiscoverable() after the mutation, then filter the
fresh skills list to get the actual count for the toast message.

Also reverts the SkillRepo.count field — keep the interface clean since
count is a transient UI concern, not a data model property.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-03-07 21:59:33 +08:00
Sube 95a74020e1 fix: align outline button text tone with usage refresh control (#1222)
Co-authored-by: zhangluguang <z397503810@gmail.com>
2026-03-07 21:17:33 +08:00
Bowen Han 078a81b867 feat: add extra field display in UsageFooter component for normal mode (#1137) 2026-03-07 21:16:43 +08:00
Mr.XYS a89f433dde fix: fix the issue of missing token statistics for cache hits in streaming responses (#1244) 2026-03-07 21:15:48 +08:00
Keith Yu 8217bfff50 feat: add Bedrock request optimizer (PRE-SEND thinking + cache injection) (#1301)
* feat: add Bedrock request optimizer (PRE-SEND thinking + cache injection)

Add a PRE-SEND request optimizer that enhances Bedrock API requests
before forwarding, complementing the existing POST-ERROR rectifier system.

New modules:
- thinking_optimizer: 3-path model detection (adaptive/legacy/skip)
  - Opus 4.6/Sonnet 4.6: adaptive thinking + effort max + 1M context beta
  - Legacy models: inject extended thinking with max budget
  - Haiku: skip (no modification)
- cache_injector: auto-inject cache_control breakpoints (max 4)
  - Injects at tools/system/assistant message positions
  - TTL upgrade for existing breakpoints (5m → 1h)

Gate: only activates for Bedrock providers (CLAUDE_CODE_USE_BEDROCK=1)
Config: stored in SQLite settings table, default OFF, user opt-in
UI: new Optimizer section in RectifierConfigPanel with 3 toggles + TTL

18 unit tests covering all paths. Verified against live Bedrock API.

* chore: remove docs/plans directory

* fix: address code review findings for Bedrock request optimizer

P0 fixes:
- Replace hardcoded Chinese with i18n t() calls in optimizer panel,
  add translation keys to zh/en/ja locale files
- Fix u64 underflow: max_tokens - 1 → max_tokens.saturating_sub(1)
- Move optimizer from before retry loop to per-provider with body
  cloning, preventing Bedrock fields leaking to non-Bedrock providers

P1 fixes:
- Replace .map() side-effect pattern with idiomatic if-let (clippy)
- Fix module alphabetical ordering in mod.rs
- Add cache_ttl whitelist validation in set_optimizer_config
- Remove #[allow(unused_assignments)] and dead budget decrement

---------

Co-authored-by: Keith (via OpenClaw) <keithyt06@users.noreply.github.com>
Co-authored-by: Jason <farion1231@gmail.com>
2026-03-07 18:57:21 +08:00
Suki 27d21c23ac Add Bailian For Coding preset configuration (#1263)
问题描述
bailian 模块使用的请求地址  https://dashscope.aliyuncs.com/apps/anthropic  仅适用于普通订阅用户,订阅 code 的用户调用该地址会无法正常使用

修改内容
增加bailian For Coding模块提供给 code 订阅用户:
正确地址:  https://coding.dashscope.aliyuncs.com/apps/anthropic 

测试验证
测试环境:本地搭建 ccswitch 运行环境,使用 code 订阅的阿里云 DashScope 账号
测试步骤:
  1. 修改地址前:调用 bailian 接口提示请求失败/无权限
  2. 修改地址后:成功调用接口,返回正常响应结果
影响范围:仅增加bailian For Coding模块,未改动其他逻辑,不影响非 code 订阅用户的使用
2026-03-04 23:49:14 +08:00
Tsukumi 0135abde1c fix: support codex /responses/compact route (#1194) 2026-03-04 23:47:38 +08:00
Jason 3d33f299a8 docs: add UCloud CompShare as sponsor partner 2026-03-04 23:23:27 +08:00
Jason 083e48bf8c fix: use structural TOML merge/subset for Codex common config snippet
The text-based approach (string append + substring matching) failed to
detect already-merged snippets when config.toml was reformatted by
external tools (MCP sync, Codex CLI). Replace with smol-toml parse/
stringify + existing deepMerge/isSubset/deepRemove for correct
structural operations. Falls back to text matching on parse failure.
2026-03-04 23:01:40 +08:00
Jason d35c2962b9 style: format ProviderList.tsx 2026-03-04 23:01:40 +08:00
Jason 4e0f9d9552 feat: replace text inputs with dropdown selects for OpenClaw agent model config
- Add useOpenClawModelOptions hook to aggregate models from all configured OpenClaw providers
- Replace read-only primary model display with a searchable Select dropdown
- Replace comma-separated fallback text input with add/remove Select rows
- Filter out already-selected models from fallback options
- Show "(not configured)" marker for values whose provider has been deleted
- Unify terminology: rename "主模型/Primary Model" to "默认模型/Default Model"
2026-03-04 23:01:40 +08:00
Jason 7d4ffa9872 feat: add model role badges and reorder presets to prioritize Opus
- Add Primary/Fallback badge to each model card in OpenClaw form
- Update modelsHint to explain model ordering semantics
- Reorder 11 aggregator/third-party presets to put Opus first
2026-03-04 23:01:40 +08:00
Jason b3dda16b3a fix: remove HTTP status code display from endpoint speed test
The status code from a simple GET request reflects route matching,
not actual endpoint availability. Users only need latency and
reachability info, which the latency number already conveys.
2026-03-04 23:01:40 +08:00
Jason 07568286fc feat: add first-run confirmation dialog for stream check
Show an informational dialog when users first click the health check
button, explaining its limitations (OAuth providers, relay services,
Bedrock). The dialog persists the confirmation in settings so it only
appears once per device.
2026-03-04 23:01:40 +08:00
Jason 377c736aad fix: support openai_chat api_format in stream check
Stream Check always used Anthropic Messages API format, causing false
failures for providers with api_format="openai_chat" (e.g. NVIDIA).
Now detects api_format from provider meta/settings_config and uses
the correct endpoint (/v1/chat/completions) and headers accordingly.
2026-03-04 23:01:40 +08:00
Jason 2dcec4178d feat: restore model health check (stream check) UI
Re-enable the stream check feature that was hidden in v3.11.0.
All backend code, database schema, and i18n keys were preserved;
only the frontend UI needed uncommenting across 4 files.
OpenCode and OpenClaw are excluded as the backend does not support them.
2026-03-04 23:01:40 +08:00
Alex b05234c6df feat(providers): add Novita presets and icon across supported apps (#1192) 2026-03-04 22:57:12 +08:00
YewFence af68d4549b fix: 修复最小化到托盘后应用过一段时间自动退出的问题 (#1245)
ExitRequested 事件处理器无条件执行清理并调用 std::process::exit(0),
导致 api.prevent_exit() 被完全抵消。当隐藏窗口的 WebView 被 Windows
后台优化策略回收、窗口对象销毁后,Tauri 运行时检测到无存活窗口自动
触发 ExitRequested,应用随即退出。

通过 ExitRequested 的 code 字段区分两种场景:
- code 为 None(运行时自动触发):仅 prevent_exit(),保持托盘后台运行
- code 为 Some(_)(用户主动 app.exit()):执行清理后退出

Closes #728
2026-03-03 16:14:50 +08:00
Jason c772874dcb docs: reorganize docs directory structure
- Delete 9 completed planning/roadmap documents
- Move 23 release notes into docs/release-notes/ with simplified filenames
- Update all cross-references in READMEs, CHANGELOG, and release notes
- Remove dangling doc reference in deeplink/mod.rs
2026-03-03 09:28:48 +08:00
Jason d5d7b3190d docs: remove cross-language links from user manual sections in READMEs 2026-03-03 08:48:52 +08:00
Jason 0c78b38295 docs: add user manual links to all three README files 2026-03-03 08:43:57 +08:00
Jason bbed2a1fe1 docs: restructure user manual for i18n and add EN/JA translations
Reorganize docs/user-manual/ from flat structure to language subdirectories
(zh/, en/, ja/) with shared assets/. Move existing Chinese docs into zh/,
fix image paths, add multilingual navigation README, and translate all 23
markdown files (~4500 lines each) to English and Japanese.
2026-03-03 08:40:52 +08:00
Jason ce9c23833a docs: add OpenClaw coverage and complete settings docs for user manual
- Add OpenClaw as the 5th supported app across all doc chapters (1-3, 5)
- Add OpenClaw provider presets table to 2.1-add.md (30 presets)
- Add OpenClaw config section to 5.1-config-files.md (JSON5 format)
- Complete 1.5-settings.md with missing sections: app visibility,
  skill sync method, terminal settings, proxy tab, WebDAV cloud sync,
  backup/restore, and log configuration
- Fix deeplink parser.rs to accept 'opencode' and 'openclaw' app types
- Update 5.3-deeplink.md with new app type parameters
- Remove incorrect OpenCode references from proxy docs (4.1-4.4)
2026-03-02 23:16:58 +08:00
Jason 2eca90e43a feat: auto-extract common config snippets from live files on first run
During app startup, iterate all app types and extract non-provider-specific
config fields from live configuration files into the database. This runs
only when no snippet exists yet for a given app type, enabling incremental
extraction as new apps are configured.
2026-03-02 11:47:36 +08:00
Jason 4b0f14e2e6 docs: sync README features across EN/ZH/JA
Add format conversion, per-provider proxy granularity, and
symlink/file-copy support to EN and JA to match ZH updates.
2026-03-02 11:30:04 +08:00
Jason 83fe3402c2 chore: bump version to v3.11.1 and add release notes 2026-02-28 16:12:50 +08:00
Jason c75311e14e fix: pass app interpolation param to proxy takeover toast messages
The i18next t() calls for proxy.takeover.enabled/disabled were missing
the `app` interpolation parameter, causing {{app}} placeholders in
translation strings to render literally instead of showing the app name.
2026-02-28 15:47:08 +08:00
Jason 35a4a15898 fix: restore flex-1 on toolbarRef to fix compact mode exit
After moving ProxyToggle/FailoverToggle outside toolbarRef, the flex-1
class was accidentally left only on the outer wrapper. Without flex-1,
toolbarRef.clientWidth reflects content width instead of available space,
causing useAutoCompact's exit condition to never trigger.
2026-02-28 15:33:15 +08:00
Jason fd836ce70d fix: let "follow system" theme auto-update by delegating to Tauri's native theme tracking
Pass "system" to set_window_theme instead of explicitly detecting dark/light,
so Tauri uses window.set_theme(None) and the WebView's prefers-color-scheme
media query stays in sync with the real OS theme.
2026-02-28 14:50:51 +08:00
Jason d5e4e8d133 refactor: move proxy toggle into panel and surface app takeover options
Move the proxy on/off switch from the accordion header into the panel
content area, placing it right above the app takeover section. This
ensures users see the takeover options immediately after enabling the
proxy, preventing the common pitfall of running the proxy without
actually taking over any app.

- Simplify accordion trigger to standard style with Badge only
- Add AnimatePresence animation for takeover section reveal
- Remove duplicate takeover switches from running info card
- Update stoppedDescription i18n to reference "above toggle"
- Add proxy.takeover.hint key in zh/en/ja
2026-02-28 09:13:32 +08:00
Jason f8c1f1736e fix: disable env check and one-click install on Windows to prevent protocol handler side effects 2026-02-28 00:12:12 +08:00
Jason 859f413756 revert: restore full config overwrite + Common Config Snippet (revert 992dda5c)
Revert the partial key-field merging refactoring introduced in 992dda5c,
along with two dependent commits (24fa8a18, 87604b18) that referenced
the now-removed ClaudeQuickToggles component.

The whitelist-based partial merge approach had critical issues:
- Non-whitelisted custom fields were lost during provider switching
- Backfill permanently stripped non-key fields from the database
- Whitelist required constant maintenance to track upstream changes

This restores the proven "full config overwrite + Common Config Snippet"
architecture where each provider stores its complete configuration and
shared settings are managed via a separate snippet mechanism.

Reverted commits:
- 24fa8a18: context-aware JSON editor hint + hide quick toggles
- 87604b18: hide ClaudeQuickToggles when creating
- 992dda5c: partial key-field merging refactoring

Restored:
- Full config snapshot write (write_live_snapshot) for Claude/Codex/Gemini
- Full config backfill (settings_config = live_config)
- Common Config Snippet UI and backend commands
- 6 frontend components/hooks for common config editing
- configApi barrel export and DB snippet methods

Removed:
- ClaudeQuickToggles component
- write_live_partial / backfill_key_fields / patch_claude_live
- All KEY_FIELDS constants
2026-02-27 23:12:34 +08:00
Jason b2b20dadd7 fix: add import button for OpenCode/OpenClaw empty state and remove auto-import on startup
Previously OpenCode and OpenClaw auto-imported providers from live config
on app startup, which could confuse users. Now they follow the same
pattern as Claude/Codex/Gemini: manual import via the empty state button.
2026-02-27 11:50:38 +08:00
Jason 3bd0a7c02c docs: highlight Common Config Snippet removal as breaking change in release notes
Expand the partial key-field merging section with Before/After explanation
and migration guide. Mark it as a breaking change in Highlights and Notes
sections across all three languages (zh/en/ja) and CHANGELOG.md.
2026-02-27 00:03:22 +08:00
Jason ac23328119 chore: bump version to v3.11.0 and add release notes
- Update version numbers in package.json, Cargo.toml, tauri.conf.json
- Add CHANGELOG.md entry for v3.11.0
- Add trilingual release notes (zh/en/ja)
- Update user manual version info
2026-02-26 23:13:59 +08:00
Jason 0c4a8d0569 fix: use local time instead of UTC for backup file names 2026-02-26 22:14:37 +08:00
Jason 01cc766a05 feat: add delete backup functionality with confirmation dialog 2026-02-26 22:06:10 +08:00
Jason 3590df68b8 fix: treat missing db file as error in manual backup to prevent false success toast
backup_database_file() returning Ok(None) was silently resolved as null
on the frontend, bypassing try/catch and showing a success toast without
actually creating a backup file. Now None is converted to an explicit
Err so the frontend correctly displays an error toast.
2026-02-26 21:53:59 +08:00
Jason 54876612b3 feat: show silent startup option only when launch on startup is enabled
Add conditional rendering with animated transition for the silent startup
toggle, so it only appears when the launch on startup option is checked.
2026-02-26 21:25:14 +08:00
Jason 3348b39089 fix: restore API Key input visibility when creating new Claude providers
The hasApiKeyField() gate added for Bedrock AKSK/API Key distinction
was incorrectly hiding the API Key input for all new providers with
empty env config. Scope the gate to cloud_provider category only.
2026-02-26 21:19:49 +08:00
Jason 99e392518a fix: remove outdated partner status from Zhipu GLM presets 2026-02-26 21:04:53 +08:00
Jason 201527c9d9 fix: merge duplicate openclaw i18n keys to restore provider form translations
JSON does not support duplicate keys — the second `openclaw` object was
silently overwriting the first, causing all provider form field translations
(providerKey, apiProtocol, baseUrl, models, etc.) to be lost at runtime.
2026-02-26 20:43:39 +08:00
Jason 924f38ebe1 fix: remove last-provider deletion restriction for OMO/OMO Slim plugins
OMO and OMO Slim are OpenCode plugins, not standalone apps — users
should be able to fully remove them. Remove the count-based guard that
prevented deleting the last active provider, and clean up the now-unused
provider-count API surface across the full stack.
2026-02-26 20:27:04 +08:00
Jason e7766d4d22 refactor: remove OMO common config two-layer merge system
Each OMO provider now stores its complete configuration directly in
settings_config.otherFields instead of relying on a shared OmoGlobalConfig
merged at write time. This simplifies the data flow from a 4-tuple
(agents, categories, otherFields, useCommonConfig) to a 3-tuple and
eliminates an entire DB table, two Tauri commands, and ~1700 lines of
merge/sync code across frontend and backend.

Backend:
- Delete database/dao/omo.rs (OmoGlobalConfig struct + get/save methods)
- Remove get/set_config_snippet from settings DAO
- Remove get/set_common_config_snippet Tauri commands
- Replace merge_config() with build_config() in services/omo.rs
- Simplify OmoVariant (remove config_key, known_keys)
- Simplify import_from_local and build_local_file_data
- Rewrite all OMO service tests

Frontend:
- Delete OmoCommonConfigEditor.tsx and OmoGlobalConfigFields.tsx
- Delete src/lib/api/config.ts
- Remove OmoGlobalConfig type and merge preview functions
- Remove useGlobalConfig/useSaveGlobalConfig query hooks
- Simplify useOmoDraftState (remove all common config state)
- Replace OmoCommonConfigEditor with read-only JsonEditor preview
- Clean i18n keys (zh/en/ja)
2026-02-26 19:31:43 +08:00
Jason 3e9815f5d2 chore: add .worktrees/ to .gitignore 2026-02-26 19:15:54 +08:00
Jason 082cb0327d fix: enforce OMO ↔ OMO Slim cross-category mutual exclusion
When activating an OMO provider, deactivate all OMO Slim providers
in the same transaction and delete the Slim config file, and vice
versa. This prevents both plugin variants from being active
simultaneously.
2026-02-26 18:08:46 +08:00
Jason 55e21c3c19 fix: invalidate OMO Slim query cache after provider mutations
OMO Slim queries (["omo-slim", ...]) were not invalidated alongside
OMO queries, causing stale UI state when switching/adding/deleting
OMO Slim providers.
2026-02-26 17:51:50 +08:00
Jason 3e2c8c12a5 fix: sync OMO agent/category recommended models with upstream sources
Regular agents & categories: align with oh-my-opencode model-requirements.ts
fallback chains (oracle→gpt-5.2, librarian→gemini-3-flash, etc.)

Slim agents: derive from Regular's design philosophy — match each agent
to its functional counterpart's first-choice model instead of using
the outdated Slim defaults. Also fix provider/model format to pure
model IDs for suffix matching compatibility.
2026-02-26 17:39:08 +08:00
Jason 90cb8db16b fix: add toast feedback for OMO "Fill Recommended" button silent failures 2026-02-26 16:02:18 +08:00
Jason 2b30819510 chore: pre-release cleanup — remove debug logs, fix clippy warning, add missing ja translations, and format code
- Remove 2 console.log statements from DeepLinkImportDialog
- Fix clippy unnecessary_map_or: use is_some_and in live.rs
- Add 17 missing Japanese i18n keys (skills, proxy, circuitBreaker, universalProvider)
- Run prettier and cargo fmt to fix pre-existing formatting drift
2026-02-26 15:11:13 +08:00
Jason 434392a669 perf: optimize session panel loading with parallel scan and head-tail JSONL reading
- Parallelize 5 provider scans using std::thread::scope
- Add read_head_tail_lines() to read only first 10 + last 30 lines from JSONL files, skipping potentially large middle sections
- Cache Codex UUID regex with LazyLock to avoid repeated compilation
- Skip expensive I/O in OpenCode when session title is already available
2026-02-26 11:16:04 +08:00
Jason 24fa8a18ef fix: show context-aware JSON editor hint and hide quick toggles for non-active providers
The hint text and ClaudeQuickToggles were misleading when editing
non-current providers or creating new ones, since the editor only
contains a config snippet rather than the full live settings.json.
2026-02-26 09:55:09 +08:00
Jason 87604b1809 fix: hide ClaudeQuickToggles when creating a new provider
The quick toggles (hide AI attribution, extended thinking, teammates
mode) patch the live config of the currently active provider, which
is incorrect during provider creation. Only show them in edit mode.
2026-02-26 09:32:51 +08:00
Jason 47435bd647 chore: update Claude model references from 4.5 to 4.6 in provider presets
Update Sonnet and Opus model IDs/names to 4.6 across Claude, OpenClaw,
and OpenCode provider preset configurations. OPENCODE_PRESET_MODEL_VARIANTS
(SDK model catalog) is intentionally left unchanged.
2026-02-25 23:25:41 +08:00
Jason 73ca8340bb feat: add SSAI Code partner provider presets, i18n, icon, and fix models
Add SSAI Code as a partner provider across all five apps with endpoint,
API key URL, and partner promotion config. Rename brand from SSSAiCode
to SSAI Code. Rename sssaicoding.svg to sssaicode.svg and register icon.
Add trilingual promotion text for $10 bonus credit. Add missing models
arrays in OpenClaw presets for CrazyRouter and SSAI Code.
2026-02-25 22:21:15 +08:00
Jason 31712f076f feat: add CrazyRouter partner provider presets, i18n, and register icons
Add CrazyRouter as a partner provider across all five apps with endpoint,
API key URL, and partner promotion config. Add trilingual promotion text
for the 30% bonus credit offer. Register aicoding and crazyrouter icons
in the icon index. Fix indentation in openclawProviderPresets.
2026-02-25 15:39:50 +08:00
Jason a254304a00 feat: add AICoding partner provider presets and i18n promotion text
Add AICoding as a partner provider across all five apps (Claude, Codex,
Gemini, OpenClaw, OpenCode) with endpoint, API key URL, and partner
promotion configuration. Add trilingual (zh/en/ja) promotion text for
the first top-up discount.
2026-02-24 23:08:22 +08:00
Jason e516f83c19 fix(test): add ResizeObserver polyfill and fix WebDAV accordion target in settings test 2026-02-24 22:28:41 +08:00
Jason b98c3ddb29 fix: add #[cfg(target_os = "windows")] to WSL helper functions to eliminate dead_code warnings 2026-02-24 22:28:41 +08:00
Jason bb3130cbe0 fix(opencode): add missing omo-slim category checks across add/form/mutation paths
Several code paths only checked for "omo" category but missed "omo-slim",
causing OMO Slim providers to be treated as regular OpenCode providers
(triggering invalid write_live_snapshot, requiring manual provider key,
and showing wrong form fields).
2026-02-24 22:28:41 +08:00
Keith Yu 8ea9638b9d feat: Add AWS Bedrock Provider Support (AKSK & API Key) (#1047)
* Add AWS Bedrock provider integration design document

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

* Add AWS Bedrock provider implementation plan

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

* Update implementation plan: add OpenCode Bedrock support

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

* feat: add cloud_provider category to ProviderCategory type

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

* feat: add AWS Bedrock (AKSK) Claude Code provider preset with tests

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

* feat: add AWS Bedrock (API Key) Claude Code provider preset with tests

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

* feat: add AWS Bedrock OpenCode provider preset with @ai-sdk/amazon-bedrock

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

* docs: add AWS Bedrock provider feature summary for PR

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

* chore: remove internal planning documents

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

* docs: add AWS Bedrock support to README (EN/ZH/JA)

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

* Add AWS Bedrock UI merge design document

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

* Add AWS Bedrock UI merge implementation plan

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

* feat: skip optional template values in validation

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

* feat: support isSecret template fields and hide base URL for Bedrock

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

* feat: add Bedrock validation, cleanup, and isBedrock prop in ProviderForm

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

* feat: extend TemplateValueConfig and merge Bedrock presets

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

* fix: mask Bedrock API Key as secret and support GovCloud regions

- Add isSecret: true to BEDROCK_API_KEY template value
- Update region regex to support multi-segment regions (us-gov-west-1)

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

* style: replace AWS icon with updated logo

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

* style: replace AWS icon with updated logo

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

* style: replace AWS icon with new PNG image

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

* fix: address code review findings

- Fix AWS icon: use SVG with embedded <image> instead of raw <img> tag
- Hide duplicate ApiKeySection for Bedrock (auth via template fields only)
- Guard settingsConfig cleanup against unresolved template placeholders

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

* chore: remove planning documents

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

* refactor: address PR review - split Bedrock into two presets, restore SVG icon

Based on maintainer review feedback on PR #1047:

1. Split merged "AWS Bedrock" back into two separate presets:
   - "AWS Bedrock (AKSK)": uses AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY
   - "AWS Bedrock (API Key)": uses top-level apiKey field via standard UI input

2. Restore aws.svg to pure vector SVG (was PNG-in-SVG)

3. Remove all Bedrock-specific logic from shared components:
   - Remove isBedrock prop from ClaudeFormFields
   - Remove Bedrock validation/cleanup blocks from ProviderForm
   - Remove optional/isSecret from TemplateValueConfig
   - Remove optional skip from useTemplateValues

4. Add cloud_provider category handling:
   - Skip API Key/Base URL required validation
   - Hide Speed Test and Base URL for cloud_provider
   - Hide API format selector for cloud_provider (always Anthropic)
   - Show API Key input only when config has apiKey field

5. Fix providerConfigUtils to support top-level apiKey:
   - getApiKeyFromConfig: check config.apiKey before env fields
   - setApiKeyInConfig: write to config.apiKey when present
   - hasApiKeyField: detect top-level apiKey property

6. Add OpenClaw Bedrock preset (bedrock-converse-stream protocol)

7. Update model IDs:
   - Sonnet: global.anthropic.claude-sonnet-4-6
   - Opus: global.anthropic.claude-opus-4-6-v1
   - Haiku: global.anthropic.claude-haiku-4-5-20251001-v1:0

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

* fix(test): align Bedrock API Key test assertions with preset implementation

The API Key preset was refactored to use standard UI input (apiKey: "")
instead of template variables, but the tests were not updated accordingly.

---------

Co-authored-by: root <root@ip-10-0-11-189.ap-northeast-1.compute.internal>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Jason <farion1231@gmail.com>
2026-02-24 21:11:18 +08:00
Jason e1e2bdef2a fix(about): show update badge instead of green check when newer version available 2026-02-24 10:23:18 +08:00
Jason c380528a27 feat(workspace): make directory paths clickable and rename "Today's Note" to "Add Memory"
Add open_workspace_directory Tauri command to open workspace/memory dirs
in the system file manager. Rename dailyMemory.createToday across all locales.
2026-02-24 09:45:10 +08:00
Jason a8dbea1398 feat(workspace): add full-text search for daily memory files
Add backend search command that performs case-insensitive matching
across all daily memory files, supporting both date and content queries.
Frontend includes animated search bar (⌘F), debounced input, snippet
display with match count badge, and search state preservation across
edits.
2026-02-24 09:03:30 +08:00
Jason 7138aca310 feat(preset): update domestic model providers to latest versions
- MiniMax: M2.1 → M2.5
- Zhipu GLM: glm-4.7 → glm-5
- BaiLing: Ling-1T → Ling-2.5-1T
- DouBaoSeed: doubao-seed-code-preview-latest → doubao-seed-2-0-code-preview-latest
- Qwen (Bailian): qwen3-max → qwen3.5-plus
2026-02-23 22:39:42 +08:00
Jason Young 992dda5c5c refactor(provider): switch from full config overwrite to partial key-field merging (#1098)
* refactor(provider): switch from full config overwrite to partial key-field merging

Replace the provider switching mechanism for Claude/Codex/Gemini from
full settings_config overwrite to partial key-field replacement, preserving
user's non-provider settings (plugins, MCP, permissions, etc.) across switches.

- Add write_live_partial() with per-app implementations for Claude (JSON env
  merge), Codex (auth replace + TOML partial merge), and Gemini (env merge)
- Add backfill_key_fields() to extract only provider-specific fields when
  saving live config back to provider entries
- Update switch_normal, sync_current_to_live, add, update to use partial merge
- Remove common config snippet feature for Claude/Codex/Gemini (no longer
  needed with partial merging); preserve OMO common config
- Delete 6 frontend files (3 components + 3 hooks), clean up 11 modified files
- Remove backend extract_common_config_* methods, 3 Tauri commands,
  CommonConfigSnippets struct, and related migration code
- Update integration tests to validate key-field-only backfill behavior

* refactor(cleanup): remove dead code and redundant MCP sync after partial-merge refactor

- Remove ConfigService legacy full-overwrite sync methods (~150 lines)
- Remove redundant McpService::sync_all_enabled from switch_normal
- Switch proxy fallback recovery from write_live_snapshot to write_live_partial
- Remove dead ProviderService::write_gemini_live wrapper
- Update tests to reflect partial-merge behavior (MCP preserved, not re-synced)

* feat(claude): add Quick Toggles for common Claude Code preferences

Add checkbox toggles for hideAttribution, alwaysThinking, and
enableTeammates that write directly to the live settings file via
RFC 7396 JSON Merge Patch. Mirror changes to the form editor using
form.watch for reactive updates.

* fix(provider): add missing key fields to partial-merge constants

Add provider-specific fields verified against official docs to prevent
key residue or loss during provider switching:

- Claude: CLAUDE_CODE_SUBAGENT_MODEL (env), model (top-level)
- Codex: review_model, plan_mode_reasoning_effort
- Gemini: GOOGLE_API_KEY (official alternative to GEMINI_API_KEY)

* fix(provider): expand partial-merge key fields for Bedrock, Vertex, Foundry and behavior settings

Add missing env/top-level fields to CLAUDE_KEY_ENV_FIELDS and
CLAUDE_KEY_TOP_LEVEL so that provider switching correctly replaces
(and clears) credentials and flags for AWS Bedrock, Google Vertex AI,
Microsoft Foundry, and provider behavior overrides like max output
tokens and prompt caching.

* feat(provider): add auth field selector for Claude providers (AUTH_TOKEN / API_KEY)

Allow users to choose between ANTHROPIC_AUTH_TOKEN and ANTHROPIC_API_KEY
when creating or editing custom Claude providers, persisted in meta.apiKeyField.

* refactor(preset): remove AiHubMix hardcoded API_KEY in favor of generic auth selector

AiHubMix was the only preset that hardcoded ANTHROPIC_API_KEY before the
generic auth field selector was introduced. Now that users can freely
choose between AUTH_TOKEN and API_KEY via the UI, remove the special-case
and default AiHubMix to the standard ANTHROPIC_AUTH_TOKEN.
2026-02-23 21:57:04 +08:00
Jason 1b20b7ff88 feat(backup): add hourly periodic backup timer during runtime
Previously periodic backup only checked on startup. Now spawns a
tokio interval task that checks every hour while the app is running.
2026-02-23 11:27:28 +08:00
Jason f8820aa22c feat(backup): add independent backup panel, configurable policy, and rename support
Extract backup & restore into a standalone AccordionItem in Advanced settings.
Add configurable auto-backup interval (disabled/6h/12h/24h/48h/7d) and retention
count (3-50) via settings. Add per-backup rename with inline editing UI.
2026-02-23 11:27:28 +08:00
Jason 3afec8a10f feat(backup): add pre-migration backup, periodic backup, backfill warning, and backup management UI
Four improvements to the database backup mechanism:

1. Auto backup before schema migration - creates a snapshot when
   upgrading from an older database version, providing a safety net
   beyond the existing SAVEPOINT rollback mechanism.

2. Periodic startup backup - checks on app launch whether the latest
   backup is older than 24 hours and creates a new one if needed,
   ensuring all users have recent backups regardless of usage patterns.

3. Backfill failure notification - switch now returns SwitchResult with
   warnings instead of silently ignoring backfill errors, so users are
   informed when their manual config changes may not have been saved.

4. Backup management UI - new BackupListSection in Settings > Data
   Management showing all backup snapshots with restore capability,
   including a confirmation dialog and automatic safety backup before
   restore.
2026-02-23 11:27:28 +08:00
Jason 5ebc879f09 feat(settings): add first-run confirmation dialogs for proxy and usage features
Prevent accidental activation of advanced features by showing a one-time
info dialog. Once confirmed, the flag is persisted in settings.json and
the dialog never appears again.

- Proxy: confirmation when toggling proxy server ON for the first time
- Usage: confirmation when enabling usage query inside UsageScriptModal
- Enhanced ConfirmDialog with "info" variant (blue icon + default button)
- Added i18n translations for zh, en, ja
2026-02-23 11:27:28 +08:00
Jason 6b4ba64bbd feat(toolbar): add smooth transition animation for AppSwitcher compact toggle
Replace conditional rendering with always-rendered span driven by CSS
max-width + opacity animation. Add time-lock in useAutoCompact to prevent
ResizeObserver flicker during expand animation.
2026-02-23 11:27:28 +08:00
Jason 5763b9094b fix(toolbar): remove height constraint that clipped AppSwitcher
The toolbar wrapper's fixed h-[32px] was smaller than AppSwitcher's
natural 40px height (32px buttons + 8px padding), causing visual
clipping. Removed the constraint and let flex layout handle sizing
within the 64px header.
2026-02-23 11:27:28 +08:00
Jason ce92f37ef0 feat(toolbar): auto-compact AppSwitcher based on available width
Replace hardcoded app count threshold with ResizeObserver-based
detection. Uses a two-layer layout (overflow-hidden outer + shrink-0
inner) to avoid the compact/normal oscillation problem.
2026-02-23 11:27:28 +08:00
Jason 2e676e5f53 feat(sessions): add session browsing for Gemini CLI 2026-02-23 11:27:28 +08:00
Jason c3f29a62d1 feat(sessions): default filter to current app when entering session page
Navigate directly to the active app's sessions instead of showing all.
2026-02-23 11:27:28 +08:00
Jason 165af5eec4 feat(sessions): add session browsing for OpenCode and OpenClaw
Add two new session providers following the existing convention-based
pattern. OpenCode reads three-layer JSON storage, OpenClaw parses JSONL
event streams. Wire up backend dispatch, frontend filter dropdown, icon
mappings, toolbar button for OpenClaw, and i18n subtitle updates.
2026-02-23 11:27:28 +08:00
Jason 8b9c09d994 feat(toolbar): add fade transition when switching between OpenClaw and other apps 2026-02-23 11:27:28 +08:00
Jason a8d391bd74 refactor(settings): split Data accordion into Import/Export and Cloud Sync 2026-02-23 11:27:28 +08:00
Jason 7d9b20721e refactor(settings): split Advanced tab into Proxy tab and move Pricing to Usage
Extract proxy-related accordion items (Local Proxy, Failover, Rectifier,
Global Outbound Proxy) into a dedicated Proxy tab via ProxyTabContent
component. Move Pricing config panel to UsageDashboard as a collapsible
accordion. This reduces SettingsPage from ~716 to ~426 lines and improves
settings discoverability with a 5-tab layout: General | Proxy | Advanced |
Usage | About.
2026-02-23 11:27:28 +08:00
Kelvin Chiu d11df17b5d feat: more granular local environment checks (#870)
* feat: more granular local environment checks

* refactor: improve PR #870 with i18n, shadcn Select, and testable helpers

- Extract is_valid_shell, is_valid_shell_flag, default_flag_for_shell
  to module-level #[cfg(windows)] functions for testability
- Add unit tests for extracted helper functions
- Replace native <select> with shadcn/ui Select components
- Extract env badge ternary to ENV_BADGE_CONFIG Record lookup
- Add i18n keys for env badges and WSL selectors (zh/en/ja)
- Unify initial useEffect load path with loadAllToolVersions()

* fix: prevent useEffect re-firing on wslShellByTool changes

The useEffect that loads initial tool versions depended on
loadAllToolVersions, which in turn depended on wslShellByTool.
This caused a full re-fetch of all 4 tools every time the user
changed a WSL shell or flag, racing with the single-tool refresh.

Fix: use empty deps [] since this is a mount-only effect. The
refresh button and shell/flag handlers cover subsequent updates.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-02-23 11:26:23 +08:00
Jason 4c88174cb0 refactor(provider): replace startup auto-import with manual import button
Remove the startup loop in lib.rs that auto-imported default providers
for Claude/Codex/Gemini. Move config snippet extraction logic into the
import_default_config command so it works when triggered manually.

Add an "Import Current Config" button to ProviderEmptyState, wired via
useMutation in ProviderList (shown only for standard apps). Update i18n
keys (zh/en/ja) with new button labels and revised empty state text.
2026-02-20 22:01:18 +08:00
Jason 5a72888852 fix(query): remove auto-import side effect from useProvidersQuery queryFn
Users now trigger provider import manually via the empty state button,
keeping queryFn pure and preventing unintended imports on mount/refocus.
2026-02-20 21:57:45 +08:00
Jason 54f1bfb5d0 chore(tray): hide Auto Failover shortcut from tray menu
The Auto (Failover) toggle in the system tray is no longer shown.
The feature remains fully functional via the Settings page.
All related backend code (handle_auto_click, AUTO_SUFFIX, etc.)
is preserved for easy re-enablement.
2026-02-20 20:08:54 +08:00
Jason 4efab15174 refactor(openclaw): make primary model read-only in Agents panel
The primary model field in the Agents defaults panel now displays as
read-only, eliminating the duplicate edit entry with the "Set as Default
Model" button on provider cards. Fallback models and runtime parameters
remain editable.
2026-02-20 16:46:02 +08:00
Jason 357d32c17e fix(i18n): clarify OpenClaw default model button labels
Rename "Enable/Default" to "Set Default/Current Default" across
zh/en/ja locales and widen button to fit longer text.
2026-02-20 11:11:10 +08:00
Jason 7532308519 fix(workspace): sort daily memory by date and inline into file grid
- Sort daily memory list by filename (YYYY-MM-DD.md) instead of mtime
  so editing an older file no longer bumps it to the top
- Move daily memory card inline with workspace MD file buttons
- Shorten card description across all locales
- Defer file creation until user actually saves (no empty file on create)
2026-02-20 10:40:58 +08:00
Jason 4440a14082 chore(ui): exclude OpenClaw from MCP & Skills app toggle lists 2026-02-20 10:40:48 +08:00
Jason d1bb4480db feat(workspace): add daily memory file management for OpenClaw
Add browse, edit, create and delete support for daily memory files
(~/.openclaw/workspace/memory/YYYY-MM-DD.md) in the Workspace panel.
2026-02-20 08:54:53 +08:00
Jason d04c279890 chore(ui): hide proxy/pricing config for OpenCode/OpenClaw providers 2026-02-19 23:34:20 +08:00
Jason 3125b5419c chore(ui): hide stream check / model test config panels
The stream check feature is unreliable due to diverse provider request
formats. Comment out the model test config UI in settings page, provider
advanced config, and the test button in provider actions. Backend code
and i18n keys are preserved for future restoration.
2026-02-19 23:19:44 +08:00
Jason 0fa6b33b5e feat(settings): add enableLocalProxy toggle to gate main page proxy UI
New users often accidentally trigger ProxyToggle/FailoverToggle on the
main page. Add a settings toggle (default off) so the proxy controls
only appear when explicitly enabled. The proxy service start/stop in
settings remains independent of this visibility flag.
2026-02-19 23:06:22 +08:00
Jason 1b71dc721c refactor(omo): deduplicate OMO/OMO Slim via OmoVariant parameterization
Introduce OmoVariant struct with STANDARD/SLIM constants to eliminate
~250 lines of copy-pasted code across DAO, service, commands, and
frontend layers. Adding a new OMO variant now requires only a single
const declaration instead of duplicating ~400 lines.
2026-02-19 21:11:58 +08:00
Jason 8e219b5eb1 feat(omo): add OMO Slim (oh-my-opencode-slim) support
Implement full OMO Slim profile management to align with ai-toolbox:
- Backend: Slim service methods, DAO, Tauri commands, plugin conflict handling
- Frontend: types, API, query hooks, form integration with isSlim parameterization
- Slim variant: 6 agents (no categories), separate config file and plugin name
- Mutual exclusion: standard OMO and Slim cannot coexist as plugins
- i18n: zh/en/ja translations for all Slim agent descriptions
2026-02-19 20:47:55 +08:00
Jason 51476953ae style: apply prettier formatting to App, SettingsPage, useSettings 2026-02-18 23:40:31 +08:00
Jason 0f4ce74916 refactor(forms): extract OpenCode/OMO/OpenClaw state from ProviderForm into dedicated hooks
Split ProviderForm.tsx (2227 → 1526 lines) by extracting:
- opencodeFormUtils.ts: pure functions and default config constants
- useOmoModelSource: OMO model source collection from OpenCode providers
- useOpencodeFormState: OpenCode provider form state and handlers
- useOmoDraftState: OMO profile draft editing state
- useOpenclawFormState: OpenClaw provider form state and handlers
2026-02-18 23:36:36 +08:00
SaladDay 9514d08ef6 fix(settings): normalize SQL import/export dark-mode card (#1067) 2026-02-17 22:52:00 +08:00
Jason adaef3522d fix(ui): add vertical spacing between directory settings sections
Replace React Fragment with a div using space-y-6 to add proper
vertical spacing between the app config directory and directory
override sections in Settings > Advanced > Directory Settings.
2026-02-17 21:55:10 +08:00
Jim Northrup 4c8334c6fd fix: Don't add ?beta=true to OpenAI Chat Completions endpoints (#1052)
Fixes Nvidia provider and other providers using apiFormat="openai_chat".

The ClaudeAdapter::build_url() method was incorrectly adding ?beta=true
to both /v1/messages and /v1/chat/completions endpoints. This caused
the Nvidia provider to fail because:

1. Nvidia uses apiFormat="openai_chat"
2. Requests are transformed to OpenAI format and sent to /v1/chat/completions
3. The URL gets ?beta=true appended (Anthropic-specific parameter)
4. Nvidia's API rejects requests with this parameter

Fix:
- Only add ?beta=true to /v1/messages endpoint
- Exclude /v1/chat/completions from getting this parameter

Tested:
- Anthropic /v1/messages still gets ?beta=true ✓
- OpenAI Chat Completions /v1/chat/completions does NOT get ?beta=true ✓
- All 13 Claude adapter tests pass ✓

Co-authored-by: jnorthrup <jnorthrup@example.com>
2026-02-16 22:53:08 +08:00
Jason 6caf843843 docs: sync SSSAiCode sponsor update across all README languages 2026-02-16 21:34:43 +08:00
Jason 6c38a8fd24 docs: add SSSAiCode sponsor across all README languages 2026-02-16 00:10:38 +08:00
Jason 977813f725 docs: sync Crazyrouter sponsor update across all README languages 2026-02-15 23:47:40 +08:00
JIA-ss 11f1ef33e4 feat(ui): add quick config toggles to Claude config editor (#1012)
Add 3 quick-toggle checkboxes above the JSON editor in Claude provider settings:
- Hide AI Attribution (sets attribution.commit/pr to empty string)
- Extended Thinking (sets alwaysThinkingEnabled to true)
- Teammates Mode (sets env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS to "1")

Uses local state to keep toggles and JsonEditor in sync without
triggering ProviderForm re-renders. Includes i18n for zh/en/ja.

Co-authored-by: Jason <farion1231@gmail.com>
2026-02-15 22:10:40 +08:00
SaladDay 20f62bf4f8 feat(webdav): follow-up 补齐自动同步与大文件防护 (#1043)
* feat(webdav): add robust auto sync with failure feedback

(cherry picked from commit bb6760124a62a964b36902c004e173534910728f)

* fix(webdav): enforce bounded download and extraction size

(cherry picked from commit 7777d6ec2b9bba07c8bbba9b04fe3ea6b15e0e79)

* fix(webdav): only show auto-sync callout for auto-source errors

* refactor(webdav): remove services->commands auto-sync dependency
2026-02-15 20:58:17 +08:00
Dex Miller 508aa6070c Fix/skill zip symlink resolution (#1040)
* fix(skill): resolve symlinks in ZIP extraction for GitHub repos (#1001)

- detect symlink entries via is_symlink() during ZIP extraction and collect target paths

- add resolve_symlinks_in_dir() to copy symlink target content into link location

- canonicalize base_dir to fix macOS /tmp → /private/tmp path comparison issue

- add path traversal safety check to block symlinks pointing outside repo boundary

- apply symlink resolution to both download_and_extract and extract_local_zip paths

Closes https://github.com/farion1231/cc-switch/issues/1001

* fix(skill): change search to match name and repo instead of description

* feat(skill): support importing skills from ~/.agents/skills/ directory

- Scan ~/.agents/skills/ in scan_unmanaged() for skill discovery
- Parse ~/.agents/.skill-lock.json to extract repo owner/name metadata
- Auto-add discovered repos to skill_repos management on import
- Add path field to UnmanagedSkill to show discovered location in UI

Closes #980

* fix(skill): use metadata name or ZIP filename for root-level SKILL.md imports (#1000)

When a ZIP contains SKILL.md at the root without a wrapper directory,
the install name was derived from the temp directory name (e.g. .tmpDZKGpF).
Now falls back to SKILL.md frontmatter name, then ZIP filename stem.

* feat(skill): scan ~/.cc-switch/skills/ for unmanaged skill discovery and import

* refactor(skill): unify scan/import logic with lock file skillPath and repo saving

- Deduplicate scan_unmanaged and import_from_apps using shared source list
- Replace hand-written AppType match with as_str() and AppType::all()
- Extract read_skill_name_desc, build_repo_info_from_lock, save_repos_from_lock helpers
- Add SkillApps::from_labels for building enable state from source labels
- Parse skillPath from .skill-lock.json for correct readme URLs
- Save skill repos to skill_repos table in both import and migration paths

* fix(skill): resolve symlink and path traversal issues in ZIP skill import

* fix(skill): separate source path validation and add canonicalization for symlink safety
2026-02-15 20:57:14 +08:00
makoMako 7b20c17ea4 fix(opencode): 补齐 install.sh 安装路径检测 (#988)
补齐 OpenCode 路径扫描来源(按官方 install.sh 优先级):
  OPENCODE_INSTALL_DIR > XDG_BIN_DIR > ~/bin > ~/.opencode/bin
保留并增强 Go 安装路径扫描(~/go/bin、GOPATH/*/bin)。

区分单值环境变量(push_env_single_dir)与 path-list 环境变量
(extend_from_path_list),避免对 OPENCODE_INSTALL_DIR 等单值
变量误用 split_paths。

增加路径去重逻辑(push_unique_path),避免重复扫描。

增加跨平台可执行候选逻辑(tool_executable_candidates):
  Windows: .cmd / .exe / 裸命令
  Unix:    裸命令

将 PATH 拼接提至外层循环,减少重复 syscall。

增加单元测试覆盖路径拼装、去重及 Windows 候选顺序。

Closes #958

Co-authored-by: Warp <agent@warp.dev>
2026-02-14 22:35:20 +08:00
Jason 5a17a67b8b fix: deduplicate OpenCodeModel import after rebase 2026-02-14 15:32:17 +08:00
Jason dca12b9f7d feat(openclaw): add 13 new provider presets
Migrate missing providers from Claude/Codex/Gemini/OpenCode presets:

Tier 1 Partners:
- RightCode (anthropic-messages)
- AICodeMirror (anthropic-messages)
- Zhipu GLM en (openai-completions, international)
- MiniMax en (openai-completions, international)

Tier 2 Chinese Officials:
- Kimi For Coding, KAT-Coder, Longcat, DouBaoSeed,
  BaiLing, Xiaomi MiMo

Tier 3 Aggregators:
- SiliconFlow, SiliconFlow en, Nvidia
2026-02-14 15:32:17 +08:00
Jason f974d203a8 fix(openclaw): remove /v1 from anthropic-messages provider baseUrls
Anthropic SDK auto-appends /v1 to baseUrl, so including it in the
preset causes double-path (/v1/v1/messages). Affects AiHubMix, DMXAPI,
PackyCode, Cubence, and AIGoCode.
2026-02-14 15:32:17 +08:00
Jason 44ba9468b5 refactor(openclaw): move model detail fields into advanced options
Keep only model ID and display name visible by default,
collapse context window, max tokens, reasoning, and cost
fields into the advanced options section.
2026-02-14 15:32:17 +08:00
Jason 5081206176 fix(openclaw): address code review findings across P0-P3 issues
- Add 25 missing i18n keys for OpenClawFormFields in all 3 locales (P0)
- Replace key={index} with stable crypto.randomUUID() keys in EnvPanel,
  ToolsPanel, and OpenClawFormFields to prevent list state bugs (P1)
- Exclude openclaw from ProxyToggle/FailoverToggle in App.tsx (P1)
- Add merge_additive_config() for openclaw/opencode deep link imports (P1)
- Normalize serde(flatten) field naming to `extra` + HashMap (P2)
- Add directory existence check in remove_openclaw_provider_from_live (P2)
- Remove dead code in import_default_config and openclaw API methods (P2)
- Add duplicate key validation in EnvPanel before save (P2)
- Add openclawConfigDir to Settings type (P2)
- Add staleTime to OpenClaw query hooks (P3)
- Fix type-unsafe delete via destructuring in mutations.ts (P3)
2026-02-14 15:32:17 +08:00
Jason 00b424628f refactor(openclaw): migrate config panels to TanStack Query hooks
Centralize query keys and extract reusable hooks (useOpenClaw.ts),
replacing manual useState/useEffect load/save patterns in Env, Tools,
and AgentsDefaults panels for consistency with MCP/Skills modules.
2026-02-14 15:32:17 +08:00
Jason bc87f9d9eb fix(openclaw): address code review findings for robustness
- Fix EnvPanel visibleKeys using entry key name instead of array index
  to prevent visibility state corruption after deletion
- Add NaN guard in AgentsDefaultsPanel numeric field parsing
- Validate provider id and models before importing from live config
- Upgrade import failure log level from debug to warn for OpenCode/OpenClaw
2026-02-14 15:32:17 +08:00
Jason eccb95b83d fix(openclaw): enable scrolling on config panels
Add overflow-y-auto to main content area so OpenClaw panels
(Env, Tools, Agents) can scroll when content exceeds viewport.
2026-02-14 15:32:17 +08:00
Jason 2b1f0f0f7e feat(openclaw): add Env/Tools/Agents config panels
- Migrate OpenClaw commands from provider.rs to dedicated commands/openclaw.rs
- Add backend types and read/write for env, tools, agents.defaults sections
- Create EnvPanel (API key + custom vars KV editor)
- Create ToolsPanel (profile selector + allow/deny lists)
- Create AgentsDefaultsPanel (default model + runtime parameters)
- Extend App.tsx menu bar with Env/Tools/Agents buttons
- Remove Prompts button for OpenClaw (overlaps with Workspace AGENTS.md)
2026-02-14 15:32:17 +08:00
Jason 9035784aa4 feat(openclaw): extend workspace files with HEARTBEAT/BOOTSTRAP/BOOT
Add 3 new markdown files to the workspace whitelist and frontend grid:
- HEARTBEAT.md: activity runlist
- BOOTSTRAP.md: first-run ritual
- BOOT.md: gateway restart checklist

Update i18n for all 3 locales (zh, en, ja).
2026-02-14 15:32:17 +08:00
Jason a61892e46a style: format appConfig array to multi-line 2026-02-14 15:32:17 +08:00
Jason 4f2812f472 feat(openclaw): show only Workspace button in menu bar
Hide Skills, Prompts, Sessions, and MCP buttons when OpenClaw is active,
as it only needs Workspace file management functionality.
2026-02-14 15:32:17 +08:00
Jason 705cc8a5af feat(openclaw): add Workspace Files panel for managing bootstrap md files
Add a dedicated panel to read/write OpenClaw's 6 workspace bootstrap files
(AGENTS.md, SOUL.md, USER.md, IDENTITY.md, TOOLS.md, MEMORY.md) directly
from ~/.openclaw/workspace/, with a whitelist-secured backend and Markdown
editor UI. Also fix prompt auto-import missing OpenCode/OpenClaw and the
PromptFormPanel filenameMap type exclusion.
2026-02-14 15:32:17 +08:00
Jason 182015264c fix(openclaw): add openclaw to all Record<AppId, T> usages
Expand McpApps interface, APP_IDS, APP_ICON_MAP, enabledCounts
initializers, and test mock data to include the openclaw key,
resolving TypeScript errors after AppId union was extended.
2026-02-14 15:31:59 +08:00
Jason a33f8fe973 perf: remove unnecessary query cache for Tauri local IPC
Tauri IPC calls are in-process (microsecond latency), so the 5-minute
staleTime and disabled refetchOnWindowFocus from web app templates are
counterproductive. Set staleTime to 0 and enable refetchOnWindowFocus
so external config changes are reflected immediately.
2026-02-14 15:31:59 +08:00
Jason f1fbe324d1 feat(openclaw): add default model button and fix sessionsApi export
- Add "Enable as Default" button to OpenClaw provider cards
- Place enable button before add/remove button for better UX
- Disable remove button when provider is set as default
- Add sessionsApi re-export from api barrel file to fix white screen
- Add i18n keys for default model feature (zh/en/ja)
2026-02-14 15:31:59 +08:00
Jason 26a2fc4fe0 fix(openclaw,opencode): correct Opus pricing and upgrade to Opus 4.6
- Fix Opus pricing from $15/$75 (Opus 4 price) to $5/$25 in openclaw presets
- Upgrade model ID from claude-opus-4-5-20251101 to claude-opus-4-6
- Update all suggestedDefaults references (fallbacks + modelCatalog)
- Apply same model upgrade in opencode presets (7 providers)
2026-02-14 15:31:59 +08:00
Jason 02f9f2e3b8 feat(openclaw): register suggested models to allowlist on provider add
When adding an OpenClaw provider with suggestedDefaults, automatically
merge its model catalog into the allowlist and set the default model
if not already configured.
2026-02-14 15:31:58 +08:00
Jason c431a86064 fix(openclaw): update button state and toast message after switch
Add cache invalidation for openclawLiveProviderIds in useSwitchProviderMutation
to ensure button state updates correctly after adding/removing providers.

Also fix toast message to show "已添加到配置" for OpenClaw (same as OpenCode).
2026-02-14 15:31:58 +08:00
Jason 46ab15f9f6 style: apply code formatting 2026-02-14 15:31:58 +08:00
Jason 7b2cf66812 feat(openclaw): add providerKey input field with validation
- Add providerKey input field in ProviderForm for OpenClaw
- Implement duplicate key detection by querying existing providers
- Add format validation (lowercase letters, numbers, hyphens only)
- Disable field in edit mode (key cannot be changed after creation)
- Update mutations.ts to support OpenClaw providerKey
- Add i18n translations for zh/en/ja
2026-02-14 15:31:58 +08:00
Jason 227f08e910 fix(openclaw): pass providerKey in AddProviderDialog submit handler
The providerKey was only being passed for opencode, causing openclaw
provider creation to fail with "Provider key is required" error.
2026-02-14 15:31:58 +08:00
Jason 392344e1e9 fix(openclaw): prevent creating default provider on first launch
Add additive mode guard in import_default_config() to skip OpenCode
and OpenClaw apps, which should use their dedicated import functions.
2026-02-14 15:31:58 +08:00
Jason 3e58e65284 fix(openclaw): update API protocol values in provider presets
Update anthropic -> anthropic-messages to match OpenClaw gateway config
2026-02-14 15:31:58 +08:00
Jason 512f22e83a feat(openclaw): add provider form fields and UI components
- Add OpenClawFormFields component for provider configuration
- Add Collapsible UI component (radix-ui dependency)
- Update ProviderForm with OpenClaw-specific handlers and preset logic
- Extend OpenClawModel type with reasoning, input, maxTokens fields
- Exclude OpenClaw from universal provider tab in AddProviderDialog
2026-02-14 15:31:58 +08:00
Jason 715e9e89c4 feat(openclaw): add additive mode frontend support
- Add getOpenClawLiveProviderIds() API for querying live config
- Update ProviderList to query OpenClaw live IDs
- Rename isOpenCodeMode to isAdditiveMode (covers OpenCode + OpenClaw)
- Update ProviderCard shouldAutoQuery and isActiveProvider logic
- Update App.tsx onRemoveFromConfig and invalidateQueries for OpenClaw
2026-02-14 15:31:58 +08:00
Jason 47f2c47a2f feat(openclaw): add agents.defaults config support
- Add types for default model config (primary + fallbacks)
- Add types for model catalog/allowlist with aliases
- Extend OpenClawModelEntry with cost and contextWindow fields
- Add Tauri commands: get/set_openclaw_default_model, get/set_openclaw_model_catalog
- Create frontend API (src/lib/api/openclaw.ts)
- Add suggestedDefaults to provider presets with model metadata
- Add i18n translations (zh/en/ja) for openclawConfig.*
2026-02-14 15:31:58 +08:00
Jason 52db7941ea fix(ui): update OpenClaw icon in icon index
Replace old pixel-art style icon with new gradient lobster icon
to match the SVG added in 2dad4729.
2026-02-14 15:31:58 +08:00
Jason 27bcfcb2b8 fix(ui): add OpenClaw to app switcher
Add "openclaw" to ALL_APPS array so OpenClaw appears in the main
interface app switcher when enabled in visibility settings.
2026-02-14 15:31:58 +08:00
Jason 9bbb6c51ff feat(ui): add OpenClaw brand icon and component 2026-02-14 15:31:58 +08:00
Jason 5c62c47878 chore(openclaw): remove dead code functions from openclaw_config
Remove 6 unused functions marked with #[allow(dead_code)]:
- get_openclaw_skills_dir: Skills not supported
- get_env_vars/set_env_var: Environment vars unused
- get_mcp_servers/set_mcp_server/remove_mcp_server: MCP not supported

OpenClaw integration only requires provider management functionality.
2026-02-14 15:31:58 +08:00
Jason 95391f19ac fix(tests): add mcp_servers table to v4 migration test fixture
Also includes OpenClaw icon that was added in previous commits.
2026-02-14 15:31:58 +08:00
Jason 28b125b34f fix(openclaw): remove MCP/Skills/Prompts support from OpenClaw
OpenClaw only needs provider management functionality, not MCP, Skills,
or Prompts features. This commit removes the incorrectly added support:

- Revert SCHEMA_VERSION from 6 to 5 (remove v5->v6 migration)
- Remove enabled_openclaw field from mcp_servers and skills tables
- Remove openclaw field from McpApps and SkillApps structs
- Update DAO queries to exclude enabled_openclaw column
- Fix frontend components and types to exclude openclaw from MCP/Prompts
- Update all related test files
2026-02-14 15:31:58 +08:00
Jason d56e0b0344 feat(i18n): add OpenClaw translations
- Add "openclaw": "OpenClaw" to apps translations in zh.json
- Add "openclaw": "OpenClaw" to apps translations in en.json
- Add "openclaw": "OpenClaw" to apps translations in ja.json
2026-02-14 15:31:58 +08:00
Jason fedb08e846 feat(ui): add OpenClaw support to frontend components
- Update App.tsx with openclaw visibility and skills fallback
- Add OpenClaw to AppSwitcher icon and display name maps
- Update McpFormModal with openclaw in enabled apps
- Update PromptFormModal/Panel with openclaw filename map
- Update EndpointSpeedTest with openclaw timeout
- Update AppVisibilitySettings with openclaw toggle
- Update test state with openclaw defaults
2026-02-14 15:31:58 +08:00
Jason 545be56698 feat(presets): add OpenClaw provider presets
- Create openclawProviderPresets.ts with provider templates
- Include Chinese officials (DeepSeek, Zhipu, Qwen, Kimi, MiniMax)
- Include aggregators (AiHubMix, DMXAPI, OpenRouter, ModelScope)
- Include third party partners (PackyCode, Cubence, AIGoCode)
- Include OpenAI Compatible custom template
2026-02-14 15:31:58 +08:00
Jason 31ec5d73a6 feat(types): add OpenClaw TypeScript type definitions
- Add OpenClawProviderConfig and OpenClawModel interfaces
- Add openclaw to McpApps, VisibleApps, ProxyTakeoverStatus
- Add "openclaw" to AppId union type
- Add openclaw to SkillApps interface
2026-02-14 15:31:58 +08:00
Jason 6952360f70 feat(backend): add OpenClaw support to commands and deeplinks
- Register openclaw_config module in lib.rs
- Add OpenClaw commands and provider import on startup
- Add OpenClaw branches to config and provider commands
- Add build_openclaw_settings() for deeplink imports
- Update MCP handlers with openclaw field in McpApps
- Add OpenClaw prompt file path
2026-02-14 15:31:58 +08:00
Jason e85878e95a feat(services): add OpenClaw branches to backend services
- Add OpenClaw branches to proxy service (not supported)
- Add OpenClaw to MCP service (skip sync, MCP still in development)
- Add OpenClaw skills directory path
- Update ProxyTakeoverStatus with openclaw field
- Add OpenClaw to stream check (not supported)
2026-02-14 15:31:58 +08:00
Jason 433c86b2d3 feat(provider): add OpenClaw provider service support
- Add import_openclaw_providers_from_live() function
- Add remove_openclaw_provider_from_live() function
- Update write_live_snapshot() for OpenClaw
- Add openclaw fields to VisibleApps and AppSettings
- Add get_openclaw_override_dir() function
2026-02-14 15:31:58 +08:00
Jason 63fafd6608 feat(openclaw): add OpenClaw configuration module
- Create openclaw_config.rs for reading/writing OpenClaw config
- Support JSON5 format (~/.openclaw/openclaw.json)
- Implement provider CRUD operations for additive mode
- Add json5 dependency to Cargo.toml
2026-02-14 15:31:58 +08:00
Jason 7f46a0b910 feat(core): add OpenClaw to AppType enum and database schema
- Add OpenClaw variant to AppType enum
- Update is_additive_mode() to return true for OpenClaw
- Update McpApps, SkillApps, McpRoot, PromptRoot structs
- Add database migration v5 to v6 for enabled_openclaw columns
- Update mcp_servers and skills table definitions
2026-02-14 15:31:38 +08:00
Dex Miller 9c34d04def fix(mcp): add missing OpenCode checkbox in MCP add/edit form (#1026)
Fixes https://github.com/farion1231/cc-switch/issues/1020
2026-02-14 15:29:54 +08:00
clx 6098fa7536 Webdav (#923)
* feat: WebDAV backup/restore

- Add WebDAV test/backup/restore commands and settings\n- Fix ja i18n missing keys; decode PROPFIND href as UTF-8\n- Stabilize Windows prompt auto-import tests via CC_SWITCH_TEST_HOME

* chore: format and minor cleanups

* fix: update build config

* feat(webdav): unify sync UX and hardening fixes

* fix(webdav): harden sync flow and stabilize sync UX/tests

* fix(webdav): add resource limits to skills.zip extraction

Prevent zip bomb / resource exhaustion by enforcing:
- MAX_EXTRACT_ENTRIES (10,000 files)
- MAX_EXTRACT_BYTES (512 MB cumulative)

* refactor(webdav): drop deviceId and display deviceName only

---------

Co-authored-by: small-lovely-cat <77799160+small-lovely-cat@users.noreply.github.com>
Co-authored-by: saladday <1203511142@qq.com>
2026-02-14 15:24:24 +08:00
Jason 721771bfe5 docs: add Crazyrouter as sponsor across all READMEs 2026-02-13 23:13:33 +08:00
Jason 1ecc0fff30 docs: update MiniMax sponsor to M2.5 across all READMEs 2026-02-13 22:47:26 +08:00
Jason b0a177725d fix: remove partner status from Zhipu GLM presets 2026-02-13 22:22:24 +08:00
ThendCN 2edee31638 fix(linux): disable WebKitGTK hardware acceleration to prevent white screen (#986)
On some Linux systems with AMD GPUs (e.g., AMD Cezanne/Radeon Vega),
WebKitGTK's GPU process fails to initialize EGL, causing the app to
show a white screen on startup.

Root cause: `amdgpu_query_info(ACCEL_WORKING)` returns EACCES (-13),
which causes EGL display creation to fail with EGL_BAD_PARAMETER,
crashing the GPU process.

Fix: Use WebKitGTK's `set_hardware_acceleration_policy(Never)` API to
disable GPU acceleration on Linux, falling back to software rendering.
This is applied at startup via Tauri's `with_webview` API.

Co-authored-by: Naozhong AI <oursnoah@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 22:53:33 +08:00
Dex Miller 62fa5213bf feat(proxy): fix thinking rectifiers and resolve clippy warnings (#1005)
* feat(proxy): align thinking rectifiers and resolve clippy warnings

- add thinking budget rectifier flow with single retry on anthropic budget errors

- align thinking signature rectification behavior with adaptive-safe handling

- expose requestThinkingBudget in settings/ui/i18n and default rectifier config to disabled

- fix clippy warnings in model_mapper format args and RectifierConfig default derive

* fix(proxy): thinking rectifiers
2026-02-12 22:28:05 +08:00
Dex Miller caba5f51ec feat(omo): improve agent model selection UX and fix lowercase keys (#1004)
* fix(omo): use lowercase keys for builtin agent definitions

OMO config schema expects all agent keys to be lowercase.
Updated OMO_BUILTIN_AGENTS keys (Sisyphus → sisyphus, Hephaestus →
hephaestus, etc.) and aligned Rust test fixtures accordingly.

* feat(omo): add i18n support and tooltips for agent/category descriptions

* feat(omo): add preset model variants for thinking level support

Add OPENCODE_PRESET_MODEL_VARIANTS constant with variant definitions
for Google, OpenAI, and Anthropic models. The omoModelVariantsMap
builder now falls back to presets when config-defined variants are
absent, enabling the variant selector for supported models.

* feat(omo): replace model select with searchable combobox and improve fallback handling

* feat(omo): enrich preset model defaults and metadata fallback

* fix(omo): preserve custom fields and align otherFields import/validation

* fix: resolve omo clippy warnings and include app update
2026-02-12 21:30:59 +08:00
Jason e349012abc docs: add Right Code as sponsor across all READMEs 2026-02-09 22:48:32 +08:00
Jason 594e0d52f7 docs: update sponsor from Zhipu GLM to MiniMax across all READMEs 2026-02-09 22:31:56 +08:00
Jason 11404d4d96 fix(ui): only show session manager button for Claude and Codex apps
Session manager backend only supports Claude and Codex providers.
Hide the nav button for Gemini/OpenCode with animated transition,
and auto-fallback to providers view when switching apps.
2026-02-09 22:12:54 +08:00
Dex Miller 0fcb1b01e2 docs: add user manual documentation (#979)
* docs: add user manual documentation

Add comprehensive user manual covering getting started, provider management,
extensions (MCP/prompts/skills), proxy configuration, and FAQ sections.
Includes screenshots and a README index.

* fix(docs): align user manual with v3.10.3 codebase

- Add OpenCode as 4th supported app throughout all docs
- Fix proxy default port 15762 → 15721
- Update Claude presets (9 → 26), Codex (3 → 10), Gemini (3 → 7)
- Add OpenCode presets (25 entries)
- Fix timeout defaults and ranges (stream first byte 60s/90s, etc.)
- Fix circuit breaker defaults with per-app values (Claude vs general)
- Fix Skills support: all 4 apps, not just Claude/Codex
- Remove non-existent Gemini authMode field
- Fix prompt deletion behavior: enabled prompts cannot be deleted
- Remove non-existent Legacy deeplink protocol, use V1 only
- Fix DB table names (usage_logs → proxy_request_logs) and add missing tables
- Fix migration version v3.8.0 → v3.7.0
- Add missing V1 deeplink parameters (config, configFormat, etc.)
- Update doc version v3.9.1 → v3.10.3
- Add claude-opus-4-1 to pricing table
- Fix recovery wait time range 10-300 → 0-300

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-02-09 15:01:15 +08:00
Dex Miller ea20b0aec2 fix(skill): correct skill doc URL branch and path resolution (#977)
Use the actual branch returned by download_repo instead of the
configured branch, fixing 404s when repos default to master but
the URL was hardcoded to main. Also switch URL format from /tree/
to /blob/ and always point to the SKILL.md file.

Closes farion1231/cc-switch#968
2026-02-09 12:30:17 +08:00
Dex Miller ed47480fc7 feat(omo): integrate Oh My OpenCode profile management (#972)
* feat(omo): integrate Oh My OpenCode profile management into Provider system

Adds full-stack OMO support: backend config read/write/import, OMO-specific
provider CRUD with exclusive switching, frontend profile editor with
agent/category/model configuration, global config management, and i18n support.

* feat(omo): add model/variant dropdowns from enabled providers

Replace model text inputs with Select dropdowns sourced from enabled
OpenCode providers, add thinking-level variant selection, and prevent
auto-enabling newly added OMO providers.

* fix(omo): use standard provider action styles for OMO switch button

* fix(omo): replace hardcoded isZh strings with proper i18n t() calls
2026-02-09 12:18:20 +08:00
644 changed files with 133176 additions and 16020 deletions
+2
View File
@@ -0,0 +1,2 @@
custom:
- https://github.com/farion1231/cc-switch/blob/main/README_ZH.md#%E2%9D%A4%EF%B8%8F%E8%B5%9E%E5%8A%A9%E5%95%86
+97
View File
@@ -0,0 +1,97 @@
name: "🐛 Bug Report / Bug 报告"
description: |
Report errors or unexpected behavior.
报告错误或异常行为。
labels:
- bug
body:
- type: checkboxes
attributes:
label: Self Checks / 自检
options:
- label: |
I have read the [FAQ](https://github.com/farion1231/cc-switch#faq) section in README.
我已阅读 README 中的[常见问题](https://github.com/farion1231/cc-switch#常见问题)。
required: true
- label: |
I have searched for [existing issues](https://github.com/farion1231/cc-switch/issues), including closed ones.
我已搜索过[已有的 Issue](https://github.com/farion1231/cc-switch/issues),包括已关闭的。
required: true
- type: input
attributes:
label: CC Switch Version / 版本号
description: |
See the Settings page in the app.
查看应用设置页面中的版本号。
placeholder: "e.g. 3.11.1"
validations:
required: true
- type: dropdown
attributes:
label: Operating System / 操作系统
multiple: false
options:
- Windows
- macOS
- Linux
validations:
required: true
- type: dropdown
attributes:
label: Related App / 涉及应用
description: |
Which app is affected?
涉及哪个应用?
multiple: true
options:
- Claude Code
- Codex
- Gemini CLI
- OpenCode
- OpenClaw
- Other / 其他
validations:
required: true
- type: textarea
attributes:
label: Steps to Reproduce / 重现步骤
description: |
Please describe the steps to reproduce the bug. Screenshots and logs are helpful.
请描述重现步骤。截图和日志会很有帮助。
placeholder: |
1. Go to ...
2. Click on ...
3. See error ...
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior / 期望行为
description: |
What did you expect to happen?
你期望发生什么?
validations:
required: true
- type: textarea
attributes:
label: Actual Behavior / 实际行为
description: |
What actually happened?
实际发生了什么?
validations:
required: false
- type: textarea
attributes:
label: Additional Context / 补充信息
description: |
Any other information, screenshots, or logs.
其他信息、截图或日志。
validations:
required: false
+12
View File
@@ -0,0 +1,12 @@
blank_issues_enabled: false
contact_links:
- name: "Security Vulnerabilities / 安全漏洞"
url: "https://github.com/farion1231/cc-switch/security/advisories/new"
about: |
Report security vulnerabilities through GitHub Security Advisories.
请通过 GitHub 安全公告报告安全漏洞。
- name: "Discussions / 讨论区"
url: "https://github.com/farion1231/cc-switch/discussions"
about: |
General discussions and community help.
一般讨论和社区帮助。
+60
View File
@@ -0,0 +1,60 @@
name: "📖 Documentation Issue / 文档问题"
description: |
Report documentation errors, outdated content, or missing information.
报告文档错误、过时内容或缺失信息。
labels:
- documentation
body:
- type: checkboxes
attributes:
label: Self Checks / 自检
options:
- label: |
I have searched for [existing issues](https://github.com/farion1231/cc-switch/issues), including closed ones.
我已搜索过[已有的 Issue](https://github.com/farion1231/cc-switch/issues),包括已关闭的。
required: true
- type: dropdown
attributes:
label: Language / 语言
description: |
Which language version of the docs?
涉及哪个语言版本的文档?
multiple: true
options:
- English
- 中文
- 日本語
validations:
required: true
- type: input
attributes:
label: Document Location / 文档位置
description: |
Which file or section is affected? Provide a link or file path.
涉及哪个文件或章节?请提供链接或文件路径。
placeholder: "e.g. README.md#faq or docs/user-manual/zh/..."
validations:
required: true
- type: dropdown
attributes:
label: Issue Type / 问题类型
options:
- "Typo or grammar / 拼写或语法错误"
- "Outdated content / 内容过时"
- "Missing information / 信息缺失"
- "Translation issue / 翻译问题"
- "Other / 其他"
validations:
required: true
- type: textarea
attributes:
label: Description / 描述
description: |
Describe the documentation issue.
描述文档问题。
validations:
required: true
@@ -0,0 +1,75 @@
name: "✨ Feature Request / 功能请求"
description: |
Propose a new feature or improvement.
提出新功能或改进建议。
labels:
- enhancement
body:
- type: checkboxes
attributes:
label: Self Checks / 自检
options:
- label: |
I have read the [FAQ](https://github.com/farion1231/cc-switch#faq) section in README.
我已阅读 README 中的[常见问题](https://github.com/farion1231/cc-switch#常见问题)。
required: true
- label: |
I have searched for [existing issues](https://github.com/farion1231/cc-switch/issues), including closed ones.
我已搜索过[已有的 Issue](https://github.com/farion1231/cc-switch/issues),包括已关闭的。
required: true
- type: dropdown
attributes:
label: Related App / 涉及应用
description: |
Which app is this feature for?
该功能涉及哪个应用?
multiple: true
options:
- Claude Code
- Codex
- Gemini CLI
- OpenCode
- OpenClaw
- General / 通用
validations:
required: true
- type: textarea
attributes:
label: Problem or Motivation / 问题或动机
description: |
Is this request related to a problem? Describe the scenario.
这个请求是否与某个问题相关?请描述使用场景。
placeholder: |
I was trying to ... and found that ...
我在尝试……的时候,发现……
validations:
required: true
- type: textarea
attributes:
label: Proposed Solution / 建议方案
description: |
Describe the solution you'd like.
描述你希望的解决方案。
validations:
required: false
- type: textarea
attributes:
label: Additional Context / 补充信息
description: |
Any other context, mockups, or screenshots.
其他背景信息、设计稿或截图。
validations:
required: false
- type: checkboxes
attributes:
label: Contribution / 参与贡献
options:
- label: |
I am interested in contributing to this feature.
我有兴趣参与开发此功能。
required: false
+64
View File
@@ -0,0 +1,64 @@
name: "❓ Question / 提问"
description: |
Ask a question about usage or configuration.
询问使用或配置相关问题。
labels:
- question
body:
- type: checkboxes
attributes:
label: Self Checks / 自检
options:
- label: |
I have read the [FAQ](https://github.com/farion1231/cc-switch#faq) section in README.
我已阅读 README 中的[常见问题](https://github.com/farion1231/cc-switch#常见问题)。
required: true
- label: |
I have searched for [existing issues](https://github.com/farion1231/cc-switch/issues), including closed ones.
我已搜索过[已有的 Issue](https://github.com/farion1231/cc-switch/issues),包括已关闭的。
required: true
- type: dropdown
attributes:
label: Related App / 涉及应用
description: |
Which app is your question about?
你的问题涉及哪个应用?
multiple: true
options:
- Claude Code
- Codex
- Gemini CLI
- OpenCode
- OpenClaw
- General / 通用
validations:
required: true
- type: textarea
attributes:
label: Your Question / 你的问题
description: |
Describe your question clearly.
请清晰地描述你的问题。
validations:
required: true
- type: textarea
attributes:
label: What Have You Tried / 你已经尝试过什么
description: |
Describe what you've already tried or researched.
描述你已经尝试过或查阅过的内容。
validations:
required: false
- type: textarea
attributes:
label: Environment / 环境信息
description: |
OS, CC Switch version, and any relevant details.
操作系统、CC Switch 版本及其他相关信息。
placeholder: "e.g. macOS 15.4, CC Switch 3.11.1"
validations:
required: false
+39
View File
@@ -0,0 +1,39 @@
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
labels:
- "dependencies"
- "frontend"
commit-message:
prefix: "chore(deps)"
groups:
frontend-deps:
patterns:
- "*"
- package-ecosystem: "cargo"
directory: "/src-tauri"
schedule:
interval: "weekly"
labels:
- "dependencies"
- "backend"
commit-message:
prefix: "chore(deps)"
groups:
cargo-deps:
patterns:
- "*"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
labels:
- "dependencies"
- "actions"
commit-message:
prefix: "chore(deps)"
+25
View File
@@ -0,0 +1,25 @@
## Summary / 概述
<!-- Briefly describe what this PR does and why. / 简要描述这个 PR 做了什么以及为什么。 -->
## Related Issue / 关联 Issue
<!-- Link the related issue. Use "Fixes #123" to auto-close it when merged. -->
<!-- 关联相关 Issue。使用 "Fixes #123" 可在合并时自动关闭。 -->
Fixes #
## Screenshots / 截图
<!-- If applicable, add before/after screenshots. / 如有需要,请添加修改前后的截图。 -->
| Before / 修改前 | After / 修改后 |
|-----------------|---------------|
| | |
## Checklist / 检查清单
- [ ] `pnpm typecheck` passes / 通过 TypeScript 类型检查
- [ ] `pnpm format:check` passes / 通过代码格式检查
- [ ] `cargo clippy` passes (if Rust code changed) / 通过 Clippy 检查(如修改了 Rust 代码)
- [ ] Updated i18n files if user-facing text changed / 如修改了用户可见文本,已更新国际化文件
+99
View File
@@ -0,0 +1,99 @@
name: CI
on:
pull_request:
branches: [main]
push:
branches: [main]
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
frontend:
name: Frontend Checks
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "20"
- name: Setup pnpm
uses: pnpm/action-setup@v6
with:
version: 10.12.3
run_install: false
- name: Get pnpm store directory
id: pnpm-store
shell: bash
run: echo "path=$(pnpm store path --silent)" >> $GITHUB_OUTPUT
- name: Cache pnpm store
uses: actions/cache@v5
with:
path: ${{ steps.pnpm-store.outputs.path }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: ${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: TypeScript type check
run: pnpm typecheck
- name: Check formatting
run: pnpm format:check
- name: Unit tests
run: pnpm test:unit
backend:
name: Backend Checks
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- name: Install Linux system deps
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential pkg-config libssl-dev \
libgtk-3-dev librsvg2-dev libayatana-appindicator3-dev
sudo apt-get install -y --no-install-recommends libwebkit2gtk-4.1-dev \
|| sudo apt-get install -y --no-install-recommends libwebkit2gtk-4.0-dev
sudo apt-get install -y --no-install-recommends libsoup-3.0-dev \
|| sudo apt-get install -y --no-install-recommends libsoup2.4-dev
- name: Cache Cargo registry and build
uses: actions/cache@v5
with:
path: |
~/.cargo/registry
~/.cargo/git
src-tauri/target
key: ${{ runner.os }}-cargo-${{ hashFiles('src-tauri/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-
- name: Create frontend dist placeholder
run: mkdir -p dist
- name: Check Rust formatting
run: cargo fmt --check --manifest-path src-tauri/Cargo.toml
- name: Clippy
run: cargo clippy --manifest-path src-tauri/Cargo.toml -- -D warnings
- name: Run tests
run: cargo test --manifest-path src-tauri/Cargo.toml
+61
View File
@@ -0,0 +1,61 @@
name: Claude
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
pull_request_review:
types: [submitted]
issues:
types: [opened, assigned]
jobs:
claude:
if: |
((github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') &&
(github.event.comment.author_association == 'OWNER' ||
github.event.comment.author_association == 'MEMBER' ||
github.event.comment.author_association == 'COLLABORATOR'))
||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude') &&
(github.event.comment.author_association == 'OWNER' ||
github.event.comment.author_association == 'MEMBER' ||
github.event.comment.author_association == 'COLLABORATOR'))
||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude') &&
(github.event.review.author_association == 'OWNER' ||
github.event.review.author_association == 'MEMBER' ||
github.event.review.author_association == 'COLLABORATOR'))
||
(github.event_name == 'issues' &&
(contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) &&
(github.event.issue.author_association == 'OWNER' ||
github.event.issue.author_association == 'MEMBER' ||
github.event.issue.author_association == 'COLLABORATOR')))
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
issues: write
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 1
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Run Claude (review only)
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
claude_args: >-
--model claude-opus-4-7
--disallowedTools Edit,Write,MultiEdit,NotebookEdit
--append-system-prompt "You are reviewing PRs for cc-switch — a small open-source Tauri 2.0 + React + TypeScript desktop app maintained by a single developer who values pragmatism over perfection.
ONLY flag HIGH SIGNAL issues. An issue qualifies only if it meets at least one of: code that fails to compile/parse/run; code that will definitely produce wrong results; a security vulnerability with a concrete trigger (SSRF, injection, unsafe deserialization, credential or data leaks); database/migration correctness (schema mismatch, data loss on upgrade, broken SCHEMA_VERSION transition); cross-platform breakage (Windows/macOS/Linux specific); clear, quotable violations of CLAUDE.md.
Each finding must include a confidence score from 0 to 100. Do NOT post any finding scored below 80. Each finding must carry a severity tag — Important (bug that should be fixed before merge), Nit (minor, worth fixing but not blocking), or Pre-existing (exists already, not introduced by this PR).
DO NOT flag any of the following: pedantic nitpicks a senior engineer would not raise; anything a linter, typechecker, pnpm format, or cargo fmt would catch; missing test coverage unless CLAUDE.md explicitly mandates it; style, naming, or 'could be more idiomatic' suggestions; speculative future-proofing ('what if X is added later'); issues on lines the PR did not modify; potential bugs for which you cannot construct a concrete failure scenario; positive feedback or 'what is well done' sections.
OUTPUT RULES: Cap Nit-level findings at 5 per review. If you found more nits, append 'plus N similar nits' to the summary instead of listing them inline. If only nits were found, lead the review with 'No blocking issues.' If nothing material is wrong, say 'LGTM' explicitly and stop — approval with zero comments is a valid and expected outcome for most PRs. Do NOT post a final APPROVE or REQUEST CHANGES verdict; leave the merge decision to the maintainer.
Never modify files, push commits, or create PRs."
+272 -40
View File
@@ -26,10 +26,10 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version: '20'
@@ -74,7 +74,7 @@ jobs:
|| sudo apt-get install -y --no-install-recommends libsoup2.4-dev
- name: Setup pnpm
uses: pnpm/action-setup@v2
uses: pnpm/action-setup@v6
with:
version: 10.12.3
run_install: false
@@ -85,7 +85,7 @@ jobs:
run: echo "path=$(pnpm store path --silent)" >> $GITHUB_OUTPUT
- name: Setup pnpm cache
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: ${{ steps.pnpm-store.outputs.path }}
key: ${{ runner.os }}-${{ runner.arch }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
@@ -150,9 +150,76 @@ jobs:
fi
echo "✅ Tauri signing key prepared"
- name: Import Apple signing certificate
if: runner.os == 'macOS'
shell: bash
run: |
set -euo pipefail
# Decode .p12 certificate from base64
CERT_PATH="$RUNNER_TEMP/certificate.p12"
printf '%s' "${{ secrets.APPLE_CERTIFICATE }}" | (base64 --decode 2>/dev/null || base64 -D) > "$CERT_PATH"
# Save original default keychain for cleanup
ORIGINAL_DEFAULT_KEYCHAIN=$(security default-keychain -d user | tr -d '"' | xargs)
echo "ORIGINAL_DEFAULT_KEYCHAIN=$ORIGINAL_DEFAULT_KEYCHAIN" >> "$GITHUB_ENV"
# Create temporary keychain
KEYCHAIN_PATH="$RUNNER_TEMP/build.keychain-db"
security create-keychain -p "${{ secrets.KEYCHAIN_PASSWORD }}" "$KEYCHAIN_PATH"
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
security default-keychain -s "$KEYCHAIN_PATH"
security unlock-keychain -p "${{ secrets.KEYCHAIN_PASSWORD }}" "$KEYCHAIN_PATH"
# Import certificate
security import "$CERT_PATH" \
-k "$KEYCHAIN_PATH" \
-P "${{ secrets.APPLE_CERTIFICATE_PASSWORD }}" \
-T /usr/bin/codesign \
-T /usr/bin/security
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "${{ secrets.KEYCHAIN_PASSWORD }}" "$KEYCHAIN_PATH"
# Dynamically resolve signing identity (must be "Developer ID Application")
IDENTITY=$(security find-identity -v -p codesigning "$KEYCHAIN_PATH" \
| grep "Developer ID Application" | grep -oE '"[^"]+"' | head -1 | tr -d '"')
if [ -z "$IDENTITY" ]; then
echo "❌ No 'Developer ID Application' identity found — listing all identities:" >&2
security find-identity -v -p codesigning "$KEYCHAIN_PATH"
exit 1
fi
echo "✅ Signing identity: $IDENTITY"
echo "APPLE_SIGNING_IDENTITY=$IDENTITY" >> "$GITHUB_ENV"
# Cleanup certificate file
rm -f "$CERT_PATH"
- name: Build Tauri App (macOS)
if: runner.os == 'macOS'
run: pnpm tauri build --target universal-apple-darwin
shell: bash
timeout-minutes: 60
env:
APPLE_SIGNING_IDENTITY: ${{ env.APPLE_SIGNING_IDENTITY }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: |
set -euo pipefail
max_attempts=3
for attempt in $(seq 1 "$max_attempts"); do
echo "=== macOS build/notarization attempt ${attempt}/${max_attempts} ==="
if pnpm tauri build --target universal-apple-darwin; then
echo "✅ macOS build/notarization succeeded"
exit 0
fi
if [ "$attempt" -eq "$max_attempts" ]; then
echo "❌ macOS build/notarization failed after ${max_attempts} attempts" >&2
exit 1
fi
sleep_seconds=$((attempt * 60))
echo "⚠️ macOS build/notarization failed, retrying in ${sleep_seconds}s..."
sleep "$sleep_seconds"
done
- name: Build Tauri App (Windows)
if: runner.os == 'Windows'
@@ -169,7 +236,8 @@ jobs:
set -euxo pipefail
mkdir -p release-assets
VERSION="${GITHUB_REF_NAME}" # e.g., v3.5.0
echo "Looking for updater artifact (.tar.gz) and .app for zip..."
# Locate bundle artifacts
TAR_GZ=""; APP_PATH=""
for path in \
"src-tauri/target/universal-apple-darwin/release/bundle/macos" \
@@ -177,28 +245,150 @@ jobs:
"src-tauri/target/x86_64-apple-darwin/release/bundle/macos" \
"src-tauri/target/release/bundle/macos"; do
if [ -d "$path" ]; then
[ -z "$TAR_GZ" ] && TAR_GZ=$(find "$path" -maxdepth 1 -name "*.tar.gz" -type f | head -1 || true)
[ -z "$TAR_GZ" ] && TAR_GZ=$(find "$path" -maxdepth 1 -name "*.tar.gz" -type f | head -1 || true)
[ -z "$APP_PATH" ] && APP_PATH=$(find "$path" -maxdepth 1 -name "*.app" -type d | head -1 || true)
fi
done
if [ -z "$TAR_GZ" ]; then
echo "No macOS .tar.gz updater artifact found" >&2
echo "No macOS .tar.gz updater artifact found" >&2
exit 1
fi
# 重命名 tar.gz 为统一格式
if [ -z "$APP_PATH" ]; then
echo "❌ No .app found" >&2
exit 1
fi
# Staple notarization ticket to .app (Tauri already notarized it)
xcrun stapler staple "$APP_PATH"
echo "✅ .app stapled"
# 1) Collect .tar.gz (updater artifact)
NEW_TAR_GZ="CC-Switch-${VERSION}-macOS.tar.gz"
cp "$TAR_GZ" "release-assets/$NEW_TAR_GZ"
[ -f "$TAR_GZ.sig" ] && cp "$TAR_GZ.sig" "release-assets/$NEW_TAR_GZ.sig" || echo ".sig for macOS not found yet"
echo "macOS updater artifact copied: $NEW_TAR_GZ"
if [ -n "$APP_PATH" ]; then
APP_DIR=$(dirname "$APP_PATH"); APP_NAME=$(basename "$APP_PATH")
NEW_ZIP="CC-Switch-${VERSION}-macOS.zip"
cd "$APP_DIR"
ditto -c -k --sequesterRsrc --keepParent "$APP_NAME" "$NEW_ZIP"
mv "$NEW_ZIP" "$GITHUB_WORKSPACE/release-assets/"
echo "macOS zip ready: $NEW_ZIP"
# 2) Collect .app as zip
NEW_ZIP="CC-Switch-${VERSION}-macOS.zip"
ditto -c -k --sequesterRsrc --keepParent "$APP_PATH" "release-assets/$NEW_ZIP"
echo "macOS zip ready: $NEW_ZIP"
# 3) Create styled DMG with create-dmg (Tauri's built-in DMG styling doesn't work on CI)
if [ -z "${APPLE_SIGNING_IDENTITY:-}" ]; then
echo "❌ APPLE_SIGNING_IDENTITY is missing before DMG creation" >&2
exit 1
fi
HOMEBREW_NO_AUTO_UPDATE=1 brew install create-dmg
NEW_DMG="CC-Switch-${VERSION}-macOS.dmg"
DMG_STAGE_DIR="$RUNNER_TEMP/dmg-stage"
rm -rf "$DMG_STAGE_DIR"
mkdir -p "$DMG_STAGE_DIR"
ditto "$APP_PATH" "$DMG_STAGE_DIR/CC Switch.app"
create-dmg \
--volname "CC Switch" \
--background "src-tauri/icons/dmg-background.png" \
--window-size 660 400 \
--window-pos 200 120 \
--icon-size 80 \
--icon "CC Switch.app" 180 220 \
--hide-extension "CC Switch.app" \
--app-drop-link 480 220 \
--codesign "$APPLE_SIGNING_IDENTITY" \
--no-internet-enable \
"release-assets/$NEW_DMG" \
"$DMG_STAGE_DIR"
rm -rf "$DMG_STAGE_DIR"
echo "✅ Styled DMG created: $NEW_DMG"
- name: Notarize macOS DMG
if: runner.os == 'macOS'
shell: bash
timeout-minutes: 30
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: |
set -euo pipefail
DMG_PATH=$(find release-assets -maxdepth 1 -name "*.dmg" -type f | head -1 || true)
if [ -z "$DMG_PATH" ]; then
echo "❌ No .dmg found in release-assets/ to notarize" >&2
exit 1
fi
echo "=== Notarizing DMG: $DMG_PATH ==="
max_attempts=3
for attempt in $(seq 1 "$max_attempts"); do
echo "=== DMG notarization attempt ${attempt}/${max_attempts} ==="
if xcrun notarytool submit "$DMG_PATH" \
--apple-id "$APPLE_ID" \
--password "$APPLE_PASSWORD" \
--team-id "$APPLE_TEAM_ID" \
--wait; then
echo "✅ DMG notarization succeeded"
xcrun stapler staple "$DMG_PATH"
echo "✅ DMG stapled"
break
fi
if [ "$attempt" -eq "$max_attempts" ]; then
echo "❌ DMG notarization failed after ${max_attempts} attempts" >&2
exit 1
fi
sleep_seconds=$((attempt * 60))
echo "⚠️ DMG notarization failed, retrying in ${sleep_seconds}s..."
sleep "$sleep_seconds"
done
- name: Verify macOS code signing and notarization
if: runner.os == 'macOS'
shell: bash
run: |
set -euo pipefail
# Verify .app (from Tauri bundle)
APP_PATH=""
for path in \
"src-tauri/target/universal-apple-darwin/release/bundle/macos" \
"src-tauri/target/aarch64-apple-darwin/release/bundle/macos" \
"src-tauri/target/x86_64-apple-darwin/release/bundle/macos" \
"src-tauri/target/release/bundle/macos"; do
if [ -d "$path" ]; then
[ -z "$APP_PATH" ] && APP_PATH=$(find "$path" -maxdepth 1 -name "*.app" -type d | head -1 || true)
fi
done
if [ -z "$APP_PATH" ]; then
echo "❌ No .app found for verification" >&2
exit 1
fi
echo "=== Verifying .app: $APP_PATH ==="
codesign --verify --deep --strict --verbose=2 "$APP_PATH"
echo "✅ codesign verification passed"
spctl -a -t exec -vv "$APP_PATH"
echo "✅ spctl assessment passed"
xcrun stapler validate "$APP_PATH"
echo "✅ .app stapler validation passed"
# Verify .dmg (from release-assets/, created by create-dmg + notarized)
DMG_PATH=$(find release-assets -maxdepth 1 -name "*.dmg" -type f | head -1 || true)
if [ -n "$DMG_PATH" ]; then
echo "=== Verifying .dmg: $DMG_PATH ==="
codesign --verify --verbose=2 "$DMG_PATH"
echo "✅ .dmg codesign verification passed"
spctl -a -t open --context context:primary-signature -vv "$DMG_PATH"
echo "✅ .dmg spctl assessment passed"
xcrun stapler validate "$DMG_PATH"
echo "✅ .dmg stapler validation passed"
else
echo "No .app found to zip (optional)" >&2
echo "No .dmg found for verification — release would ship without verified DMG" >&2
exit 1
fi
- name: Prepare Windows Assets
@@ -299,29 +489,12 @@ jobs:
echo "Collected signatures (if any alongside artifacts):"
ls -la release-assets/*.sig || echo "No signatures found"
- name: Upload Release Assets
uses: softprops/action-gh-release@v2
- name: Upload release artifacts to workflow
uses: actions/upload-artifact@v7
with:
tag_name: ${{ github.ref_name }}
name: CC Switch ${{ github.ref_name }}
prerelease: true
body: |
## CC Switch ${{ github.ref_name }}
Claude Code 供应商切换工具
### 下载
- **macOS**: `CC-Switch-${{ github.ref_name }}-macOS.zip`(解压即用)或 `CC-Switch-${{ github.ref_name }}-macOS.tar.gz`Homebrew
- **Windows**: `CC-Switch-${{ github.ref_name }}-Windows.msi`(安装版)或 `CC-Switch-${{ github.ref_name }}-Windows-Portable.zip`(绿色版)
- **Linux (x86_64)**: `CC-Switch-${{ github.ref_name }}-Linux-x86_64.AppImage` / `.deb` / `.rpm`
- **Linux (ARM64)**: `CC-Switch-${{ github.ref_name }}-Linux-arm64.AppImage` / `.deb` / `.rpm`
---
提示:macOS 如遇"已损坏"提示,可在终端执行:`xattr -cr "/Applications/CC Switch.app"`
files: release-assets/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
name: release-assets-${{ runner.os }}-${{ matrix.arch || runner.arch }}
path: release-assets/*
if-no-files-found: error
- name: List generated bundles (debug)
if: always()
@@ -330,10 +503,69 @@ jobs:
echo "Listing bundles in src-tauri/target..."
find src-tauri/target -maxdepth 4 -type f -name "*.*" 2>/dev/null || true
- name: Clean up Apple signing keychain
if: runner.os == 'macOS' && always()
shell: bash
run: |
if [ -n "${ORIGINAL_DEFAULT_KEYCHAIN:-}" ]; then
security default-keychain -s "$ORIGINAL_DEFAULT_KEYCHAIN" || true
fi
if [ -f "$RUNNER_TEMP/build.keychain-db" ]; then
security delete-keychain "$RUNNER_TEMP/build.keychain-db" || true
fi
publish-release:
name: Publish GitHub Release
runs-on: ubuntu-22.04
needs: release
permissions:
contents: write
steps:
- name: Download built release artifacts
uses: actions/download-artifact@v8
with:
pattern: release-assets-*
path: release-assets
merge-multiple: true
- name: List downloaded release artifacts
shell: bash
run: |
set -euo pipefail
ls -la release-assets
- name: Upload Release Assets
uses: softprops/action-gh-release@v3
with:
tag_name: ${{ github.ref_name }}
name: CC Switch ${{ github.ref_name }}
prerelease: true
body: |
## CC Switch ${{ github.ref_name }}
🌐 **Only Official Website / 唯一官方网站 / 唯一の公式サイト**: [ccswitch.io](https://ccswitch.io)
Claude Code 供应商切换工具
### 下载
- **macOS**: `CC-Switch-${{ github.ref_name }}-macOS.dmg`(推荐)或 `CC-Switch-${{ github.ref_name }}-macOS.zip`(解压即用)
- **Windows**: `CC-Switch-${{ github.ref_name }}-Windows.msi`(安装版)或 `CC-Switch-${{ github.ref_name }}-Windows-Portable.zip`(绿色版)
- **Linux (x86_64)**: `CC-Switch-${{ github.ref_name }}-Linux-x86_64.AppImage` / `.deb` / `.rpm`
- **Linux (ARM64)**: `CC-Switch-${{ github.ref_name }}-Linux-arm64.AppImage` / `.deb` / `.rpm`
> `.tar.gz` 为 Tauri updater 自动更新专用,无需手动下载。
---
macOS 版本已通过 Apple 代码签名和公证,可直接安装使用。
files: release-assets/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
assemble-latest-json:
name: Assemble latest.json
runs-on: ubuntu-22.04
needs: release
needs: publish-release
permissions:
contents: write
steps:
+49
View File
@@ -0,0 +1,49 @@
name: Close Stale Issues
on:
schedule:
# Run daily at 00:00 UTC
- cron: '0 0 * * *'
workflow_dispatch: # Allow manual trigger
permissions:
issues: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v10
with:
# --- Timing ---
days-before-stale: 60
days-before-close: 14
# --- Stale label ---
stale-issue-label: 'stale'
# --- Messages (bilingual) ---
stale-issue-message: |
此 issue 已超过 60 天没有活动,已被标记为 `stale`。
如果此问题仍然存在,请回复以保持 issue 打开状态,否则将在 14 天后自动关闭。
This issue has been automatically marked as `stale` because it has not had activity for 60 days.
Please reply to keep it open, otherwise it will be automatically closed in 14 days.
close-issue-message: |
此 issue 因长时间无活动已被自动关闭。如果问题仍然存在,欢迎重新打开。
This issue has been automatically closed due to inactivity. If the problem persists, feel free to reopen it.
# --- Exemptions ---
# Issues with these labels will NEVER be marked stale
exempt-issue-labels: 'security,performance'
# Issues with 3+ reactions are likely popular requests, exempt them
exempt-issue-created-after: '2020-01-01'
# --- Processing limits ---
# Process up to 100 issues per run to avoid API rate limits
operations-per-run: 100
# --- Only issues, not PRs ---
days-before-pr-stale: -1
days-before-pr-close: -1
+7
View File
@@ -23,3 +23,10 @@ nul
flatpak/cc-switch.deb
flatpak-build/
flatpak-repo/
.worktrees/
.spec-workflow/
copilot-api
.history
CODEBUDDY.md
.github
mainWindow.js
+1 -1
View File
@@ -1 +1 @@
22.12.0
22.12.0
+780 -2
View File
@@ -7,9 +7,787 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [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
- **Windows Home Dir Regression**: Prevent providers/settings “disappearing” after upgrading from v3.10.2 → v3.10.3 when `HOME` differs from the real user profile directory; restore default path resolution and auto-detect the v3.10.3 legacy database location.
- **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
Development since v3.14.0 focuses on Codex OAuth stability, tray usage visibility, Skills import/install reliability, Gemini session restore paths, and simplifying Hermes configuration health handling.
**Stats**: 13 commits | 48 files changed | +1,883 insertions | -808 deletions
### Added
- **Tray Usage Visibility**: System tray submenus now show cached usage for the current Claude / Codex / Gemini provider, including subscription and script-based usage summaries with utilization color markers. Tray-triggered refreshes are throttled, limited to visible apps, and synchronized back into React Query so the main window and tray share fresh usage data (#2184).
- **Tray Coding-Plan Usage (Kimi / Zhipu / MiniMax)**: System tray now renders 5-hour + weekly window usage for Chinese coding-plan providers using the same `🟢 h12% w80%` two-window layout as official subscription badges (worst utilization drives the emoji). Creating a Claude provider whose `ANTHROPIC_BASE_URL` matches a known coding-plan host now auto-injects `meta.usage_script`, so the tray lights up without opening the Usage Script modal. Existing `usage_script` values are preserved on update.
- **Codex OAuth FAST Mode**: Added an explicit FAST mode toggle for Codex OAuth-backed Claude providers. When enabled, converted Responses requests send `service_tier="priority"` for lower latency; the toggle stays off by default to avoid unexpectedly increasing ChatGPT quota consumption (#2210).
### Changed
- **Session and Settings Layout Polish**: Hardened the scroll-area viewport with width containment to fix horizontal overflow, and tightened app bottom spacing plus settings footer spacing so long session/settings views fit more cleanly (#2201).
### Removed
- **Hermes Config Health Scanner**: Removed the in-app Hermes config health scanner, warning banner, `scan_hermes_config_health` command, `HermesHealthWarning` type, and `HermesWriteOutcome.warnings` payload. CC Switch now keeps the Hermes surface focused on active provider display, provider switching defaults, memory editing, and launching the Hermes Web UI for deep configuration.
### Fixed
- **Codex OAuth Cache Routing**: Stabilized ChatGPT Codex reverse-proxy cache identity by using client-provided session IDs for `prompt_cache_key` and Codex session headers, preserving explicit cache keys, and avoiding generated UUID cache churn (#2218).
- **Codex OAuth Responses SSE Aggregation**: Non-streaming Anthropic clients now receive JSON even when the ChatGPT Codex upstream forces OpenAI Responses SSE; CC Switch aggregates the upstream SSE events before running the non-streaming transform (#2235).
- **Codex OAuth Stream Check Parity**: Stream checks now build Codex OAuth test requests with the same `store: false`, encrypted reasoning include, and provider FAST mode setting as production proxy requests (#2210).
- **Codex Model Extraction**: Replaced first-line regex matching with TOML parsing when reading Codex config models, so multiline TOML is handled correctly (#2227).
- **Model Quick-Set / One-Click Config**: Model quick-set updates now apply against the latest provider form config, preventing stale state from making one-click configuration fail (#2249).
- **Skills Import Duplicates**: The Skills import dialog disables actions while import is pending and the installed-skills cache deduplicates imported results by ID, preventing double-clicks from adding duplicate installed entries (#2139, #2211).
- **Root-Level Skill Repos**: Skill install and update flows now consistently resolve three source patterns: direct nested paths, install-name recursive search, and repository-root `SKILL.md` sources (#2231).
- **Gemini Session Restore Paths**: Gemini session scanning now reads `.project_root` metadata so restore flows can pass the original project directory when available (#2240).
- **Provider Hover Names**: Provider icons now expose the provider name on hover for inline SVG, image URL, and fallback initials render paths (#2237).
## [3.14.0] - 2026-04-21
Development since v3.13.0 focuses on onboarding Hermes Agent as a first-class managed app, rolling out Claude Opus 4.7 across the preset matrix, adding a Gemini Native API proxy, and sharpening session, usage, and proxy workflows.
**Stats**: 100 commits | 219 files changed | +20,548 insertions | -3,569 deletions
### Added
- **Hermes Agent Support (6th Managed App)**: Added Hermes Agent as a first-class managed app with database migration v9→v10, full Rust command surface, YAML-backed `~/.hermes/config.yaml` read/write with atomic backups, MCP sync, Skills sync, session manager with SQLite + JSONL support, and dedicated frontend panels. Supports four API protocols (`chat_completions`, `anthropic_messages`, `codex_responses`, `bedrock_converse`) aligned with Hermes Agent 0.10.0 schema. Read-only rendering for providers owned by the user-authored `providers:` dict, with deep configuration delegated to the Hermes Web UI.
- **Hermes Memory Panel**: Added a Memory panel for editing `MEMORY.md` and `USER.md` directly from CC Switch, with an enable switch, character-count limits, and a live save flow. Replaces the Prompts entry for Hermes.
- **Hermes Provider Presets**: Added ~50 Hermes provider presets spanning Nous Research, Shengsuanyun, OpenRouter, DeepSeek, Together AI, StepFun, Zhipu GLM, Bailian, Kimi, MiniMax, DouBao, BaiLing, ModelScope, KAT-Coder, PackyCode, Cubence, AIGoCode, RightCode, AICodeMirror, AICoding, CrazyRouter, SSSAiCode, Micu, CTok.ai, DDSHub, E-FlowCode, LionCCAPI, PIPELLM, Compshare, SiliconFlow, AiHubMix, DMXAPI, TheRouter, Novita, Nvidia, and Xiaomi MiMo.
- **Claude Opus 4.7 Support**: Added Claude Opus 4.7 with adaptive thinking whitelisting, per-million pricing seed, and Bedrock SKU (`anthropic.claude-opus-4-7` / `global.anthropic.claude-opus-4-7`, dropping the legacy `-v1` suffix). Migrated all aggregator and Bedrock presets to Opus 4.7 as the default Opus model.
- **Claude `max` Effort Tier**: Upgraded the Claude effort dropdown from `high` to `max` for extended reasoning capacity.
- **Gemini Native API Proxy**: Added `api_format = "gemini_native"` so the proxy can forward to Google's `generateContent` API with full streaming, schema conversion, and shadow request support. Adds `gemini_url.rs`, `gemini_schema.rs`, `gemini_shadow.rs`, `streaming_gemini.rs`, and `transform_gemini.rs` under the proxy providers module.
- **GitHub Copilot Enterprise Server**: Added GHES authentication and endpoint configuration for Copilot-backed Claude providers, plus thinking-block stripping before upstream to preserve premium interaction quota.
- **Session List Virtualization**: Virtualized the session list via `@tanstack/react-virtual` so long conversations (thousands of records) scroll smoothly; long session messages are now collapsed by default to reduce text layout cost.
- **Codex / OpenClaw Session Title Extraction**: Added meaningful title auto-extraction for Codex and OpenClaw sessions with 2-line display; strips OpenClaw `message_id` suffix noise.
- **Usage Date Range Picker**: Added a date range selector to the usage dashboard with preset tabs (Today / 1d / 7d / 14d / 30d), a custom date + time calendar picker, and a page-jump input on paginated lists.
- **Model Mapping Quick-Set**: Added a quick-set button next to model mapping fields in provider forms for faster edits.
- **Stream Check Error Classification**: Classified Stream Check errors and surfaced them as color-coded toasts; refreshed default probe models and added explicit detection for "model not found" responses.
- **Block Official Provider Switching During Local Routing**: Blocks switching to official providers while Local Routing is active, since routing official API traffic through the local proxy carries account-suspension risk. A warning toast surfaces the block.
- **Pricing Database Refresh (v8 → v9)**: Added ~50 new model pricing entries and corrected stale prices via a reseed-on-migration step, including Claude 4.7, Opus 4.7 Adaptive Thinking, Grok 4, Qwen 3.5/3.6, MiniMax M2.5/M2.7, Doubao Seed 2.0 series, and GLM-5/5.1. DeepSeek and Kimi K2.5 prices updated.
- **Application-Level Window Controls**: Added an opt-in setting to render CC Switch's own minimize / toggle-maximize / close buttons instead of the system decorations, materially improving the experience on Linux Wayland where compositor-drawn buttons can become inert.
- **Hermes in Unified Skills Management**: Added Hermes to the unified Skills surface; skill install, enable, and filter now cover the Hermes app alongside Claude / Codex / Gemini / OpenCode / OpenClaw.
- **OpenClaw Config Directory Override**: Added a settings option to point CC Switch at a custom `openclaw.json` location.
- **Hermes Config Directory Override**: Added a settings option to point CC Switch at a custom `~/.hermes/config.yaml` location, backed by data-driven dispatch.
- **StepFun Step Plan Preset**: Added StepFun Step Plan (EN/ZH) provider presets.
- **New API Usage Script Template**: Added a User-Agent header to the New API usage script template for better upstream compatibility.
- **Launch Hermes Dashboard from Toolbar**: When the Hermes Web UI probe fails, the toolbar entry now offers to run `hermes dashboard` in the user's preferred terminal via a temp bash/batch script. `hermes dashboard` opens the browser itself once ready, so no polling is required. Also corrects the stale `hermes web` hint in the offline toast (the real command is `hermes dashboard`) and reorders Linux terminal detection to try `which` before stat'ing `/usr/bin`, `/bin`, `/usr/local/bin`.
- **LemonData Provider Preset (All Six Apps)**: Registered LemonData as a third-party partner preset across Claude, Codex, Gemini, OpenCode, OpenClaw, and Hermes, with icon assets and zh/en/ja partner-promotion copy. Claude uses `ANTHROPIC_API_KEY` auth; OpenAI-compatible apps target `gpt-5.4`.
- **DDSHub Codex Preset**: Added a Codex-compatible endpoint for DDSHub at the same host as its Claude service; base URL omits the `/v1` suffix because the gateway auto-routes OpenAI SDK paths.
### Changed
- **"Local Proxy Takeover" → "Local Routing"**: Unified terminology across UI copy, README, and docs in all three locales. Functional behavior is unchanged.
- **Hermes `Auto` api_mode Removed**: Users must now pick an explicit protocol; new deeplinks default to `chat_completions`. Eliminates URL-based heuristic surprises.
- **Hermes Provider Form**: Added an API mode dropdown and per-provider model editor; bound per-provider models to the top-level `model:` when switching active providers.
- **Hermes Deep Config Delegation**: Deep YAML knobs are now delegated to the Hermes Web UI via a direct launch action, rather than duplicated in the CC Switch form.
- **`ANTHROPIC_REASONING_MODEL` Removed from Claude Quick-Set**: Decoupled the reasoning capability from model selection; the legacy field is no longer surfaced in the quick-set form.
- **Per-Provider Proxy Config Removed**: Consolidated into global Local Routing; the provider-level proxy toggle and associated storage are gone.
- **Unified Toolbar Icon Button Width**: Normalized icon-button widths across Claude / Codex / Gemini / OpenCode / OpenClaw / Hermes panels for a consistent header look.
- **Rust Toolchain Pinned to 1.95**: Adopted clippy 1.95 suggestions across the workspace and pinned the toolchain to prevent nightly drift.
- **Tray Menu ID Constant**: The tray identifier moved from the hardcoded string `"main"` to a `TRAY_ID` constant (`"cc-switch"`) across all call sites.
- **Copilot Request Classification**: Refined request routing inside the Copilot optimizer to further reduce unnecessary premium interaction consumption.
- **Usage Script Intranet Support**: Removed private-IP / suspicious-hostname blocking from usage scripts, unblocking enterprise intranet, Docker, and self-hosted API endpoints. Built-in templates still enforce HTTPS (except localhost) and same-origin checks; custom templates remain user-controlled with those request-URL checks skipped.
- **Failover Queue Notes**: Provider notes now appear in failover queue selectors and queue rows for easier identification across multi-provider queues.
- **Hermes Toolbar Layout**: Swapped the Hermes Web UI button from `ExternalLink` to `LayoutDashboard` (clicking may spawn `hermes dashboard` rather than just opening a URL), and moved MCP to the final toolbar slot so Hermes matches the Claude / Codex / Gemini / OpenCode layout.
### Fixed
- **Header Auto-Compact Latching After Maximize**: The toolbar no longer stays compacted after maximize/restore; compaction now reevaluates on size changes.
- **Hermes YAML Pollution & OAuth MCP Auth Drop**: Round-tripping through CC Switch no longer drops OAuth MCP `auth` blocks or pollutes unrelated YAML keys; guard tests added via `tests/hermes_roundtrip.rs`.
- **Hermes Active Provider Display**: Hermes UI now correctly surfaces the active provider and wires add / enable / remove actions.
- **Hermes Provider Persistence**: Providers persist under `custom_providers:` so `api_mode` and `model` survive restarts and config reloads.
- **Codex `cache_control` Preservation**: Preserve `cache_control` when merging system prompts during Codex format conversion (#1946).
- **Claude Prompt Cache Key Leak**: Stopped sending prompt cache keys during Claude chat conversions (#2003).
- **Proxy Hop-by-Hop Header Stripping**: Strip hop-by-hop response headers (Connection, Keep-Alive, Transfer-Encoding, etc.) per RFC 7230.
- **Permissive Proxy CORS Removed**: Removed the permissive CORS layer from the proxy (#1915).
- **Copilot Premium Consumption**: Further reduced unnecessary Copilot premium interaction consumption during pass-through traffic.
- **Backend Error Details in Proxy Toast**: Surface backend error payload details in proxy-related toast messages instead of a generic failure string.
- **Usage Log Deduplication**: Deduplicated proxy and session-log usage records so the same request is no longer double-counted; synced the request log time range with the dashboard's 1d / 7d / 30d selector.
- **Common Config Checkbox Persistence**: Checkbox state for Claude / Codex / Gemini common-config toggles now persists correctly across reopens.
- **Claude Plugin `settings.json` Sync**: Editing the current provider now syncs back to `settings.json` for the Claude plugin path.
- **Google Official Gemini Env Preservation**: Saving the Google Official Gemini provider no longer clobbers the `env` block.
- **OpenCode JSON5 Parser for Trailing Commas**: OpenCode config reads now tolerate trailing commas via a JSON5 parser.
- **Preset Refreshes**: Refreshed stale context windows for DeepSeek and Claude 1M; refreshed stale model IDs; backfilled Hermes model lists; fixed the Nous endpoint and replaced the Hermes placeholder icon with Nous brand artwork; pruned unused official Hermes presets.
- **Auto-Expand Collapsed Messages on Search Hit**: Collapsed messages now auto-expand when a search match lands inside hidden content.
- **Unknown Subscription Quota Tiers Hidden**: Provider cards no longer render unknown subscription quota tiers.
- **Weekly Limit Label Unified**: Aligned the weekly_limit tier label with the official 7-day naming across locales.
- **Root-Level Skill Repo Install**: Fixed skill installation when the repository root itself is a skill.
- **Session ID Parsing Clippy**: Removed a redundant closure in session ID parsing (clippy warning).
- **Usage Log Stat Dedup**: Deduplicated proxy-sourced and session-log-sourced usage records for accurate totals.
- **Stream Check Default Models Refresh**: Updated stream-check default probe models to match each vendor's current lineup.
- **Skills Import Sync**: Imported Skills are now immediately synced into enabled app directories instead of only being recorded in the database, so the UI no longer shows "installed" while the target app directory is missing the skill.
- **Ghostty Session Restore**: Fixed Ghostty session restore launch by using shell execution with `--working-directory`, avoiding `cwd` escaping issues when the path contains spaces or special characters.
- **Hermes Health Check Borrowing OpenClaw Schema**: Hermes providers were routed through `check_additive_app_stream` (the OpenClaw dispatcher), which reads camelCase `baseUrl` / `apiKey` / `api` and surfaced "OpenClaw provider is missing baseUrl" even when every Hermes field was filled. Introduced `check_hermes_stream` with Hermes-specific extractors that map `api_mode` (`chat_completions` / `anthropic_messages` / `codex_responses`) to the matching `check_claude_stream` `api_format`, and returns `bedrock_converse` as unsupported. `api_mode` is now resolved before URL / API key extraction, so `bedrock_converse` users see the real cause rather than a misleading "missing base_url".
- **Usage Query Modal for Hermes & OpenClaw**: `getProviderCredentials` now reads flat `settingsConfig` fields for Hermes (snake_case `base_url` / `api_key`) and OpenClaw (camelCase `baseUrl` / `apiKey`), so the "official balance" template auto-selects for matching providers like SiliconFlow. Also refactored the BALANCE and TOKEN_PLAN test paths to reuse the precomputed `providerCredentials` instead of re-reading `env.ANTHROPIC_*` directly, fixing the "empty key" error for non-Claude apps even when the key was configured.
### Docs
- **README Sponsor Updates**: Updated SiliconFlow signup bonus to ¥16, trimmed the SSSAiCode sponsor blurb, updated partner logos, and added LemonData as a new sponsor.
- **Global Proxy Hint Clarified**: Clarified the global proxy hint about local routing across all three locales.
- **Takeover → Routing Rename**: Renamed takeover docs to routing and updated anchors across all languages.
- **PIPELLM Website URL**: Updated the PIPELLM sponsor website URL to `code.pipellm.ai`.
### Breaking
- **Hermes requires explicit `api_mode`**: The `Auto` mode is gone; imported or deeplinked providers default to `chat_completions`. Users with prior `Auto` configs will be prompted to pick a protocol.
- **`ANTHROPIC_REASONING_MODEL` removed from Claude quick-set**: The legacy field is no longer exposed; existing settings are cleaned up automatically.
- **Per-provider proxy configuration removed**: Migrate to the global Local Routing setting. Existing per-provider proxy values are ignored.
- **Database schema bumped v9 → v10**: Adds `enabled_hermes` columns to `mcp_servers` and `skills` (auto-migrated with `DEFAULT 0`; no data loss).
- **Pricing table reseeded (v8 → v9)**: The `model_pricing` table is cleared and reseeded on first launch to pick up new models and corrected prices.
- **XCodeAPI preset removed**: Users of the XCodeAPI preset should switch to another provider.
---
## [3.13.0] - 2026-04-10
Development since v3.12.3 focuses on quota visibility, provider workflow upgrades, stronger proxy compatibility, and lower-overhead tray / session workflows.
### Added
- **Lightweight Mode**: Added a tray-only mode that destroys the main window and keeps CC Switch running from the system tray, with the window recreated when users reopen it.
- **Provider Model Auto-Fetch**: Added OpenAI-compatible `/v1/models` discovery for Claude, Codex, Gemini, OpenCode, and OpenClaw provider forms, including grouped dropdown selection and failure-specific error messages.
- **Quota & Balance Visibility**: Added inline quota or balance display for official Claude / Codex / Gemini providers, GitHub Copilot premium interactions, Codex OAuth providers, Token Plan providers (Kimi / Zhipu GLM / MiniMax), and official balance queries for DeepSeek, StepFun, SiliconFlow, OpenRouter, and Novita AI. Copilot / ChatGPT OAuth and CLI subscription quota now only auto-poll for the currently active provider, preventing unnecessary API calls and misleading displays on non-current cards.
- **Skills Discovery & Batch Updates**: Added SHA-256 based skill update detection, per-skill and batch update actions, a storage-location toggle between CC Switch and `~/.agents/skills`, and public `skills.sh` search integration.
- **Session Workflow Upgrades**: Added batch delete in Session Manager, a directory picker before launching Claude terminal restore commands, usage import from Claude / Codex / Gemini session logs without requiring proxy interception, and per-app usage filtering for Claude / Codex / Gemini dashboards.
- **Codex OAuth Reverse Proxy**: Added ChatGPT Plus / Pro based Codex OAuth reverse proxy support for Claude provider cards, including managed OAuth login and inline subscription quota display.
- **OpenCode / OpenClaw Stream Check Coverage**: Added OpenCode npm package mapping plus support for OpenClaw `openai-completions` and the remaining OpenClaw protocol variants in Stream Check.
- **Full URL Endpoint Mode**: Added a provider option that treats `base_url` as a complete upstream endpoint so proxy forwarding and stream checks can work with vendors that require nonstandard URL layouts.
- **OpenCode StepFun Step Plan Preset**: Added a StepFun Step Plan provider preset for OpenCode.
- **Copilot Interaction Optimizer**: Added request classification and routing logic to reduce unnecessary GitHub Copilot premium interaction consumption.
- **First-Run Welcome Dialog**: Added a one-time welcome dialog on fresh installs explaining how existing configuration is preserved as a default provider and how the bundled official preset enables one-click revert. Upgrade users are excluded.
- **Official Provider Seeding**: Added automatic seeding of Claude Official, OpenAI Official, and Google Official provider entries on startup, giving every user a one-click path back to the official endpoint.
- **OpenCode / OpenClaw Auto-Import**: Added automatic startup import of live OpenCode and OpenClaw provider configurations, matching the auto-import behavior already present for Claude, Codex, and Gemini.
- **Common Config Editor Guidance**: Added an informational guide and empty-state prompt to the Common Config snippet editor modal for Claude, Codex, and Gemini, with i18n support.
- **Common Config First-Run Notice**: Added a one-time informational dialog explaining Common Config Snippets when users first open the provider add/edit form.
- **Claude Session Titles**: Added meaningful title extraction for Claude sessions using a priority chain: custom-title metadata, first real user message, then directory basename fallback.
- **Session Search Highlighting**: Added keyword highlighting in session titles and messages during Session Manager search.
- **URL-Based Provider Icons**: Added a dual rendering mode to the icon system supporting Vite URL imports for large SVGs and raster images (PNG, JPG, WebP), keeping small SVGs inlined.
- **Kaku Terminal Support**: Added Kaku as a selectable terminal for session launch on macOS, reusing the WezTerm-compatible launch path.
- **OMO Slim Council Support**: Restored first-class council support as a built-in oh-my-opencode-slim agent with updated metadata and UI copy.
- **TheRouter Provider Preset**: Added TheRouter provider presets across Claude, Codex, Gemini, OpenCode, and OpenClaw.
- **DDSHub Provider Preset**: Added DDSHub as a third-party partner provider for Claude with icon and partner promotion text.
- **LionCCAPI Provider Preset**: Added LionCCAPI as a third-party partner provider across all five apps with anthropic-messages protocol for OpenCode and OpenClaw.
- **Shengsuanyun Provider Preset**: Added Shengsuanyun (胜算云) as an aggregator partner provider across all five apps with URL-based icon and localized display name.
- **PIPELLM Provider Preset**: Added PIPELLM provider preset across Claude, Codex, OpenCode, and OpenClaw with full model definitions and icon.
- **E-FlowCode Provider Preset**: Added E-FlowCode provider preset across all five apps with per-app protocol configuration.
### Changed
- **Tray Menu Organization**: Reworked the tray menu into per-app submenus to prevent overflow and make background provider switching scale better with larger provider lists.
- **Proxy Forwarding Stack**: Refactored proxy forwarding onto a Hyper-based client with transparent header forwarding, improved endpoint rewriting, and better support for dynamic upstream endpoints.
- **OAuth Auth Center UI Polish**: Tightened the Auth Center copy, layout, and icon presentation so the Codex OAuth login flow feels cleaner and less cluttered.
- **Provider Key Lifecycle & Live Sync**: Reworked additive provider create / rename / duplicate flows so live config writes, cleanup, and rollback stay consistent across OpenCode / OpenClaw and takeover scenarios.
- **Codex OAuth Defaults**: Updated the Codex OAuth preset to the GPT-5.4 model family.
### Fixed
- **Copilot Authentication & Proxy Compatibility**: Fixed GitHub Copilot authentication regressions, corrected enterprise / dynamic endpoint handling, repaired clipboard verification-code copying on macOS and Linux, and fixed Responses routing when Copilot-backed Claude providers target OpenAI models.
- **Streaming Parser Compatibility**: Fixed SSE parsing to accept fields with optional spaces, improving compatibility with non-strict streaming implementations.
- **UTF-8 Stream Chunk Boundaries**: Fixed intermittent garbled output (U+FFFD replacement characters) in Claude Code when multi-byte UTF-8 sequences such as Chinese characters or emoji were split across TCP stream chunks via the Copilot reverse proxy, by preserving incomplete trailing bytes across chunks in all four SSE streaming paths instead of lossy decoding.
- **Fragmented System Prompt Normalization**: Fixed strict OpenAI-compatible chat backends (Nvidia, Qwen-style) rejecting requests when converted Claude payloads contained multiple system messages, by merging system content into a single leading system message during the Anthropic → OpenAI chat transformation.
- **Provider Switch State Corruption**: Serialized per-app provider switches to prevent concurrent failover or hot-switch operations from leaving `is_current`, settings state, and live backup state out of sync.
- **Claude Takeover Live Config Drift**: Fixed provider edits while Claude takeover is active so live settings remain aligned with the latest provider state without breaking takeover restore behavior.
- **WebDAV Password Retention & Validation**: Fixed the WebDAV password field so saved credentials remain visible after refresh and treated `MKCOL 405` responses correctly during connection validation.
- **Provider Card Action States**: Fixed additive-mode highlight behavior, aligned usage display layout across provider cards, replaced hard proxy-switch blocking with a warning path, and disabled unsupported test / usage actions for Copilot and Codex OAuth cards.
- **Usage Accuracy & Pricing**: Fixed MiniMax quota math and 0%→100% progression, corrected CNY→USD pricing plus missing model definitions, improved Gemini session-log syncing, and resolved session-based usage entries being shown as unknown providers.
- **Usage Editor & Skills UI Regressions**: Fixed usage query fields being reset while editing extractor code, corrected broken `skills.sh` links and empty descriptions, and fixed auto-query defaults plus number-input clearing in usage configuration.
- **Chinese Skills Terminology**: Unified Skills-related labels across settings panels in the `zh` locale so storage and sync options use consistent wording.
- **Environment & Preset Compatibility**: Added Bun global bin detection in CLI scan, adapted to the oh-my-openagent rename with backward compatibility, corrected the OpenCode `kimi-for-coding` preset, gated Gemini keychain parsing to macOS, and fixed an OpenClaw serializer panic on empty collections.
- **Linux UI Unresponsive on Startup**: Fixed a bug where the window UI (including native title bar buttons) couldn't receive clicks on Linux until the user manually maximized and restored the window. Root causes: (1) Tauri webview did not acquire keyboard focus after `show()` on Linux, so the first click was consumed by X11/Wayland click-to-activate (Tauri #10746, wry #637); (2) GTK surface's input region failed to renegotiate on the `visible:false → show()` path under some WebKitGTK/compositor combinations, leaving the entire window unresponsive. Mitigations: set `WEBKIT_DISABLE_COMPOSITING_MODE=1` at startup, and added a new `linux_fix::nudge_main_window` helper that performs `set_focus` + a ±1px no-op resize ~200ms after show, equivalent to a visually invisible "maximize-and-restore". Wired into all window-re-show paths (normal startup, deeplink, single_instance, tray `show_main`, lightweight exit).
- **Linux Drag Region on Header**: Removed `data-tauri-drag-region` from the top header bar on Linux to avoid triggering `gtk_window_begin_move_drag` paths affected by Tauri #13440 under Wayland. macOS drag behavior is preserved.
- **OpenCode / OpenClaw Stream Check Edge Cases**: Fixed custom-header passthrough, OpenClaw custom auth-header detection, Bedrock error messaging, and OpenCode default `baseURL` fallback handling in Stream Check.
- **Duplicate Toast on Provider Switch**: Fixed double toast notifications (proxy-required warning followed by switch-success) when switching to Copilot, ChatGPT, or OpenAI-format providers with the proxy not running.
- **Session Search Accuracy & Chinese Support**: Fixed session search result truncation across providers and switched FlexSearch tokenizer to full mode for proper Chinese substring matching.
- **Adaptive Thinking Reasoning Effort**: Fixed `resolve_reasoning_effort()` mapping adaptive thinking to `xhigh` instead of incorrectly using `high` in OpenAI format conversions.
- **Thinking Model Fallback Display**: Fixed the Claude provider form showing an empty Thinking model field after saving only a main model by applying read-only fallback to ANTHROPIC_MODEL.
- **Auth Tab Localization**: Fixed missing i18n translation keys for the settings auth tab label across all locale bundles.
- **Schema Migration Guard**: Fixed database migrations failing when skills or model_pricing tables did not exist by adding table-existence checks before ALTER and UPDATE operations.
### Docs
- **User Manual Refresh**: Updated the EN / ZH / JA manuals for tray submenus, lightweight mode, provider model fetching, session management, workspace files, WebDAV v2 behavior, OpenCode / OpenClaw activation, and other provider workflow improvements.
- **Community & Contribution Docs**: Added `CONTRIBUTING.md`, `SECURITY.md`, `CODE_OF_CONDUCT.md`, bilingual issue / PR templates, Dependabot config, and CI quality checks.
- **Release Notes Risk Notice**: Added a Copilot reverse proxy risk notice and anchored highlight links in the v3.12.3 release notes across all three languages.
- **Sponsor Partners**: Added Shengsuanyun, LionCC, and DDS as sponsor partners in README across all languages.
---
## [3.12.3] - 2026-03-24
Major release adding GitHub Copilot reverse proxy support, macOS code signing & Apple notarization, intelligent reasoning effort mapping for o-series models, skill backup/restore lifecycle, proxy gzip compression, and critical fixes for WebDAV password safety, tool message parsing, and dark mode.
**Stats**: 36 commits | 107 files changed | +9,124 insertions | -802 deletions
### Added
- **GitHub Copilot Reverse Proxy**: Full GitHub Copilot integration as a Claude Code provider via OAuth Device Code flow; includes multi-account management, automatic token refresh, Anthropic ↔ OpenAI format conversion, real-time model list fetching, and usage statistics (#930)
- **Copilot Auth Center**: New Auth Center panel in Settings for managing GitHub accounts globally, with per-provider account binding via `meta.authBinding`
- **Tool Search Toggle**: Added `ENABLE_TOOL_SEARCH` env var support for Claude 2.1.76+; exposed as a checkbox in the provider Common Config editor (#930)
- **Reasoning Effort Mapping**: Two-tier `resolve_reasoning_effort()` for OpenAI o-series and GPT-5+ models — explicit `output_config.effort` takes priority, falling back to thinking `budget_tokens` thresholds (<4 000→low, 4 00016 000→medium, ≥16 000→high); covers both Chat Completions and Responses API paths with 17 unit tests
- **OpenCode SQLite Backend**: Added SQLite session storage support for OpenCode alongside existing JSON backend; dual-backend scan with SQLite priority on ID conflicts, atomic session deletion, and path validation (#1401)
- **Skill Auto-Backup**: Skill files are automatically backed up to `~/.cc-switch/skill-backups/` before uninstall, with metadata preserved in `meta.json`; old backups pruned to keep at most 20
- **Skill Backup Restore & Delete**: Added list/restore/delete commands for skill backups; restore copies files back to SSOT, saves the DB record, and syncs to the current app with rollback on failure
- **macOS Code Signing & Notarization**: CI now imports an Apple Developer ID certificate, signs the universal binary, submits for Apple notarization, and staples the ticket to both `.app` and `.dmg`; a hard-fail verification step (`codesign --verify` + `spctl -a` + `stapler validate`) gates the release for both artifacts
- **Codex 1M Context Window Toggle**: One-click checkbox in Codex config editor to set `model_context_window = 1000000` with auto-populated `model_auto_compact_token_limit = 900000`; unchecking removes both fields
- **Disable Auto-Upgrade Toggle**: Added `DISABLE_AUTOUPDATER` env var checkbox in the Claude Common Config editor to prevent Claude Code from auto-upgrading
### Changed
- **Skills Cache Strategy**: Replaced `invalidateQueries` with direct `setQueryData` updates for skill install/uninstall/import operations; added `staleTime: Infinity` with `keepPreviousData` to eliminate loading flicker (#1573)
- **Proxy Gzip Compression**: Non-streaming proxy requests now auto-negotiate gzip compression instead of forcing `identity`; streaming requests conservatively keep `identity` to avoid SSE decompression errors
- **o1/o3 Model Compatibility**: Chat Completions proxy forwarding now correctly uses `max_completion_tokens` instead of `max_tokens` for OpenAI o-series models such as o1/o3/o4-mini (#1451)
- **OpenCode Model Variants**: Placed OpenCode model variants at top level instead of inside options for better discoverability (#1317)
- **Skills Import Flow**: Replaced implicit filesystem-based app inference with explicit `ImportSkillSelection` to prevent incorrect multi-app activation; added reconciliation to remove disabled/orphaned symlinks and MCP servers from live config
- **Claude 4.6 Context Window**: Updated Claude Opus 4.6 and Sonnet 4.6 context window from 200K to 1M across OpenClaw and OpenCode presets (GA release)
- **MiniMax Model Upgrade**: Updated MiniMax presets from M2.5 to M2.7 across Claude, OpenClaw, and OpenCode configurations with updated partner descriptions in all three locales
- **Xiaomi MiMo Model Upgrade**: Updated MiMo presets from mimo-v2-flash to mimo-v2-pro across all supported applications
- **AddProviderDialog Simplification**: Removed redundant OAuth tab, reducing dialog from 3 tabs to 2 (app-specific + universal)
- **Provider Form Advanced Options Collapse**: Model mapping, API format, and other advanced fields in the Claude provider form now auto-collapse when empty; auto-expands when any value is set or when a preset fills them in
### Fixed
- **WebDAV Password Silent Clear**: Fixed WebDAV password being silently wiped when ProviderList or UsageScriptModal saved settings by stripping `webdavSync` from frontend payloads and adding backend backfill logic in `merge_settings_for_save()` to preserve existing passwords
- **Tool Message Parsing**: Fixed tool_use/tool_result message classification across Claude (tool_result content blocks), Codex (function_call/function_call_output payloads), and Gemini (array content + toolCalls extraction) session providers (#1401)
- **Dark Mode Selector**: Changed Tailwind `darkMode` from `["selector", "class"]` to `["selector", ".dark"]` to ensure correct dark mode activation (#1596)
- **Copilot Request Fingerprint**: Unified Copilot request fingerprint headers across all API call sites to prevent User-Agent leakage and stream check mismatches
- **o-series Responses API Tokens**: Kept Responses API on the correct `max_output_tokens` field for o-series models instead of incorrectly injecting `max_completion_tokens`
- **Provider Form Double Submit**: Prevented duplicate submissions on rapid button clicks in provider add/edit forms (#1352)
- **Ghostty Session Restore**: Fixed Claude session restore in Ghostty terminal (#1506)
- **Skill ZIP Import Extension**: Added `.skill` file extension support in ZIP import dialog (#1240, #1455)
- **Skill ZIP Install Target App**: ZIP skill installs now use the currently active app instead of always defaulting to Claude
- **OpenClaw Active Card Highlight**: Fixed active OpenClaw provider card not being highlighted (#1419)
- **Responsive Layout with TOC**: Improved responsive design when TOC title exists (#1491)
- **Import Skills Dialog White Screen**: Added missing TooltipProvider in ImportSkillsDialog to prevent runtime crash when opening the dialog
- **Panel Bottom Blank Area**: Replaced hardcoded `h-[calc(100vh-8rem)]` with `flex-1 min-h-0` across all content panels to eliminate bottom gap caused by mismatched offset values
### Docs
- **Pricing Model ID Normalization**: Added documentation section explaining model ID normalization rules (prefix stripping, suffix trimming, `@``-` replacement) in EN/ZH/JA user manuals (#1591)
- **macOS Signed & Notarized**: Removed all `xattr` workaround instructions and "unidentified developer" warnings from README, README_ZH, installation guides (EN/ZH/JA), and FAQ pages (EN/ZH/JA); replaced with "signed and notarized by Apple" messaging
---
## [3.12.2] - 2026-03-12
Post-v3.12.1 work focuses on Common Config safety during proxy takeover and more reliable Codex TOML editing.
**Stats**: 5 commits | 22 files changed | +1,716 insertions | -288 deletions
### Added
- **Empty State Guidance**: Improved first-run experience with detailed import instructions and a conditional Common Config snippet hint for Claude/Codex/Gemini providers
### Changed
- **Proxy Takeover Restore Flow**: Proxy takeover hot-switch and provider sync now refresh the restore backup instead of overwriting live config files, rebuilding effective provider settings with Common Config applied so rollback preserves the real user configuration
- **Codex TOML Editing Engine**: Refactored Codex `config.toml` updates onto shared section-aware TOML helpers in Rust and TypeScript, covering `base_url` and `model` field edits across provider forms and takeover cleanup
- **Common Config Initialization Lifecycle**: Startup now auto-extracts Common Config snippets from clean live configs before takeover restoration, tracks explicit "snippet cleared" state, and persists a one-time legacy migration flag to avoid repeated backfills
### Fixed
- **Common Config Loss During Takeover**: Fixed cases where proxy takeover could drop Common Config changes, overwrite live configs during sync, or produce incomplete restore snapshots when switching providers
- **Codex Restore Snapshot Preservation**: Fixed Codex takeover restore backups so existing `mcp_servers` blocks survive provider hot-switches instead of being discarded; changed MCP backup preservation from wholesale table replacement to per-server-id merge so provider/common-config MCP updates win on conflict while live-only servers are retained
- **Cleared Snippet Resurrection**: Fixed startup auto-extraction recreating Common Config snippets that users had intentionally cleared
- **Codex `base_url` Misplacement**: Fixed Codex `base_url` extraction and editing to target the active `[model_providers.<name>]` section instead of appending to the file tail or confusing `mcp_servers.*.base_url` entries for provider endpoints
---
## [3.12.1] - 2026-03-12
### Patch Release
Stability-focused patch release fixing the Common Config modal infinite reopen loop, a WebDAV sync foreign key constraint failure, several i18n interpolation issues, and a Windows toolbar compact mode bug. Also adds **StepFun** provider presets, **OpenClaw input type selection** and **authHeader** support, upgrades Gemini to **3.1-pro**, and welcomes four new sponsor partners.
**Stats**: 19 commits | 56 files changed | +1,429 insertions | -396 deletions
### Added
#### Provider Presets
- **StepFun**: Added StepFun (阶跃星辰) provider presets including the step-3.5-flash model across supported applications (#1369, thanks @hengm3467)
#### OpenClaw Enhancements
- **Input Type Selection**: Added input type selection dropdown for model Advanced Options in OpenClaw configuration form (#1368, thanks @liuxxxu)
- **authHeader Field**: Added optional `authHeader` boolean to OpenClawProviderConfig for vendor-specific auth header support (e.g. Longcat), and refactored form state to reuse the shared type
#### Sponsor Partners
- **Micu API**: Added Micu API as sponsor partner with affiliate links
- **XCodeAPI**: Added XCodeAPI as sponsor partner
- **SiliconFlow**: Added SiliconFlow (硅基流动) as sponsor partner with affiliate links
- **CTok**: Added CTok as sponsor partner
### Changed
- **UCloud → Compshare**: Renamed UCloud provider to Compshare (优云智算) with full i18n support across all three locales (EN/ZH/JA)
- **Compshare Links**: Updated Compshare sponsor registration links to coding-plan page
- **Gemini Model Upgrade**: Upgraded default Gemini model from 2.5-pro to 3.1-pro in provider presets
### Fixed
#### Common Config & UI
- **Common Config Modal Loop**: Fixed an infinite reopen loop in the Common Config modal and added draft editing support to prevent data loss during edits
- **Toolbar Compact Mode (Windows)**: Fixed toolbar compact mode not triggering on Windows due to left-side overflow (#1375, thanks @zuoliangyu)
- **Session Search Index**: Fixed session search index not syncing with query data, causing stale list display after session deletion
#### Sync & Data
- **WebDAV Provider Health FK**: Fixed foreign key constraint failure when restoring `provider_health` table during WebDAV sync
#### Provider & Preset
- **Longcat authHeader**: Added missing `authHeader: true` to Longcat provider preset (#1377, thanks @wavever)
- **OpenClaw Tool Permissions**: Aligned OpenClaw tool permission profiles with upstream schema (#1355, thanks @bigsongeth)
- **X-Code API URL**: Corrected X-Code API URL from `www.x-code.cn` to `x-code.cc`
#### i18n & Localization
- **Stream Check Toast**: Fixed stream check toast i18n interpolation keys not matching translation placeholders
- **Proxy Startup Toast**: Fixed proxy startup toast not interpolating address and port values (#1399, thanks @Mason-mengze)
- **OpenCode API Format Label**: Renamed OpenCode API format label from "OpenAI" to "OpenAI Responses" for accuracy
---
## [3.12.0] - 2026-03-09
### Feature Release
This release restores the **Model Health Check (Stream Check)** UI, adds **OpenAI Responses API** format conversion, introduces the **Bedrock Optimizer** for thinking + cache injection, expands provider presets (Ucloud, Micu, X-Code API, Novita, Bailian For Coding), overhauls **OpenClaw config panels** with a JSON5 round-trip write engine, enhances **WebDAV sync** with dual-layer versioning, and delivers a comprehensive **i18n audit** fixing 69 missing keys alongside 20+ bug fixes.
**Stats**: 56 commits | 221 files changed | +20,582 insertions | -8,026 deletions
### Added
#### Stream Check (Model Health Check)
- **Restore Stream Check UI**: Brought back the model health check (Stream Check) panel for testing provider endpoint availability with live streaming validation
- **First-Run Confirmation**: Added a confirmation dialog on first use of Stream Check to inform users about the feature's purpose and network requests
- **OpenAI Chat Format Support**: Stream Check now supports `openai_chat` api_format, enabling health checks for providers using OpenAI-compatible endpoints
#### OpenAI Responses API
- **Responses API Format Conversion**: New `api_format = "openai_responses"` option enabling Anthropic Messages ↔ OpenAI Responses API bidirectional conversion for providers that implement the Responses API
- **Responses API Deduplication**: Deduplicated and improved the Responses API conversion logic, consolidating shared transformation code
#### Bedrock Optimizer
- **Bedrock Request Optimizer**: PRE-SEND optimizer that injects thinking parameters and cache control blocks into AWS Bedrock requests, enabling extended thinking and prompt caching on Bedrock endpoints (#1301)
#### OpenClaw Enhancements
- **JSON5 Round-Trip Write Engine**: Overhauled OpenClaw config panels with a JSON5 round-trip write engine that preserves comments, formatting, and ordering when saving configuration changes
- **Config Panel Improvements**: Redesigned EnvPanel as a full JSON editor, added `tools.profile` selection to ToolsPanel, introduced OpenClawHealthBanner for config validation warnings, and added legacy timeout migration support in Agents Defaults
- **Agent Model Dropdown**: Replaced text inputs with dropdown selects for OpenClaw agent model configuration, offering a curated list of available models
- **User-Agent Toggle**: Added a User-Agent header toggle for OpenClaw, defaulting to off to avoid potential compatibility issues with certain providers
#### Provider Presets
- **Ucloud**: Added Ucloud partner provider preset for Claude, Codex, and OpenClaw with endpointCandidates, unified apiKeyUrl, refreshed model defaults, and OpenClaw `templateValues` / `suggestedDefaults`
- **Micu**: Added Micu partner provider preset for Claude, Codex, OpenClaw, and OpenCode with OpenClaw `templateValues` / `suggestedDefaults`
- **X-Code API**: Added X-Code API partner provider preset for Claude, Codex, and OpenCode with endpointCandidates
- **Novita**: Added Novita provider presets and icon across all supported apps (#1192)
- **Bailian For Coding**: Added Bailian For Coding preset configuration (#1263)
- **SiliconFlow Partner Badge**: Added partner badge designation for SiliconFlow provider presets
- **Model Role Badges**: Added model role badges (e.g., Opus, Sonnet) to provider presets and reordered presets to prioritize Opus models
#### WebDAV Sync
- **Dual-Layer Versioning**: Added protocol v2 + db-v6 dual-layer versioning to WebDAV sync, enabling backward-compatible sync format evolution and automatic migration detection
- **Auto-Sync Confirmation**: Added a confirmation dialog when toggling WebDAV auto-sync on/off to prevent accidental changes
#### Usage & Data
- **Daily Rollups & Auto-Vacuum**: Added usage daily rollups for aggregated statistics, incremental auto-vacuum for storage management, and sync-aware backup that coordinates with WebDAV sync cycles
- **UsageFooter Extra Fields**: Added extra field display in UsageFooter component for normal mode, showing additional usage metadata (#1137)
#### Session Management
- **Session Deletion**: Added session deletion with per-provider cleanup and path safety validation, allowing users to remove individual conversation sessions
#### UI & Config
- **Auth Field Selector**: Restored Claude provider auth field selector supporting both AUTH_TOKEN and API_KEY authentication modes
- **Failover Toggle**: Moved failover toggle to display independently on the main page with a confirmation dialog for enabling/disabling
- **Common Config Auto-Extract**: Auto-extract Common Config Snippets from live configuration files on first run, seeding initial common config without manual setup
- **New Provider Page Improvements**: Improved the new provider page with API endpoint and model name fields (#1155)
### Changed
#### Architecture
- **Common Config Runtime Overlay**: Common Config is now applied as a runtime overlay during provider switching instead of being materialized (merged) into each provider's stored config. This preserves the original provider config in the database and applies common settings dynamically at write time
- **First-Run Auto-Extract**: On first run, Common Config Snippets are automatically extracted from the current live configuration files, eliminating the need for manual initial setup
### Fixed
#### Proxy & Streaming
- **OpenAI Streaming Conversion**: Fixed OpenAI ChatCompletion → Anthropic Messages streaming conversion that could produce malformed events under certain response structures
- **Codex /responses/compact Route**: Added support for Codex `/responses/compact` route in proxy forwarding (#1194)
- **Codex Common Config TOML Merge**: Fixed Codex Common Config to use structural TOML merge/subset instead of raw string comparison, correctly handling key ordering and formatting differences
- **Proxy Forwarder Failure Logs**: Improved proxy forwarder failure logging with more descriptive error messages
#### Provider & Preset
- **X-Code Rename**: Renamed "X-Code" provider to "X-Code API" for consistency with the official branding
- **SSSAiCode Missing /v1**: Added missing `/v1` path to SSSAiCode default endpoint for Codex and OpenCode
- **AICoding URL Fix**: Removed `www` prefix from aicoding.sh provider URLs to match the correct domain
- **New Provider Page Input Handling**: Fixed the new provider page so API endpoint / model fields handle line-break deletion correctly and added the missing `codexConfig.modelNameHint` i18n key for zh/en/ja
#### Platform
- **Cache Hit Token Statistics**: Fixed missing token statistics for cache hits in streaming responses (#1244)
- **Minimize-to-Tray Auto Exit**: Fixed issue where the application would automatically exit after being minimized to the system tray for a period of time (#1245)
#### i18n & Localization
- **Comprehensive i18n Audit**: Added 69 missing i18n keys and fixed hardcoded Chinese strings across the application, improving localization coverage for all three languages (zh/en/ja)
- **Model Test Panel i18n**: Corrected i18n key paths for model test panel title and description
- **JSON5 Slash Escaping**: Normalized JSON5 slash escaping and added i18n support for OpenClaw panel labels
#### UI
- **Skills Count Display**: Fixed skills count not displaying correctly when adding new skills (#1295)
- **Endpoint Speed Test**: Removed HTTP status code display from endpoint speed test results to reduce visual noise
- **Outline Button Text Tone**: Aligned outline button text color tone with usage refresh control for visual consistency (#1222)
### Performance
- **OpenClaw Config Write Skip**: Skip backup and atomic write when OpenClaw configuration content is unchanged, avoiding unnecessary I/O operations
### Documentation
- **User Manual i18n**: Restructured user manual for internationalization and added complete EN/JA translations alongside the existing ZH documentation
- **User Manual OpenClaw**: Added OpenClaw coverage and completed settings documentation for the user manual
- **UCloud CompShare Sponsor**: Added UCloud CompShare as a sponsor partner
- **Docs Directory Reorganization**: Reorganized docs directory structure, added user manual links to all three README files, removed cross-language links from user manual sections, and synced README features across EN/ZH/JA
### Maintenance
- **Periodic Maintenance Timer**: Consolidated periodic maintenance timers into a unified scheduler, combining vacuum and rollup operations into a single timer
- **OpenClaw Save Toast**: Removed backup path display from OpenClaw save toasts for cleaner notification messages
---
## [3.11.1] - 2026-02-28
### Hotfix Release
This release reverts the Partial Key-Field Merging architecture introduced in v3.11.0, restoring the proven "full config overwrite + Common Config Snippet" mechanism, and fixes several UI and platform compatibility issues.
**Stats**: 8 commits | 52 files changed | +3,948 insertions | -1,411 deletions
### Reverted
- **Restore Full Config Overwrite + Common Config Snippet** (revert 992dda5c): Reverted the partial key-field merging refactoring from v3.11.0 due to critical issues — non-whitelisted custom fields were lost during provider switching, backfill permanently stripped non-key fields from the database, and the whitelist required constant maintenance. Restores full config snapshot write, Common Config Snippet UI and backend commands, and 6 frontend components/hooks
### Changed
- **Proxy Panel Layout**: Moved proxy on/off toggle from accordion header into panel content area, placed directly above app takeover options, ensuring users see takeover configuration immediately after enabling the proxy
- **Manual Import for OpenCode/OpenClaw**: Removed auto-import on startup; empty state now shows an "Import Current Config" button, consistent with Claude/Codex/Gemini behavior
### Fixed
- **"Follow System" Theme Not Auto-Updating**: Delegated to Tauri's native theme tracking (`set_window_theme(None)`) so the WebView's `prefers-color-scheme` media query stays in sync with OS theme changes
- **Compact Mode Cannot Exit**: Restored `flex-1` on `toolbarRef` so `useAutoCompact`'s exit condition triggers correctly based on available width instead of content width
- **Proxy Takeover Toast Shows {{app}}**: Added missing `app` interpolation parameter to i18next `t()` calls for proxy takeover enabled/disabled messages
- **Windows Protocol Handler Side Effects**: Disabled environment check and one-click install on Windows to prevent unintended protocol handler registration
---
## [3.11.0] - 2026-02-26
### Feature Release
This release introduces **OpenClaw** as the fifth supported application, a full **Session Manager** for browsing conversation history across all apps, an independent **Backup Management** panel, **Oh My OpenCode (OMO)** integration, and 50+ other features, fixes, and improvements across 147 commits.
**Stats**: 147 commits | 274 files changed | +32,179 insertions | -5,467 deletions
### Added
#### OpenClaw Support (New Application)
- **OpenClaw Integration**: Full management support for OpenClaw as the fifth application in CC Switch, including provider switching, configuration panels (Env / Tools / Agents Defaults), Workspace file management (HEARTBEAT / BOOTSTRAP / BOOT), daily memory files, and additive overlay mode
- **OpenClaw Provider Presets**: 13+ built-in provider presets with brand icon and complete i18n (zh/en/ja)
- **OpenClaw Form Fields**: Dedicated provider form with providerKey input, model allowlist auto-registration, and default model button
- **OpenClaw Config Panels**: Env editor, Tools editor, and Agents Defaults editor backed by JSON5 read/write (`openclaw_config.rs`)
#### Session Manager
- **Session Manager**: Browse and search conversation history for Claude Code, Codex, Gemini CLI, OpenCode, and OpenClaw with table-of-contents navigation and in-session search
- **Session App Filter**: Auto-filter sessions by current app when entering the session page
- **Session Performance**: Parallel directory scanning and head-tail JSONL reading for faster session list loading
#### Backup Management
- **Backup Panel**: Independent backup management panel with configurable backup policy (max count, auto-cleanup) and backup rename support
- **Periodic Backup**: Hourly automatic backup timer during runtime
- **Pre-Migration Backup**: Automatic backup before database schema migrations with backfill warning
- **Delete Backup**: Delete individual backup files with confirmation dialog
- **Backup Time Fix**: Use local time instead of UTC for backup file names
#### Oh My OpenCode (OMO)
- **OMO Integration**: Full Oh My OpenCode config file management with agent model selection, category configuration, and recommended model fill
- **OMO Slim**: Lightweight oh-my-opencode-slim mode support with OmoVariant parameterization
- **OMO Cross-Exclusion**: Enforce OMO ↔ OMO Slim mutual exclusion at the database level
#### Workspace
- **Daily Memory Search**: Full-text search across daily memory files with date-sorted display
- **Clickable Paths**: Directory paths in workspace panels are now clickable; renamed “Today's Note” to “Add Memory”
- **Workspace Files Panel**: Manage bootstrap markdown files for OpenClaw (HEARTBEAT / BOOTSTRAP / BOOT types)
#### Provider Presets
- **AWS Bedrock**: Support for AKSK and API Key authentication modes (Claude and OpenCode)
- **SSAI Code**: Partner provider preset across all five apps
- **CrazyRouter**: Partner provider preset with custom icon
- **AICoding**: Partner provider preset with i18n promotion text
- **Bailian**: Renamed from Qwen Coder with new icon; updated domestic model providers to latest versions
#### Proxy & Network
- **Thinking Budget Rectifier**: New rectifier for thinking budget parameters with dedicated module (`thinking_budget_rectifier.rs`)
- **WebDAV Auto Sync**: Automatic periodic sync with large file protection mechanism
#### UI & UX
- **Theme Animation**: Circular reveal animation when toggling between light and dark themes
- **Claude Quick Toggles**: Quick toggle switches in the Claude config JSON editor for common settings
- **Dynamic Endpoint Hint**: Context-aware hint text in endpoint input based on API format selection
- **AppSwitcher Auto Compact**: Automatically collapse to compact mode based on available width, with smooth transition animation
- **App Transition**: Fade-in/fade-out animation when switching between OpenClaw and other apps
- **Silent Startup Conditional**: Show silent startup option only when launch-on-startup is enabled
#### Settings & Environment
- **First-Run Confirmation**: Confirmation dialogs for proxy and usage features on first use
- **Local Proxy Toggle**: `enableLocalProxy` setting to control proxy UI visibility on the home page
- **Environment Check**: More granular local environment detection (installed CLI tool versions, Volta path detection)
#### Usage & Pricing
- **Usage Dashboard Enhancement**: Auto-refresh control, robust formatting, and request log table improvements
- **New Model Pricing**: Added pricing data for claude-opus-4-6 and gpt-5.3-codex with incremental data seeding
### Changed
#### Architecture
- **Partial Key-Field Merging (⚠️ Breaking, reverted in v3.11.1)**: Provider switching now uses partial key-field merging instead of full config overwrite, preserving user's non-provider settings (plugins, MCP, permissions). The "Common Config Snippet" feature has been removed as it is no longer needed. Removes 6 frontend files and ~150 lines of backend dead code (#1098)
- **Manual Import**: Replaced auto-import on startup with manual “Import Current Config” button in empty state, reducing ~47 lines of startup code
- **OMO Variant Parameterization**: Eliminated ~250 lines of OMO/OMO Slim code duplication via `OmoVariant` struct with STANDARD/SLIM constants
- **OMO Common Config Removal**: Removed the two-layer merge system for OMO common config (-1,733 lines across 21 files)
#### Code Quality
- **ProviderForm Decomposition**: Extracted ProviderForm.tsx from 2,227 lines to 1,526 lines by splitting into 5 focused modules (opencodeFormUtils, useOmoModelSource, useOpencodeFormState, useOmoDraftState, useOpenclawFormState)
- **Shared MCP/Skills Components**: Extracted AppCountBar, AppToggleGroup, and ListItemRow shared components to eliminate duplication across MCP and Skills panels
- **OpenClaw TanStack Query Migration**: Migrated Env, Tools, and AgentsDefaults panels from manual useState/useEffect to centralized TanStack Query hooks
#### Settings Layout
- **Proxy Tab**: Split Advanced tab into dedicated Proxy tab (local proxy, failover, rectifiers, global outbound proxy); moved pricing config to Usage dashboard as collapsible accordion. SettingsPage reduced from ~716 to ~426 lines with 5-tab layout: General | Proxy | Advanced | Usage | About
- **Data Section Split**: Split data accordion into Import/Export and Cloud Sync sections for better discoverability
#### Terminal & Config
- **Unified Terminal Selection**: Consolidated terminal preference to global settings; added WezTerm support and terminal name mapping (iterm2 → iterm)
- **OpenClaw Agents Panel**: Primary model field set to read-only; detailed model fields (context window, max tokens, reasoning, cost) moved to advanced options
- **Claude Model Update**: Updated Claude model references from 4.5 to 4.6 across all provider presets
### Fixed
#### Critical
- **Windows Home Dir Regression**: Restored default home directory resolution on Windows to prevent providers/settings “disappearing” when `HOME` env var differs from the real user profile directory (Git/MSYS environments); auto-detects v3.10.3 legacy database location
- **Linux White Screen**: Disabled WebKitGTK hardware acceleration on AMD GPUs (Cezanne/Radeon Vega) to prevent EGL initialization failure causing blank screen on startup
- **OpenAI Beta Parameter**: Stopped appending `?beta=true` to OpenAI Chat Completions endpoints, fixing request failures for Nvidia and other `apiFormat=”openai_chat”` providers
- **Health Check Auth Mode**: Health check now respects provider's auth_mode setting instead of always using x-api-key header
#### Provider & Preset
- **OpenClaw /v1 Prefix**: Removed /v1 prefix from OpenClaw anthropic-messages presets to prevent double path (/v1/v1/messages) with Anthropic SDK auto-append
- **Opus Pricing**: Corrected Opus pricing from $15/$75 to $5/$25 and upgraded model ID to claude-opus-4-6
- **AIGoCode URLs**: Unified API base URL to https://api.aigocode.com across all apps; removed trailing /v1 suffix
- **Zhipu GLM**: Removed outdated partner status from Claude, OpenCode, and OpenClaw presets
- **API Key Visibility**: Restored API Key input field when creating new Claude providers (was incorrectly hidden for non-cloud_provider categories)
#### OMO / OMO Slim
- **OMO Slim Category Checks**: Added missing omo-slim category checks across add/form/mutation paths
- **OMO Slim Cache Invalidation**: Invalidate OMO Slim query cache after provider mutations to prevent stale UI state
- **OMO Recommended Models**: Synced agent/category recommended models with upstream sources; fixed provider/model format to pure model IDs
- **OMO Fill Feedback**: Added toast feedback when “Fill Recommended” button silently fails
- **OMO Last-Provider Restriction**: Removed last-provider deletion restriction for OMO/OMO Slim plugins
- **OpenCode Model Validation**: Reject saving OpenCode providers without at least one configured model
#### OpenClaw
- **OpenClaw P0-P3 Fixes**: Fixed 25 missing i18n keys, replaced key={index} with stable crypto.randomUUID(), excluded openclaw from ProxyToggle/FailoverToggle, added deep link merge_additive_config(), unified serde(flatten) naming, added directory existence checks, removed dead code, added duplicate key validation
- **OpenClaw Robustness**: Fixed EnvPanel visibleKeys using entry key names instead of array indices; added NaN guards; validated provider ID and model before import
- **OpenClaw i18n Dedup**: Merged duplicate openclaw i18n keys to restore provider form translations
#### Platform
- **Window Flash**: Prevented window flicker on silent startup (Windows)
- **Title Bar Theme**: Title bar now follows dark/light mode theme changes
- **Skills Path Separator**: Fixed path separator matching for skill installation status on Windows (supports both `/` and `\`)
- **WSL Conditional Compilation**: Added `#[cfg(target_os = “windows”)]` to WSL helper functions to eliminate dead_code warnings on non-Windows platforms
#### UI
- **Toolbar Clipping**: Removed toolbar height limit that was clipping AppSwitcher
- **Update Badge**: Show update badge instead of green check when a newer version is available
- **Session Button Visibility**: Only show Session Manager button for Claude and Codex apps
- **Directory Spacing**: Added vertical spacing between directory setting sections
- **Dark Mode Cards**: Unified SQL import/export card styling in dark mode
- **OpenClaw Scroll**: Enabled scrolling for OpenClaw configuration panel content
#### i18n & Localization
- **Session Manager i18n**: Replaced hardcoded Chinese strings with i18n keys for relative time, role labels, and UI elements
- **OpenClaw Default Model Label**: Renamed “Enable/Default” to “Set as Default / Current Default” with wider button
- **Daily Memory Sort**: Sort daily memory files by filename date (YYYY-MM-DD.md) instead of modification time
- **Backup Name i18n**: Use local time for backup file names
#### Other
- **Skill Doc URL**: Use actual branch from download_repo for documentation URL; switched from /tree/ to /blob/ pointing to SKILL.md
- **OpenCode Install Detection**: Added install.sh priority paths (OPENCODE_INSTALL_DIR > XDG_BIN_DIR > ~/bin > ~/.opencode/bin) with path dedup and cross-platform executable candidates
- **Provider Auto-Import**: Removed auto-import side effect from useProvidersQuery queryFn; users now trigger import manually via empty state button
- **Manual Backup Validation**: Treat missing database file as error during manual backup to prevent false success toast
### Performance
- **Session Panel Loading**: Parallel directory scanning and head-tail JSONL reading for Codex, OpenClaw, and OpenCode session providers
- **Query Cache Cleanup**: Removed unnecessary TanStack Query cache overhead for Tauri local IPC calls
### Documentation
- **Sponsors**: Added/updated SSSAiCode, Crazyrouter, AICoding, Right Code, and MiniMax sponsor entries across all README languages
- **User Manual**: Added user manual documentation (#979)
### Maintenance
- **Pre-Release Cleanup**: Removed debug logs, fixed clippy warnings, added missing Japanese translations, and formatted code
- **UI Exclusions**: Hidden MCP, Skills, proxy/pricing, stream check, and model test panels for OpenClaw where not applicable
---
@@ -450,7 +1228,7 @@ This beta release introduces the **Local API Proxy** feature, along with Skills
### Stats
- 51 commits since v3.7.1; 207 files changed; +17,297 / -6,870 lines. See [release-note-v3.8.0](docs/release-note-v3.8.0-en.md) for details.
- 51 commits since v3.7.1; 207 files changed; +17,297 / -6,870 lines. See [release-note-v3.8.0](docs/release-notes/v3.8.0-en.md) for details.
---
+175
View File
@@ -0,0 +1,175 @@
# Contributor Covenant Code of Conduct
> [中文版本](#贡献者公约行为准则)
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our community include:
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
- Focusing on what is best not just for us as individuals, but for the overall community
Examples of unacceptable behavior include:
- The use of sexualized language or imagery, and sexual attention or advances of any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email address, without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at **farion1231@gmail.com**. All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series of actions.
**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, available at [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at [https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations
---
# 贡献者公约行为准则
> [English Version](#contributor-covenant-code-of-conduct)
## 我们的承诺
身为社区成员、贡献者和领袖,我们承诺使社区参与者不受骚扰,无论其年龄、体型、可见或不可见的缺陷、族裔、性征、性别认同和表达、经验水平、教育程度、社会与经济地位、国籍、相貌、种族、种姓、肤色、宗教信仰、性倾向或性取向如何。
我们承诺以有助于建立开放、友善、多样化、包容、健康社区的方式行事和互动。
## 我们的准则
有助于为我们的社区创造积极环境的行为例子包括但不限于:
- 表现出对他人的同情和善意
- 尊重不同的主张、观点和感受
- 提出和大方接受建设性意见
- 承担责任并向受我们错误影响的人道歉
- 注重社区共同诉求,而非个人得失
不当行为例子包括:
- 使用情色化的语言或图像,及性引诱或挑逗
- 嘲弄、侮辱或诋毁性评论,以及人身或政治攻击
- 公开或私下的骚扰行为
- 未经他人明确许可,公布他人的私人信息,如物理或电子邮件地址
- 其他有理由认定为违反职业操守的不当行为
## 责任和权力
社区领袖有责任解释和落实我们所认可的行为准则,并妥善公正地对他们认为不当、威胁、冒犯或有害的任何行为采取纠正措施。
社区领袖有权力和责任删除、编辑或拒绝与本行为准则不相符的评论(comment)、提交(able)、代码、维基(wiki)编辑、议题(able)或其他贡献,并在适当时告知采取措施的理由。
## 适用范围
本行为准则适用于所有社区场合,也适用于在公共场所代表社区时的个人。
代表社区的情形包括使用官方电子邮件地址、通过官方社交媒体帐户发帖或在线上或线下活动中担任指定代表。
## 监督
辱骂、骚扰或其他不可接受的行为可通过 **farion1231@gmail.com** 向负责监督的社区领袖报告。所有投诉都将得到及时和公平的审查和调查。
所有社区领袖都有义务尊重任何事件报告者的隐私和安全。
## 处理方针
社区领袖将遵循下列社区处理方针来明确他们所认定违反本行为准则的行为的处理方式:
### 1. 纠正
**社区影响**:使用不恰当的语言或其他在社区中被认定为不符合职业道德或不受欢迎的行为。
**处理意见**:由社区领袖发出非公开的书面警告,明确说明违规行为的性质,并解释举止如何不妥。或将要求公开道歉。
### 2. 警告
**社区影响**:单个或一系列违规行为。
**处理意见**:警告并对连续性行为进行处理。在指定时间内,不得与相关人员互动,包括主动与行为准则执行者互动。这包括避免在社区场所和外部渠道中的互动。违反这些条款可能会导致临时或永久封禁。
### 3. 临时封禁
**社区影响**:严重违反社区准则,包括持续的不当行为。
**处理意见**:在指定时间内,暂时禁止与社区进行任何形式的互动或公开交流。在此期间,不得与相关人员进行公开或私下互动,包括主动与行为准则执行者互动。违反这些条款可能会导致永久封禁。
### 4. 永久封禁
**社区影响**:行为模式表现出违反社区准则,包括持续的不当行为、骚扰个人或攻击或贬低某个类别的个体。
**处理意见**:永久禁止在社区内进行任何形式的公开互动。
## 参见
本行为准则改编自 [Contributor Covenant][homepage] 2.1 版,参见 [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]。
社区处理方针灵感来源于 [Mozilla 的行为准则执行阶梯][Mozilla CoC]。
有关本行为准则的常见问题的答案,参见 [https://www.contributor-covenant.org/faq][FAQ]。其他语言翻译参见 [https://www.contributor-covenant.org/translations][translations]。
[homepage]: https://www.contributor-covenant.org
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations
+253
View File
@@ -0,0 +1,253 @@
# Contributing to CC Switch
> [中文版本](#贡献指南)
Thank you for your interest in contributing to CC Switch! Please read our [Code of Conduct](./CODE_OF_CONDUCT.md) before participating.
## How to Contribute
There are many ways to contribute:
- **Report bugs** — Found something broken? [Open a bug report](https://github.com/farion1231/cc-switch/issues/new?template=bug_report.yml).
- **Suggest features** — Have an idea? [Submit a feature request](https://github.com/farion1231/cc-switch/issues/new?template=feature_request.yml).
- **Improve docs** — Spot a typo or missing info? [Report a doc issue](https://github.com/farion1231/cc-switch/issues/new?template=doc_issue.yml).
- **Contribute code** — Fix bugs or implement features via pull requests.
- **Translate** — Help us improve translations for English, Chinese, and Japanese.
> **Security vulnerabilities**: Please do NOT use public issues. See our [Security Policy](./SECURITY.md) instead.
## Development Setup
### Prerequisites
- Node.js 18+ and pnpm 8+
- Rust 1.85+ and Cargo
- [Tauri 2.0 prerequisites](https://v2.tauri.app/start/prerequisites/)
### Quick Start
```bash
# Install dependencies
pnpm install
# Start development server with hot reload
pnpm dev
```
### Useful Commands
| Command | Description |
|---------|-------------|
| `pnpm dev` | Start dev server (hot reload) |
| `pnpm build` | Production build |
| `pnpm typecheck` | TypeScript type checking |
| `pnpm test:unit` | Run unit tests |
| `pnpm lint` | ESLint check |
| `pnpm format` | Format code (Prettier) |
| `pnpm format:check` | Check code formatting |
For Rust backend:
```bash
cd src-tauri
cargo fmt # Format Rust code
cargo clippy # Run linter
cargo test # Run tests
```
## Code Style
- **Frontend**: Prettier for formatting, ESLint for linting, strict TypeScript (`pnpm typecheck`)
- **Backend**: `cargo fmt` for formatting, `cargo clippy` for linting
- **Tauri 2.0**: Command names must use camelCase
Run all checks before submitting:
```bash
pnpm typecheck && pnpm format:check && pnpm test:unit
cd src-tauri && cargo fmt --check && cargo clippy && cargo test
```
## Pull Request Guidelines
1. **Open an issue first** for new features — PRs for features that are not a good fit may be closed.
2. **Fork and branch** — Create a feature branch from `main` (e.g., `feat/my-feature` or `fix/issue-123`).
3. **Keep PRs focused** — One feature or fix per PR. Avoid unrelated changes.
4. **Follow the PR template** — Fill in the summary, related issue, and checklist.
### PR Checklist
- [ ] `pnpm typecheck` passes
- [ ] `pnpm format:check` passes
- [ ] `cargo clippy` passes (if Rust code changed)
- [ ] Updated i18n files if user-facing text changed
### Commit Convention
We use [Conventional Commits](https://www.conventionalcommits.org/):
```
feat(provider): add support for new provider
fix(tray): resolve menu not updating after switch
docs(readme): update installation instructions
ci: add format check workflow
chore(deps): update dependencies
```
## AI-Assisted Contributions
We welcome AI-assisted contributions, but **the responsibility stays with you**. AI tools lower the cost of writing code — they do not lower the cost of reviewing it. Maintainers are not obligated to clean up AI-generated output.
By submitting a PR, you agree to the following:
1. **You have read and understood your code.** You must be able to explain any line in your PR. If you cannot, it is not ready for review.
2. **You have tested it yourself.** Every change must be verified locally — not just "it looks right." Do not submit code for platforms or features you cannot test.
3. **PRs must be small and focused.** One issue, one PR. Large, sprawling, multi-topic PRs will be closed.
4. **Open an issue first.** Drive-by PRs with no prior discussion — especially AI-generated ones — may be closed without review.
5. **Maintainers may close without explanation.** PRs that appear to be unreviewed AI output — hallucinated fixes, unnecessary refactors, bulk changes with no context — may be closed at the maintainer's discretion.
**In short**: AI is a tool, not a substitute for understanding. Use it to help you contribute better, not to shift work onto maintainers.
## Internationalization (i18n)
CC Switch supports three languages. When modifying user-facing text:
1. Update **all three** locale files:
- `src/locales/en/translation.json`
- `src/locales/zh/translation.json`
- `src/locales/ja/translation.json`
2. Use the `t()` function from i18next for all UI text.
3. Never hardcode user-facing strings.
## Questions?
- [Open a question](https://github.com/farion1231/cc-switch/issues/new?template=question.yml)
- [GitHub Discussions](https://github.com/farion1231/cc-switch/discussions)
---
# 贡献指南
> [English Version](#contributing-to-cc-switch)
感谢你对 CC Switch 的贡献兴趣!参与之前请阅读我们的[行为准则](./CODE_OF_CONDUCT.md)。
## 如何贡献
你可以通过多种方式参与贡献:
- **报告 Bug** — 发现问题?[提交 Bug 报告](https://github.com/farion1231/cc-switch/issues/new?template=bug_report.yml)。
- **建议功能** — 有想法?[提交功能请求](https://github.com/farion1231/cc-switch/issues/new?template=feature_request.yml)。
- **改进文档** — 发现错误或缺失?[报告文档问题](https://github.com/farion1231/cc-switch/issues/new?template=doc_issue.yml)。
- **贡献代码** — 通过 Pull Request 修复 Bug 或实现新功能。
- **翻译** — 帮助改进英文、中文和日文的翻译。
> **安全漏洞**:请不要使用公开 Issue 报告。请参阅我们的[安全策略](./SECURITY.md)。
## 开发环境搭建
### 前提条件
- Node.js 18+ 和 pnpm 8+
- Rust 1.85+ 和 Cargo
- [Tauri 2.0 开发环境](https://v2.tauri.app/start/prerequisites/)
### 快速开始
```bash
# 安装依赖
pnpm install
# 启动开发服务器(热重载)
pnpm dev
```
### 常用命令
| 命令 | 说明 |
|------|------|
| `pnpm dev` | 启动开发服务器(热重载) |
| `pnpm build` | 构建生产版本 |
| `pnpm typecheck` | TypeScript 类型检查 |
| `pnpm test:unit` | 运行单元测试 |
| `pnpm lint` | ESLint 检查 |
| `pnpm format` | 格式化代码(Prettier |
| `pnpm format:check` | 检查代码格式 |
Rust 后端命令:
```bash
cd src-tauri
cargo fmt # 格式化 Rust 代码
cargo clippy # 运行 Clippy 检查
cargo test # 运行测试
```
## 代码规范
- **前端**:使用 Prettier 格式化、ESLint 检查、严格 TypeScript`pnpm typecheck`
- **后端**:使用 `cargo fmt` 格式化、`cargo clippy` 检查
- **Tauri 2.0**:命令名必须使用 camelCase
提交前运行所有检查:
```bash
pnpm typecheck && pnpm format:check && pnpm test:unit
cd src-tauri && cargo fmt --check && cargo clippy && cargo test
```
## Pull Request 指南
1. **先开 Issue 讨论** — 新功能请先开 Issue,不适合项目方向的 PR 可能会被关闭。
2. **Fork 并创建分支** — 从 `main` 创建功能分支(如 `feat/my-feature``fix/issue-123`)。
3. **保持 PR 专注** — 每个 PR 只做一件事,避免无关改动。
4. **遵循 PR 模板** — 填写概述、关联 Issue 和检查清单。
### PR 检查清单
- [ ] `pnpm typecheck` 通过
- [ ] `pnpm format:check` 通过
- [ ] `cargo clippy` 通过(如修改了 Rust 代码)
- [ ] 如修改了用户可见文本,已更新国际化文件
### 提交信息规范
我们使用 [Conventional Commits](https://www.conventionalcommits.org/)
```
feat(provider): add support for new provider
fix(tray): resolve menu not updating after switch
docs(readme): update installation instructions
ci: add format check workflow
chore(deps): update dependencies
```
## AI 辅助贡献
我们欢迎 AI 辅助的贡献,但**责任始终在你身上**。AI 工具降低了写代码的成本,但并没有降低 review 的成本。维护者没有义务替你清理 AI 的产出。
提交 PR 即表示你同意以下规则:
1. **你已阅读并理解了你的代码。** 你必须能解释 PR 中的每一行。如果做不到,说明还没准备好提交 review。
2. **你已亲自测试过。** 每个改动都必须在本地验证——而不是"看起来对"。不要提交你自己无法测试的平台或功能的代码。
3. **PR 必须小而聚焦。** 一个 Issue 对应一个 PR。大而散、跨多个主题的 PR 会被直接关闭。
4. **先开 Issue 讨论。** 没有事先讨论的"路过式 PR"——尤其是 AI 生成的——可能会被直接关闭。
5. **维护者可以直接关闭。** 看起来是未经审阅的 AI 产出的 PR——虚构的修复、不必要的重构、缺乏上下文的批量改动——维护者可自行决定关闭。
**一句话总结**:AI 是工具,不是理解力的替代品。用它来帮助你更好地贡献,而不是把工作转移给维护者。
## 国际化(i18n
CC Switch 支持三种语言。修改用户可见文本时:
1. **同时更新三个**语言文件:
- `src/locales/en/translation.json`
- `src/locales/zh/translation.json`
- `src/locales/ja/translation.json`
2. 所有 UI 文本使用 i18next 的 `t()` 函数。
3. 不要硬编码用户可见的字符串。
## 有疑问?
- [提问](https://github.com/farion1231/cc-switch/issues/new?template=question.yml)
- [GitHub 讨论区](https://github.com/farion1231/cc-switch/discussions)
+252 -223
View File
@@ -1,30 +1,41 @@
<div align="center">
# All-in-One Assistant for Claude Code, Codex & Gemini CLI
# CC Switch
[![Version](https://img.shields.io/badge/version-3.10.2-blue.svg)](https://github.com/farion1231/cc-switch/releases)
### The All-in-One Manager for 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/endpoint?url=https://api.pinstudios.net/api/badges/downloads/farion1231/cc-switch/total)](https://github.com/farion1231/cc-switch/releases/latest)
[![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>
### 🌐 The Only Official Website: **[ccswitch.io](https://ccswitch.io)**
English | [中文](README_ZH.md) | [日本語](README_JA.md) | [Changelog](CHANGELOG.md)
</div>
## ❤️Sponsor
[![Zhipu GLM](assets/partners/banners/glm-en.jpg)](https://z.ai/subscribe?ic=8JVLJQFSKB)
> [Want to appear here?](mailto:farion1231@gmail.com)
This project is sponsored by Z.ai, supporting us with their GLM CODING PLAN.GLM CODING PLAN is a subscription service designed for AI coding, starting at just $3/month. It provides access to their flagship GLM-4.6 model across 10+ popular AI coding tools (Claude Code, Cline, Roo Code, etc.), offering developers top-tier, fast, and stable coding experiences.Get 10% OFF the GLM CODING PLAN with [this link](https://z.ai/subscribe?ic=8JVLJQFSKB)!
<details open>
<summary>Click to collapse</summary>
[![MiniMax](assets/partners/banners/minimax-en.jpeg)](https://platform.minimax.io/subscribe/coding-plan?code=ClLhgxr2je&source=link)
MiniMax-M2.7 is a next-generation large language model designed for autonomous evolution and real-world productivity. Unlike traditional models, M2.7 actively participates in its own improvement through agent teams, dynamic tool use, and reinforcement learning loops. It delivers strong performance in software engineering (56.22% on SWE-Pro, 55.6% on VIBE-Pro, 57.0% on Terminal Bench 2) and excels in complex office workflows, achieving a leading 1495 ELO on GDPval-AA. With high-fidelity editing across Word, Excel, and PowerPoint, and a 97% adherence rate across 40+ complex skills, M2.7 sets a new standard for building AI-native workflows and organizations.
[Click](https://platform.minimax.io/subscribe/coding-plan?code=ClLhgxr2je&source=link) to get an exclusive 12% off the MiniMax Token Plan!
---
<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>Thanks to PackyCode for sponsoring this project! PackyCode is a reliable and efficient API relay service provider, offering relay services for Claude Code, Codex, Gemini, and more. PackyCode provides special discounts for our software users: register using <a href="https://www.packyapi.com/register?aff=cc-switch">this link</a> and enter the "cc-switch" promo code during recharge to get 10% off.</td>
<td>Thanks to PackyCode for sponsoring this project! PackyCode is a reliable and efficient API relay service provider, offering relay services for Claude Code, Codex, Gemini, and more. PackyCode provides special discounts for our software users: register using <a href="https://www.packyapi.com/register?aff=cc-switch">this link</a> and enter the "cc-switch" promo code during first recharge to get 10% off.</td>
</tr>
<tr>
@@ -32,12 +43,34 @@ This project is sponsored by Z.ai, supporting us with their GLM CODING PLAN.GLM
<td>Thanks to AIGoCode for sponsoring this project! AIGoCode is an all-in-one platform that integrates Claude Code, Codex, and the latest Gemini models, providing you with stable, efficient, and highly cost-effective AI coding services. The platform offers flexible subscription plans, zero risk of account suspension, direct access with no VPN required, and lightning-fast responses. AIGoCode has prepared a special benefit for CC Switch users: if you register via <a href="https://aigocode.com/invite/CC-SWITCH">this link</a>, you'll receive an extra 10% bonus credit on your first top-up!</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>Thanks to Shengsuanyun for sponsoring this project! Shengsuanyun is a super factory serving AI Native Teams — an industrial-grade AI task parallel execution platform. Its model marketplace aggregates Claude, ChatGPT, Gemini, and other domestic and international LLM and multimedia model capabilities with direct supply. Absolutely no reverse engineering or dilution — platform-wide model SLA availability reaches 99.7%, with <a href="https://watch.shengsuanyun.com/status/shengsuanyun">monitoring dashboards</a> showing green across the board. It also offers enterprise-grade custom gateways for fine-grained team cost and permission management, smart routing, security protection, and BYOK (Bring Your Own Key) hosting. The platform charges on a pay-per-use and tokens plan (coming soon) basis, with invoicing available. Register via <a href="https://www.shengsuanyun.com/?from=CH_4HHXMRYF">this link</a> as a new user to receive ¥10 in credits plus a 10% bonus on your first top-up.</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>Thanks to AICodeMirror for sponsoring this project! AICodeMirror provides official high-stability relay services for Claude Code / Codex / Gemini CLI, with enterprise-grade concurrency, fast invoicing, and 24/7 dedicated technical support.
Claude Code / Codex / Gemini official channels at 38% / 2% / 9% of original price, with extra discounts on top-ups! AICodeMirror offers special benefits for CC Switch users: register via <a href="https://www.aicodemirror.com/register?invitecode=9915W3">this link</a> to enjoy 20% off your first top-up, and enterprise customers can get up to 25% off!</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>Thanks to PatewayAI for sponsoring this project! PatewayAI is an API relay service provider built for heavy AI developers, focused on directly relaying official high-quality model APIs. It offers the full Claude lineup and the Codex series, 100% sourced from official channels — no dilution, no fakes, verification welcome. Billing is transparent and every token-level invoice can be audited line by line.
It also supports enterprise-grade concurrency and provides a dedicated management platform for enterprise customers — formal contracts and invoicing are available; visit the official website for contact details.
Register now via <a href="https://pateway.ai/?ch=etzpm8&aff=WB6M6F67#/">this link</a> to receive $3 in trial credit. Top-ups go as low as 60% of the original price, with a two-way referral bonus of up to $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>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>
<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>Thanks to SiliconFlow for sponsoring this project! SiliconFlow is a high-performance AI infrastructure and model API platform, providing fast and reliable access to language, speech, image, and video models in one place. With pay-as-you-go billing, broad multimodal model support, high-speed inference, and enterprise-grade stability, SiliconFlow helps developers and teams build and scale AI applications more efficiently. Register via <a href="https://cloud.siliconflow.cn/i/drGuwc9k">this link</a> and complete real-name verification to receive ¥16 in bonus credit, usable across models on the platform. SiliconFlow is also now compatible with OpenClaw, allowing users to connect a SiliconFlow API key and call major AI models for free.</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>Thanks to Cubence for sponsoring this project! Cubence is a reliable and efficient API relay service provider, offering relay services for Claude Code, Codex, Gemini, and more with flexible billing options including pay-as-you-go and monthly plans. Cubence provides special discounts for CC Switch users: register using <a href="https://cubence.com/signup?code=CCSWITCH&source=ccs">this link</a> and enter the "CCSWITCH" promo code during recharge to get 10% off every top-up!</td>
@@ -48,13 +81,84 @@ Claude Code / Codex / Gemini official channels at 38% / 2% / 9% of original pric
<td>Thanks to DMXAPI for sponsoring this project! DMXAPI provides global large model API services to 200+ enterprise users. One API key for all global models. Features include: instant invoicing, unlimited concurrency, starting from $0.15, 24/7 technical support. GPT/Claude/Gemini all at 32% off, domestic models 20-50% off, Claude Code exclusive models at 66% off! <a href="https://www.dmxapi.cn/register?aff=bUHu">Register here</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>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>
</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>Thank you to Right Code for sponsoring this project! Right Code reliably provides routing services for models such as Claude Code, Codex, and Gemini, with both pay-as-you-go and monthly subscription billing options available. Invoices are available upon top-up, and enterprise and team users can receive dedicated one-on-one support. Right Code also offers an exclusive discount for CC Switch users: register via <a href="https://www.right.codes/register?aff=CCSWITCH">this link</a>, and with every top-up you will receive pay-as-you-go credit equivalent to 5% of the amount paid.</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>Thanks to SSSAiCode for sponsoring this project! SSSAiCode is a stable and reliable API relay service, dedicated to providing stable, reliable, and affordable Claude and Codex model services, with same-day fast invoicing. SSSAiCode offers a special deal for CC Switch users: register via <a href="https://www.sssaicode.com/register?ref=DCP0SM">this link</a> to enjoy $10 extra credit on every top-up!</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>Thanks to Micu API for sponsoring this project! Micu API is a global LLM relay service provider dedicated to delivering the best cost-performance ratio with high stability. Backed by a registered enterprise for core assurance, eliminating any risk of service discontinuation, with fast official invoicing support! We champion "zero cost to try": top up from as low as ¥1 with no minimum, and get fee-free refunds anytime! Micu API offers an exclusive deal for CC Switch users: register via <a href="https://www.micuapi.ai/register?aff=aOYQ">this link</a> and enter promo code "ccswitch" when topping up to enjoy a <strong>10% discount</strong>!</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>Thanks to LemonData for sponsoring this project! LemonData is a high-performance AI API aggregation platform — one API key for 300+ models including GPT, Claude, Gemini, DeepSeek, and more. All models priced 3070% below official rates with auto-failover, smart routing, and unlimited concurrency. New users get $1 free credit instantly upon registration — sign up via <a href="https://lemondata.cc/r/FFX1ZDUP">this link</a>to claim your bonus and start building right away</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>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://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>
</tr>
<tr>
<td width="180"><a href="https://runapi.co"><img src="assets/partners/logos/runapi.jpg" alt="RunAPI" width="150"></a></td>
<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>
</table>
</details>
## Why CC Switch?
Modern AI-powered coding relies on CLI tools like Claude Code, Codex, Gemini CLI, OpenCode, and OpenClaw — but each has its own configuration format. Switching API providers means manually editing JSON, TOML, or `.env` files, and there is no unified way to manage MCP and Skills across multiple tools.
**CC Switch** gives you a single desktop app to manage all five CLI tools. Instead of editing config files by hand, you get a visual interface to import providers with one click, switch between them instantly, with 50+ built-in provider presets, unified MCP and Skills management, and system tray quick switching — all backed by a reliable SQLite database with atomic writes that protect your configs from corruption.
- **One App, Five CLI Tools** — Manage Claude Code, Codex, Gemini CLI, OpenCode, and OpenClaw from a single interface
- **No More Manual Editing** — 50+ provider presets including AWS Bedrock, NVIDIA NIM, and community relays; just pick and switch
- **Unified MCP & Skills Management** — One panel to manage MCP servers and Skills across four apps with bidirectional sync
- **System Tray Quick Switch** — Switch providers instantly from the tray menu, no need to open the full app
- **Cloud Sync** — Sync provider data across devices via Dropbox, OneDrive, iCloud, or WebDAV servers
- **Cross-Platform** — Native desktop app for Windows, macOS, and Linux, built with Tauri 2
- **Built-in Utilities** — Includes various utilities for first-launch login confirmation, signature bypass, plugin extension sync, and more
## Screenshots
| Main Interface | Add Provider |
@@ -63,108 +167,125 @@ Claude Code / Codex / Gemini official channels at 38% / 2% / 9% of original pric
## Features
### Current Version: v3.10.2 | [Full Changelog](CHANGELOG.md) | [Release Notes](docs/release-note-v3.9.0-en.md)
[Full Changelog](CHANGELOG.md) | [Release Notes](docs/release-notes/v3.15.0-en.md)
**v3.8.0 Major Update (2025-11-28)**
### Provider Management
**Persistence Architecture Upgrade & Brand New UI**
- **5 CLI tools, 50+ presets** — Claude Code, Codex, Gemini CLI, OpenCode, OpenClaw; copy your key and import with one click
- **Universal providers** — One config syncs to multiple apps (OpenCode, OpenClaw)
- One-click switching, system tray quick access, drag-and-drop sorting, import/export
- **SQLite + JSON Dual-layer Architecture**
- Migrated from JSON file storage to SQLite + JSON dual-layer structure
- Syncable data (providers, MCP, Prompts, Skills) stored in SQLite
- Device-level data (window state, local paths) stored in JSON
- Lays the foundation for future cloud sync functionality
- Schema version management for database migrations
### Proxy & Failover
- **Brand New User Interface**
- Completely redesigned interface layout
- Unified component styles and smoother animations
- Optimized visual hierarchy
- Tailwind CSS downgraded from v4 to v3.4 for better browser compatibility
- **Local proxy with hot-switching** — Format conversion, auto-failover, circuit breaker, provider health monitoring, and request rectifier
- **App-level takeover** — Independently proxy Claude, Codex, or Gemini, down to individual providers
- **Japanese Language Support**
- Added Japanese interface support (now supports Chinese/English/Japanese)
### MCP, Prompts & Skills
- **Auto Launch on Startup**
- One-click enable/disable in settings
- Platform-native APIs (Registry/LaunchAgent/XDG autostart)
- **Unified MCP panel** — Manage MCP servers across 4 apps with bidirectional sync and Deep Link import
- **Prompts** — Markdown editor with cross-app sync (CLAUDE.md / AGENTS.md / GEMINI.md) and backfill protection
- **Skills** — One-click install from GitHub repos or ZIP files, custom repository management, with symlink and file copy support
- **Skills Recursive Scanning**
- Support for multi-level directory structures
- Allow same-named skills from different repositories
### Usage & Cost Tracking
- **Critical Bug Fixes**
- Fixed custom endpoints lost when updating providers
- Fixed Gemini configuration write issues
- Fixed Linux WebKitGTK rendering issues
- **Usage dashboard** — Track spending, requests, and tokens with trend charts, detailed request logs, and custom per-model pricing
**v3.7.0 Highlights**
### Session Manager & Workspace
**Six Core Features, 18,000+ Lines of New Code**
- Browse, search, and restore conversation history across all apps
- **Workspace editor** (OpenClaw) — Edit agent files (AGENTS.md, SOUL.md, etc.) with Markdown preview
- **Gemini CLI Integration**
- Third supported AI CLI (Claude Code / Codex / Gemini)
- Dual-file configuration support (`.env` + `settings.json`)
- Complete MCP server management
- Presets: Google Official (OAuth) / PackyCode / Custom
### System & Platform
- **Claude Skills Management System**
- Auto-scan skills from GitHub repositories (3 pre-configured curated repos)
- One-click install/uninstall to `~/.claude/skills/`
- Custom repository support + subdirectory scanning
- Complete lifecycle management (discover/install/update)
- **Cloud sync** — Custom config directory (Dropbox, OneDrive, iCloud, NAS) and WebDAV server sync
- **Deep Link** (`ccswitch://`) — Import providers, MCP servers, prompts, and skills via URL
- Dark / Light / System theme, auto-launch, auto-updater, atomic writes, auto-backups, i18n (zh/en/ja)
- **Prompts Management System**
- Multi-preset system prompt management (unlimited presets, quick switching)
- Cross-app support (Claude: `CLAUDE.md` / Codex: `AGENTS.md` / Gemini: `GEMINI.md`)
- Markdown editor (CodeMirror 6 + real-time preview)
- Smart backfill protection, preserves manual modifications
## FAQ
- **MCP v3.7.0 Unified Architecture**
- Single panel manages MCP servers across three applications
- New SSE (Server-Sent Events) transport type
- Smart JSON parser + Codex TOML format auto-correction
- Unified import/export + bidirectional sync
<details>
<summary><strong>Which AI CLI tools does CC Switch support?</strong></summary>
- **Deep Link Protocol**
- `ccswitch://` protocol registration (all platforms)
- One-click import provider configs via shared links
- Security validation + lifecycle integration
CC Switch supports five tools: **Claude Code**, **Codex**, **Gemini CLI**, **OpenCode**, and **OpenClaw**. Each tool has dedicated provider presets and configuration management.
- **Environment Variable Conflict Detection**
- Auto-detect cross-app configuration conflicts (Claude/Codex/Gemini/MCP)
- Visual conflict indicators + resolution suggestions
- Override warnings + backup before changes
</details>
**Core Capabilities**
<details>
<summary><strong>Do I need to restart the terminal after switching providers?</strong></summary>
- **Provider Management**: One-click switching between Claude Code, Codex, and Gemini API configurations
- **Speed Testing**: Measure API endpoint latency with visual quality indicators
- **Import/Export**: Backup and restore configs with auto-rotation (keep 10 most recent)
- **i18n Support**: Complete Chinese/English localization (UI, errors, tray)
- **Claude Plugin Sync**: One-click apply/restore Claude plugin configurations
For most tools, yes — restart your terminal or the CLI tool for changes to take effect. The exception is **Claude Code**, which currently supports hot-switching of provider data without a restart.
**v3.6 Highlights**
</details>
- Provider duplication & drag-and-drop sorting
- Multi-endpoint management & custom config directory (cloud sync ready)
- Granular model configuration (4-tier: Haiku/Sonnet/Opus/Custom)
- WSL environment support with auto-sync on directory change
- 100% hooks test coverage & complete architecture refactoring
<details>
<summary><strong>My plugin configuration disappeared after switching providers — what happened?</strong></summary>
**System Features**
CC Switch provides a "Shared Config Snippet" feature to pass common data (beyond API keys and endpoints) between providers. Go to "Edit Provider" → "Shared Config Panel" → click "Extract from Current Provider" to save all common data. When creating a new provider, check "Write Shared Config" (enabled by default) to include plugin data in the new provider. All your configuration items are preserved in the default provider imported when you first launched the app.
- System tray with quick switching
- Single instance daemon
- Built-in auto-updater
- Atomic writes with rollback protection
</details>
<details>
<summary><strong>macOS installation</strong></summary>
CC Switch for macOS is code-signed and notarized by Apple. You can download and install it directly — no extra steps needed. We recommend using the `.dmg` installer.
</details>
<details>
<summary><strong>Why can't I delete the currently active provider?</strong></summary>
CC Switch follows a "minimal intrusion" design principle — even if you uninstall the app, your CLI tools will continue to work normally. The system always keeps one active configuration, because deleting all configurations would make the corresponding CLI tool unusable. If you rarely use a specific CLI tool, you can hide it in Settings. To switch back to official login, see the next question.
</details>
<details>
<summary><strong>How do I switch back to official login?</strong></summary>
Add an official provider from the preset list. After switching to it, run the Log out / Log in flow, and then you can freely switch between the official provider and third-party providers. Codex supports switching between different official providers, making it easy to switch between multiple Plus or Team accounts.
</details>
<details>
<summary><strong>Where is my data stored?</strong></summary>
- **Database**: `~/.cc-switch/cc-switch.db` (SQLite — providers, MCP, prompts, skills)
- **Local settings**: `~/.cc-switch/settings.json` (device-level UI preferences)
- **Backups**: `~/.cc-switch/backups/` (auto-rotated, keeps 10 most recent)
- **Skills**: `~/.cc-switch/skills/` (symlinked to corresponding apps by default)
- **Skill Backups**: `~/.cc-switch/skill-backups/` (created automatically before uninstall, keeps 20 most recent)
</details>
## Documentation
For detailed guides on every feature, check out the **[User Manual](docs/user-manual/en/README.md)** — covering provider management, MCP/Prompts/Skills, proxy & failover, and more.
## Quick Start
### Basic Usage
1. **Add Provider**: Click "Add Provider" → Choose a preset or create custom configuration
2. **Switch Provider**:
- Main UI: Select provider → Click "Enable"
- System Tray: Click provider name directly (instant effect)
3. **Takes Effect**: Restart your terminal or the corresponding CLI tool to apply changes (Claude Code does not require a restart)
4. **Back to Official**: Add an "Official Login" preset, restart the CLI tool, then follow its login/OAuth flow
### MCP, Prompts, Skills & Sessions
- **MCP**: Click the "MCP" button → Add servers via templates or custom config → Toggle per-app sync
- **Prompts**: Click "Prompts" → Create presets with Markdown editor → Activate to sync to live files
- **Skills**: Click "Skills" → Browse GitHub repos → One-click install to all apps
- **Sessions**: Click "Sessions" → Browse, search, and restore conversation history across all apps
> **Note**: On first launch, you can manually import existing CLI tool configs as the default provider.
## Download & Installation
### System Requirements
- **Windows**: Windows 10 and above
- **macOS**: macOS 10.15 (Catalina) and above
- **macOS**: macOS 12 (Monterey) and above
- **Linux**: Ubuntu 22.04+ / Debian 11+ / Fedora 34+ and other mainstream distributions
### Windows Users
@@ -188,9 +309,9 @@ brew upgrade --cask cc-switch
**Method 2: Manual Download**
Download `CC-Switch-v{version}-macOS.zip` from the [Releases](../../releases) page and extract to use.
Download `CC-Switch-v{version}-macOS.dmg` (recommended) or `.zip` from the [Releases](../../releases) page.
> **Note**: Since the author doesn't have an Apple Developer account, you may see an "unidentified developer" warning on first launch. Please close it first, then go to "System Settings" → "Privacy & Security" → click "Open Anyway", and you'll be able to open it normally afterwards.
> **Note**: CC Switch for macOS is code-signed and notarized by Apple. You can install and open it directly.
### Arch Linux Users
@@ -207,98 +328,11 @@ Download the latest Linux build from the [Releases](../../releases) page:
- `CC-Switch-v{version}-Linux.deb` (Debian/Ubuntu)
- `CC-Switch-v{version}-Linux.rpm` (Fedora/RHEL/openSUSE)
- `CC-Switch-v{version}-Linux.AppImage` (Universal)
- `CC-Switch-v{version}-Linux.flatpak` (Flatpak)
Flatpak install & run:
> **Flatpak**: Not included in official releases. You can build it yourself from the `.deb` — see [`flatpak/README.md`](flatpak/README.md) for instructions.
```bash
flatpak install --user ./CC-Switch-v{version}-Linux.flatpak
flatpak run com.ccswitch.desktop
```
## Quick Start
### Basic Usage
1. **Add Provider**: Click "Add Provider" → Choose preset or create custom configuration
2. **Switch Provider**:
- Main UI: Select provider → Click "Enable"
- System Tray: Click provider name directly (instant effect)
3. **Takes Effect**: Restart your terminal or Claude Code / Codex / Gemini clients to apply changes
4. **Back to Official**: Select the "Official Login" preset (Claude/Codex) or "Google Official" preset (Gemini), restart the corresponding client, then follow its login/OAuth flow
### MCP Management
- **Location**: Click "MCP" button in top-right corner
- **Add Server**:
- Use built-in templates (mcp-fetch, mcp-filesystem, etc.)
- Support stdio / http / sse transport types
- Configure independent MCP servers for different apps
- **Enable/Disable**: Toggle switches to control which servers sync to live config
- **Sync**: Enabled servers auto-sync to each app's live files
- **Import/Export**: Import existing MCP servers from Claude/Codex/Gemini config files
### Skills Management (v3.7.0 New)
- **Location**: Click "Skills" button in top-right corner
- **Discover Skills**:
- Auto-scan pre-configured GitHub repositories (Anthropic official, ComposioHQ, community, etc.)
- Add custom repositories (supports subdirectory scanning)
- **Install Skills**: Click "Install" to one-click install to `~/.claude/skills/`
- **Uninstall Skills**: Click "Uninstall" to safely remove and clean up state
- **Manage Repositories**: Add/remove custom GitHub repositories
### Prompts Management (v3.7.0 New)
- **Location**: Click "Prompts" button in top-right corner
- **Create Presets**:
- Create unlimited system prompt presets
- Use Markdown editor to write prompts (syntax highlighting + real-time preview)
- **Switch Presets**: Select preset → Click "Activate" to apply immediately
- **Sync Mechanism**:
- Claude: `~/.claude/CLAUDE.md`
- Codex: `~/.codex/AGENTS.md`
- Gemini: `~/.gemini/GEMINI.md`
- **Protection Mechanism**: Auto-save current prompt content before switching, preserves manual modifications
### Configuration Files
**Claude Code**
- Live config: `~/.claude/settings.json` (or `claude.json`)
- API key field: `env.ANTHROPIC_AUTH_TOKEN` or `env.ANTHROPIC_API_KEY`
- MCP servers: `~/.claude.json``mcpServers`
**Codex**
- Live config: `~/.codex/auth.json` (required) + `config.toml` (optional)
- API key field: `OPENAI_API_KEY` in `auth.json`
- MCP servers: `~/.codex/config.toml``[mcp_servers]` tables
**Gemini**
- Live config: `~/.gemini/.env` (API key) + `~/.gemini/settings.json` (auth mode)
- API key field: `GEMINI_API_KEY` or `GOOGLE_GEMINI_API_KEY` in `.env`
- Environment variables: Support `GOOGLE_GEMINI_BASE_URL`, `GEMINI_MODEL`, etc.
- MCP servers: `~/.gemini/settings.json``mcpServers`
- Tray quick switch: Each provider switch rewrites `~/.gemini/.env`, no need to restart Gemini CLI
**CC Switch Storage (v3.8.0 New Architecture)**
- Database (SSOT): `~/.cc-switch/cc-switch.db` (SQLite, stores providers, MCP, Prompts, Skills)
- Local settings: `~/.cc-switch/settings.json` (device-level settings)
- Backups: `~/.cc-switch/backups/` (auto-rotate, keep 10)
### Cloud Sync Setup
1. Go to Settings → "Custom Configuration Directory"
2. Choose your cloud sync folder (Dropbox, OneDrive, iCloud, etc.)
3. Restart app to apply
4. Repeat on other devices to enable cross-device sync
> **Note**: First launch auto-imports existing Claude/Codex configs as default provider.
## Architecture Overview
<details>
<summary><strong>Architecture Overview</strong></summary>
### Design Principles
@@ -333,16 +367,15 @@ flatpak run com.ccswitch.desktop
- **ProviderService**: Provider CRUD, switching, backfill, sorting
- **McpService**: MCP server management, import/export, live file sync
- **ProxyService**: Local proxy mode with hot-switching and format conversion
- **SessionManager**: Conversation history browsing across all supported apps
- **ConfigService**: Config import/export, backup rotation
- **SpeedtestService**: API endpoint latency measurement
**v3.6 Refactoring**
</details>
- Backend: 5-phase refactoring (error handling → command split → tests → services → concurrency)
- Frontend: 4-stage refactoring (test infra → hooks → components → cleanup)
- Testing: 100% hooks coverage + integration tests (vitest + MSW)
## Development
<details>
<summary><strong>Development Guide</strong></summary>
### Environment Requirements
@@ -403,7 +436,7 @@ cargo test test_name
cargo test --features test-hooks
```
### Testing Guide (v3.6 New)
### Testing Guide
**Frontend Testing**:
@@ -411,18 +444,6 @@ cargo test --features test-hooks
- Uses **MSW (Mock Service Worker)** to mock Tauri API calls
- Uses **@testing-library/react** for component testing
**Test Coverage**:
- Hooks unit tests (100% coverage)
- `useProviderActions` - Provider operations
- `useMcpActions` - MCP management
- `useSettings` series - Settings management
- `useImportExport` - Import/export
- Integration tests
- App main application flow
- SettingsDialog complete interaction
- MCP panel functionality
**Running Tests**:
```bash
@@ -436,49 +457,56 @@ pnpm test:unit:watch
pnpm test:unit --coverage
```
## Tech Stack
### Tech Stack
**Frontend**: React 18 · TypeScript · Vite · TailwindCSS 4 · TanStack Query v5 · react-i18next · react-hook-form · zod · shadcn/ui · @dnd-kit
**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
## Project Structure
</details>
<details>
<summary><strong>Project Structure</strong></summary>
```
├── src/ # Frontend (React + TypeScript)
│ ├── components/ # UI components (providers/settings/mcp/ui)
│ ├── hooks/ # Custom hooks (business logic)
├── src/ # Frontend (React + TypeScript)
│ ├── components/
│ ├── providers/ # Provider management
│ │ ├── mcp/ # MCP panel
│ │ ├── prompts/ # Prompts management
│ │ ├── skills/ # Skills management
│ │ ├── sessions/ # Session Manager
│ │ ├── proxy/ # Proxy mode panel
│ │ ├── openclaw/ # OpenClaw config panels
│ │ ├── settings/ # Settings (Terminal/Backup/About)
│ │ ├── deeplink/ # Deep Link import
│ │ ├── env/ # Environment variable management
│ │ ├── universal/ # Cross-app configuration
│ │ ├── usage/ # Usage statistics
│ │ └── ui/ # shadcn/ui component library
│ ├── hooks/ # Custom hooks (business logic)
│ ├── lib/
│ │ ├── api/ # Tauri API wrapper (type-safe)
│ │ └── query/ # TanStack Query config
│ ├── i18n/locales/ # Translations (zh/en)
│ ├── config/ # Presets (providers/mcp)
│ └── types/ # TypeScript definitions
├── src-tauri/ # Backend (Rust)
│ │ ├── api/ # Tauri API wrapper (type-safe)
│ │ └── query/ # TanStack Query config
│ ├── locales/ # Translations (zh/en/ja)
│ ├── config/ # Presets (providers/mcp)
│ └── types/ # TypeScript definitions
├── src-tauri/ # Backend (Rust)
│ └── src/
│ ├── commands/ # Tauri command layer (by domain)
│ ├── services/ # Business logic layer
│ ├── app_config.rs # Config data models
│ ├── provider.rs # Provider domain models
│ ├── mcp.rs # MCP sync & validation
── lib.rs # App entry & tray menu
├── tests/ # Frontend tests
│ ├── hooks/ # Unit tests
│ └── components/ # Integration tests
└── assets/ # Screenshots & partner resources
│ ├── commands/ # Tauri command layer (by domain)
│ ├── services/ # Business logic layer
│ ├── database/ # SQLite DAO layer
│ ├── proxy/ # Proxy module
│ ├── session_manager/ # Session management
── deeplink/ # Deep Link handling
│ └── mcp/ # MCP sync module
├── tests/ # Frontend tests
└── assets/ # Screenshots & partner resources
```
## Changelog
See [CHANGELOG.md](CHANGELOG.md) for version update details.
## Legacy Electron Version
[Releases](../../releases) retains v2.0.3 legacy Electron version
If you need legacy Electron code, you can pull the electron-legacy branch
</details>
## Contributing
@@ -489,7 +517,8 @@ Before submitting PRs, please ensure:
- Pass type check: `pnpm typecheck`
- Pass format check: `pnpm format:check`
- Pass unit tests: `pnpm test:unit`
- 💡 For new features, please open an issue for discussion before submitting a PR
For new features, please open an issue for discussion before submitting a PR. PRs for features that are not a good fit for the project may be closed.
## Star History
+252 -224
View File
@@ -1,23 +1,34 @@
<div align="center">
# Claude Code / Codex / Gemini CLI オールインワン・アシスタント
# CC Switch
[![Version](https://img.shields.io/badge/version-3.10.2-blue.svg)](https://github.com/farion1231/cc-switch/releases)
### 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/endpoint?url=https://api.pinstudios.net/api/badges/downloads/farion1231/cc-switch/total)](https://github.com/farion1231/cc-switch/releases/latest)
[![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>
[English](README.md) | [中文](README_ZH.md) | 日本語 | [Changelog](CHANGELOG.md) | [v3.9.0 リリースノート](docs/release-note-v3.9.0-ja.md)
### 🌐 唯一の公式サイト:**[ccswitch.io](https://ccswitch.io)**
[English](README.md) | [中文](README_ZH.md) | 日本語 | [Changelog](CHANGELOG.md)
</div>
## ❤️スポンサー
[![Zhipu GLM](assets/partners/banners/glm-en.jpg)](https://z.ai/subscribe?ic=8JVLJQFSKB)
> [ここに掲載しませんか?](mailto:farion1231@gmail.com)
本プロジェクトは Z.ai の GLM CODING PLAN による支援を受けています。GLM CODING PLAN は AI コーディング向けのサブスクリプションで、月額わずか 3 ドルから。Claude Code、Cline、Roo Code など 10 以上の人気 AI コーディングツールでフラッグシップモデル GLM-4.6 を利用でき、速く安定した開発体験を提供します。[このリンク](https://z.ai/subscribe?ic=8JVLJQFSKB) から申し込むと 10% オフになります!
<details open>
<summary>クリックで折りたたむ</summary>
[![MiniMax](assets/partners/banners/minimax-en.jpeg)](https://platform.minimax.io/subscribe/coding-plan?code=ClLhgxr2je&source=link)
MiniMax-M2.7 は、自律的進化と実世界の生産性向上のために設計された次世代大規模言語モデルです。従来のモデルとは異なり、M2.7 はエージェントチーム、動的ツール使用、強化学習ループを通じて自身の改善に積極的に参加します。ソフトウェアエンジニアリングにおいて優れた性能を発揮し(SWE-Pro で 56.22%、VIBE-Pro で 55.6%、Terminal Bench 2 で 57.0%)、複雑なオフィスワークフローにも秀でており、GDPval-AA で 1495 ELO のリーディングスコアを達成しています。Word・Excel・PowerPoint の高忠実度編集と、40 以上の複雑なスキルにわたる 97% の遵守率により、M2.7 は AI ネイティブなワークフローと組織構築の新基準を打ち立てます。
[こちら](https://platform.minimax.io/subscribe/coding-plan?code=ClLhgxr2je&source=link)から MiniMax Token Plan の限定 12% オフを入手!
---
@@ -32,12 +43,34 @@
<td>本プロジェクトは AIGoCode のスポンサー提供でお届けしています。AIGoCode は、Claude Code・Codex・最新の Gemini モデルを統合したオールインワンのAIコーディングプラットフォームで、安定性・高速性・コストパフォーマンスに優れた開発サービスを提供します。柔軟なサブスクリプションプランを備え、レスポンスも非常に高速です。さらに、CC Switch ユーザー向けの特典として、<a href="https://aigocode.com/invite/CC-SWITCH">このリンク</a>から登録すると、初回チャージ時に10%分のボーナスクレジットが付与されます!</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>胜算雲(Shengsuanyun)のご支援に感謝します!胜算雲は AI ネイティブチーム向けのスーパーファクトリーであり、産業グレードの AI タスク並列実行プラットフォームです。モデルマーケットプレイスでは Claude、ChatGPT、Gemini をはじめとする国内外の LLM およびマルチメディアモデルの計算リソースを集約・直接提供。リバースエンジニアリングや品質低下は一切なく、プラットフォーム全体のモデル SLA 可用性は 99.7% に達し、<a href="https://watch.shengsuanyun.com/status/shengsuanyun">監視ダッシュボード</a>は常時グリーン表示です。さらにエンタープライズ向けカスタムゲートウェイを提供し、チームのきめ細かなコスト・権限管理、スマートルーティング、セキュリティ保護、BYOK(自社キー持ち込み)ホスティングを実現します。従量課金およびトークンプラン(近日公開)対応で、請求書発行にも対応。<a href="https://www.shengsuanyun.com/?from=CH_4HHXMRYF">このリンク</a>から新規登録すると 10 元分のクレジットと初回チャージ 10% ボーナスが付与されます。</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>AICodeMirror のご支援に感謝します!AICodeMirror は Claude Code / Codex / Gemini CLI の公式高安定リレーサービスを提供しており、エンタープライズ級の同時接続、迅速な請求書発行、24時間年中無休の専用テクニカルサポートを備えています。
Claude Code / Codex / Gemini 公式チャンネルが最安で元価格の 38% / 2% / 9%、チャージ時にはさらに割引!AICodeMirror は CC Switch ユーザー向けに特別特典を用意:<a href="https://www.aicodemirror.com/register?invitecode=9915W3">このリンク</a>から登録すると初回チャージ 20% オフ、法人のお客様は最大 25% オフ!</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>PatewayAI のご支援に感謝します!PatewayAI はヘビーな AI 開発者向けに、公式直結の高品質モデル API 中継サービスを専門に提供するプロバイダーです。Claude シリーズ全モデルおよび Codex シリーズに対応し、100% 公式ソースから直接提供。混ぜ物・水増しは一切なく、検証も歓迎します。課金は透明で、トークン単位の請求書を 1 件ずつ照合可能です。
エンタープライズ級の高同時接続にも対応し、法人のお客様には専用の管理プラットフォームを提供。正式契約および請求書発行に対応しており、詳細は公式サイトの連絡先よりお問い合わせください。
現在、<a href="https://pateway.ai/?ch=etzpm8&aff=WB6M6F67#/">このリンク</a>からご登録いただくと $3 のトライアルクレジットを進呈。チャージは最安で元価格の 60%、友達紹介は双方にボーナスが付与され、紹介報酬は最大 $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>Dola seed のご支援に感謝します!Dola Seed 2.0 は ByteDance がグローバル市場向けに独自開発したフルモーダル汎用大規模モデルです。統一されたマルチモーダルアーキテクチャを基盤に、テキスト・画像・音声・動画の統合的な理解と生成をサポートします。エージェント連携をネイティブに実現し、強力な推論、長時間タスクの実行、ツール統合、コーディング能力を備えています。スマートコックピット、パーソナルアシスタント、教育、カスタマーサポート、マーケティング、リテールなど幅広いシナリオに適用可能で、マルチモーダル認識、エンドツーエンドの複雑なタスク遂行、安定したインタラクション、データセキュリティに優れ、ModelArk プラットフォームを通じて手軽に利用・デプロイできます。<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">このリンク</a>からご登録いただくと、モデルごとに 500,000 トークンの無料推論クォータを進呈します。</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>SiliconFlow のご支援に感謝します!SiliconFlow は高性能 AI インフラストラクチャおよびモデル API プラットフォームで、言語・音声・画像・動画モデルへの高速かつ信頼性の高いアクセスをワンストップで提供します。従量課金制、豊富なマルチモーダルモデル対応、高速推論、エンタープライズグレードの安定性を備え、開発者やチームがより効率的に AI アプリケーションを構築・拡張できるようサポートします。<a href="https://cloud.siliconflow.cn/i/drGuwc9k">このリンク</a>から登録し、本人確認を完了すると、プラットフォーム内の全モデルで利用可能な ¥16 のボーナスクレジットが付与されます。SiliconFlow は OpenClaw にも対応しており、SiliconFlow の API キーを接続することで主要な AI モデルを無料で呼び出すことができます。</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>Cubence のご支援に感謝します!Cubence は Claude Code、Codex、Gemini などのリレーサービスを提供する信頼性の高い API 中継プラットフォームで、従量課金や月額プランなど柔軟な料金体系を提供しています。CC Switch ユーザー向けの特別割引:<a href="https://cubence.com/signup?code=CCSWITCH&source=ccs">このリンク</a>で登録し、チャージ時に「CCSWITCH」クーポンを入力すると、毎回 10% オフになります!</td>
@@ -48,13 +81,83 @@ Claude Code / Codex / Gemini 公式チャンネルが最安で元価格の 38% /
<td>DMXAPI のご支援に感謝します!DMXAPI は 200 社以上の企業ユーザーにグローバル大規模モデル API サービスを提供しています。1 つの API キーで全世界のモデルにアクセス可能。即時請求書発行、同時接続数無制限、最低 $0.15 から、24 時間年中無休のテクニカルサポート。GPT/Claude/Gemini が全て 32% オフ、国内モデルは 20〜50% オフ、Claude Code 専用モデルは 66% オフ実施中!<a href="https://www.dmxapi.cn/register?aff=bUHu">登録はこちら</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>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>
</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>本プロジェクトへのご支援として、Right Code にご協賛いただき誠にありがとうございます。Right Code は、Claude Code、Codex、Gemini などのモデル向け中継サービスを安定して提供しており、従量課金と月額プランの 2 つの料金体系から選択できます。チャージ後に請求書の発行が可能で、法人・チームのお客様には専任担当による個別対応も行っています。さらに、CC Switch ユーザー向けの特別優待として、<a href="https://www.right.codes/register?aff=CCSWITCH">こちらのリンク</a>から登録すると、チャージのたびに実際の支払額の 5% 相当の従量課金クレジットが付与されます。</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>SSSAiCode のご支援に感謝します!SSSAiCode は安定性と信頼性に優れた API 中継サービスで、安定的で信頼性が高く、手頃な価格の Claude・Codex モデルサービスを提供しています。当日の迅速な請求書発行をサポート。CC Switch ユーザー向けの特別特典:<a href="https://www.sssaicode.com/register?ref=DCP0SM">こちらのリンク</a>から登録すると、毎回のチャージで $10 の追加ボーナスを受けられます!</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>Micu API のご支援に感謝します!Micu API は、最高のコストパフォーマンスと高い安定性を追求するグローバル大規模言語モデル中継サービスプロバイダーです。法人企業がバックアップしており、サービス停止のリスクを排除、迅速な正規請求書発行に対応!「試行コストゼロ」をモットーに、最低 1 元からチャージ可能で手数料無料、いつでも返金可能!CC Switch ユーザー向けの限定特典:<a href="https://www.micuapi.ai/register?aff=aOYQ">こちらのリンク</a>から登録し、チャージ時にプロモコード「ccswitch」を入力すると <strong>10% 割引</strong> が適用されます!</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>LemonData のご支援に感謝します!LemonData は高性能 AI API アグリゲーションプラットフォームで、GPT、Claude、Gemini、DeepSeek など 300 以上のモデルに 1 つの API キーでアクセス可能。全モデルが公式価格の 30〜70% オフで自動フェイルオーバー、スマートルーティング、無制限同時接続に対応。新規ユーザーは登録だけで即座に $1 の無料クレジットを獲得 — <a href="https://lemondata.cc/r/FFX1ZDUP">こちらのリンク</a>から登録してボーナスを獲得し、すぐに開発を始めましょう!</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>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://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>
</tr>
<tr>
<td width="180"><a href="https://runapi.co"><img src="assets/partners/logos/runapi.jpg" alt="RunAPI" width="150"></a></td>
<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>
</table>
</details>
## CC Switch を選ぶ理由
最新の AI コーディングは Claude Code、Codex、Gemini CLI、OpenCode、OpenClaw などの CLI ツールに依存していますが、各ツールの設定形式はバラバラです。API プロバイダを切り替えるたびに JSON、TOML、`.env` ファイルを手動で編集する必要があり、複数ツール間で MCP や Skills を統一的に管理する手段もありません。
**CC Switch** は、5 つの CLI ツールを 1 つのデスクトップアプリで一元管理できます。設定ファイルを手作業で編集する代わりに、ワンクリックでプロバイダをインポートし、瞬時に切り替えられるビジュアルインターフェースを提供します。50 以上の組み込みプリセット、統一 MCP・Skills 管理、システムトレイからの即時切り替え機能を搭載。すべてはアトミック書き込みによる信頼性の高い SQLite データベースに支えられており、設定の破損を防ぎます。
- **1 つのアプリで 5 つの CLI ツール** -- Claude Code、Codex、Gemini CLI、OpenCode、OpenClaw を単一インターフェースで管理
- **手動編集は不要** -- AWS Bedrock、NVIDIA NIM、コミュニティリレーなど 50 以上のプロバイダプリセットを内蔵。選んで切り替えるだけ
- **統一 MCP・Skills 管理** -- 1 つのパネルで 4 つのアプリの MCP サーバーと Skills を双方向同期で管理
- **システムトレイでクイック切り替え** -- トレイメニューから即座にプロバイダを切り替え。アプリを開く必要なし
- **クラウド同期** -- Dropbox、OneDrive、iCloud、または WebDAV サーバー経由でデバイス間のプロバイダデータを同期
- **クロスプラットフォーム** -- Tauri 2 で構築された Windows、macOS、Linux 対応のネイティブデスクトップアプリ
- **便利ツール内蔵** -- 初回起動時のログイン確認、署名バイパス、プラグイン拡張の同期など、さまざまなユーティリティを搭載
## スクリーンショット
| メイン画面 | プロバイダ追加 |
@@ -63,108 +166,125 @@ Claude Code / Codex / Gemini 公式チャンネルが最安で元価格の 38% /
## 特長
### 現在のバージョン:v3.10.2 | [完全な更新履歴](CHANGELOG.md) | [リリースノート](docs/release-note-v3.9.0-ja.md)
[完全な更新履歴](CHANGELOG.md) | [リリースノート](docs/release-notes/v3.15.0-ja.md)
**v3.8.0 メジャーアップデート (2025-11-28)**
### プロバイダ管理
**永続化アーキテクチャ刷新 & 新 UI**
- **5 つの CLI ツール、50 以上のプリセット** -- Claude Code、Codex、Gemini CLI、OpenCode、OpenClaw。キーをコピーしてワンクリックでインポート
- **ユニバーサルプロバイダ** -- 1 つの設定を複数アプリに同期(OpenCode、OpenClaw
- ワンクリック切り替え、システムトレイクイックアクセス、ドラッグ&ドロップ並び替え、インポート/エクスポート
- **SQLite + JSON 二層構造**
- JSON 単独保存から SQLite + JSON の二層構造へ移行
- 同期対象データ(プロバイダ、MCP、Prompts、Skills)は SQLite に保存
- デバイス固有データ(ウィンドウ状態、ローカルパス)は JSON に保存
- 将来のクラウド同期の土台を用意
- DB マイグレーション用にスキーマバージョンを管理
### プロキシ & フェイルオーバー
- **新しいユーザーインターフェース**
- レイアウトを全面再設計
- コンポーネントスタイルとアニメーションを統一
- 視覚的な階層を最適化
- ブラウザ互換性向上のため Tailwind CSS を v4 から v3.4 にダウングレード
- **ローカルプロキシのホットスイッチ** -- フォーマット変換、自動フェイルオーバー、サーキットブレーカー、プロバイダヘルスモニタリング、リクエストレクティファイア
- **アプリレベルのテイクオーバー** -- Claude、Codex、Gemini を個別にプロキシ経由でルーティング、プロバイダ単位で設定可能
- **日本語対応**
- UI が中国語/英語/日本語の 3 言語対応に
### MCP、Prompts & Skills
- **自動起動**
- 設定画面でワンクリック ON/OFF
- プラットフォームネイティブ APIRegistry/LaunchAgent/XDG autostart)を使用
- **統一 MCP パネル** -- 4 つのアプリの MCP サーバーを管理、双方向同期、Deep Link インポート対応
- **Prompts** -- Markdown エディタ、クロスアプリ同期(CLAUDE.md / AGENTS.md / GEMINI.md)、バックフィル保護
- **Skills** -- GitHub リポジトリまたは ZIP ファイルからワンクリックインストール、カスタムリポジトリ管理、シンボリックリンクとファイルコピーに対応
- **Skills 再帰スキャン**
- 多階層ディレクトリをサポート
- リポジトリが異なる同名スキルを許可
### 使用量 & コストトラッキング
- **重要なバグ修正**
- プロバイダ更新時にカスタムエンドポイントが失われる問題を修正
- Gemini 設定の書き込み問題を修正
- Linux WebKitGTK の描画問題を修正
- **使用量ダッシュボード** -- プロバイダ横断で支出・リクエスト数・トークン使用量を追跡、トレンドチャート、詳細リクエストログ、カスタムモデル価格設定
**v3.7.0 ハイライト**
### Session Manager & ワークスペース
**6 つのコア機能、18,000 行超の新コード**
- すべてのアプリの会話履歴を閲覧・検索・復元
- **ワークスペースエディタ**(OpenClaw)-- エージェントファイル(AGENTS.md、SOUL.md など)を Markdown プレビュー付きで編集
- **Gemini CLI 統合**
- Claude Code / Codex / Gemini の 3 番目のサポート AI CLI
- 2 つの設定ファイル(`.env` + `settings.json`)に対応
- MCP サーバー管理を完備
- プリセット:Google 公式(OAuth/ PackyCode / カスタム
### システム & プラットフォーム
- **Claude Skills 管理システム**
- GitHub リポジトリを自動スキャン(3 つのキュレーション済みリポジトリを同梱)
- `~/.claude/skills/` へワンクリックでインストール/アンインストール
- カスタムリポジトリ + サブディレクトリスキャンをサポート
- ライフサイクル管理(検出/インストール/更新)を完備
- **クラウド同期** -- カスタム設定ディレクトリ(Dropbox、OneDrive、iCloud、NAS)および WebDAV サーバー同期
- **Deep Link** (`ccswitch://`) -- URL 経由でプロバイダ、MCP サーバー、Prompts、Skills をワンクリックインポート
- ダーク / ライト / システムテーマ、自動起動、自動アップデーター、アトミック書き込み、自動バックアップ、多言語対応(中/英/日)
- **Prompts 管理システム**
- 無制限のシステムプロンプトプリセットを作成
- Markdown エディタ(CodeMirror 6 + リアルタイムプレビュー)付き
- スマートなバックフィル保護で手動変更を保持
- 複数アプリに同時対応(Claude: `CLAUDE.md` / Codex: `AGENTS.md` / Gemini: `GEMINI.md`
## よくある質問
- **MCP v3.7.0 統合アーキテクチャ**
- 1 つのパネルで 3 アプリの MCP を管理
- 新たに SSEServer-Sent Events)トランスポートを追加
- スマート JSON パーサー + Codex TOML 自動修正
- 双方向のインポート/エクスポート + 双方向同期
<details>
<summary><strong>CC Switch はどの AI CLI ツールに対応していますか?</strong></summary>
- **ディープリンクプロトコル**
- `ccswitch://` を全プラットフォームで登録
- 共有リンクからプロバイダ設定をワンクリックでインポート
- セキュリティ検証 + ライフサイクル統合
CC Switch は **Claude Code**、**Codex**、**Gemini CLI**、**OpenCode**、**OpenClaw** の 5 つのツールに対応しています。各ツールに専用のプロバイダプリセットと設定管理が用意されています。
- **環境変数の競合検知**
- Claude/Codex/Gemini/MCP 間の設定競合を自動検出
- 競合表示 + 解決ガイド
- 上書き前の警告 + バックアップ
</details>
**コア機能**
<details>
<summary><strong>プロバイダを切り替えた後、ターミナルの再起動は必要ですか?</strong></summary>
- **プロバイダ管理**Claude Code、Codex、Gemini の API 設定をワンクリックで切り替え
- **速度テスト**:エンドポイント遅延を計測し、品質を可視化
- **インポート/エクスポート**:設定をバックアップ・復元(最新 10 件を自動ローテーション)
- **多言語対応**:UI/エラー/トレイを含む中国語・英語・日本語ローカライズ
- **Claude プラグイン同期**:Claude プラグイン設定をワンクリックで適用/復元
ほとんどのツールでは、はい。変更を反映するにはターミナルまたは CLI ツールを再起動してください。ただし **Claude Code** は例外で、現在プロバイダデータのホットスイッチに対応しており、再起動は不要です。
**v3.6 ハイライト**
</details>
- プロバイダの複製とドラッグ&ドロップ並び替え
- 複数エンドポイント管理とカスタム設定ディレクトリ(クラウド同期準備済み)
- 4 階層のモデル設定(Haiku/Sonnet/Opus/Custom
- WSL 環境をサポートし、ディレクトリ変更時に自動同期
- Hooks テスト 100% カバレッジ + アーキテクチャ全面リファクタ
<details>
<summary><strong>プロバイダを切り替えた後、プラグイン設定が消えてしまいました。どうすればよいですか?</strong></summary>
**システム機能**
CC Switch には「共有設定スニペット」機能があり、APIキーやエンドポイント以外の共通データをプロバイダ間で引き継ぐことができます。「プロバイダ編集」→「共有設定パネル」→「現在のプロバイダから抽出」をクリックして、すべての共通データを保存してください。新しいプロバイダを作成する際に「共有設定を書き込む」にチェック(デフォルトで有効)を入れれば、プラグインなどのデータが新しいプロバイダ設定に含まれます。すべての設定項目は、アプリ初回起動時にインポートされたデフォルトプロバイダに保存されており、失われることはありません。
- クイックスイッチ付きシステムトレイ
- シングルインスタンス常駐
- ビルトイン自動アップデータ
- ロールバック保護付きのアトミック書き込み
</details>
<details>
<summary><strong>macOS のインストールについて</strong></summary>
CC Switch の macOS 版は Apple によるコード署名と公証が完了しています。直接ダウンロードしてインストールできます — 追加の手順は不要です。`.dmg` インストーラの使用を推奨します。
</details>
<details>
<summary><strong>現在アクティブなプロバイダを削除できないのはなぜですか?</strong></summary>
CC Switch は「最小限の介入」という設計原則に従っています。アプリをアンインストールしても、CLI ツールは正常に動作し続けます。すべての設定を削除すると対応する CLI ツールが使用できなくなるため、システムは常にアクティブな設定を 1 つ保持します。特定の CLI ツールをあまり使用しない場合は、設定で非表示にできます。公式ログインに戻す方法は、次の質問をご覧ください。
</details>
<details>
<summary><strong>公式ログインに戻すにはどうすればよいですか?</strong></summary>
プリセットリストから公式プロバイダを追加してください。切り替え後、ログアウト/ログインのフローを実行すれば、以降は公式プロバイダとサードパーティプロバイダを自由に切り替えられます。Codex では異なる公式プロバイダ間の切り替えに対応しており、複数の Plus アカウントや Team アカウントの切り替えに便利です。
</details>
<details>
<summary><strong>データはどこに保存されますか?</strong></summary>
- **データベース**: `~/.cc-switch/cc-switch.db`SQLite -- プロバイダ、MCP、Prompts、Skills
- **ローカル設定**: `~/.cc-switch/settings.json`(デバイスレベルの UI 設定)
- **バックアップ**: `~/.cc-switch/backups/`(自動ローテーション、最新 10 件を保持)
- **Skills**: `~/.cc-switch/skills/`(デフォルトでシンボリックリンクにより対応アプリに接続)
- **Skill バックアップ**: `~/.cc-switch/skill-backups/`(アンインストール前に自動作成、最新 20 件を保持)
</details>
## ドキュメント
各機能の詳しい使い方については、**[ユーザーマニュアル](docs/user-manual/ja/README.md)** をご覧ください。プロバイダ管理、MCP/Prompts/Skills、プロキシとフェイルオーバーなど、すべての機能を網羅しています。
## クイックスタート
### 基本的な使い方
1. **プロバイダ追加**: 「Add Provider」をクリック → プリセットを選ぶかカスタム設定を作成
2. **プロバイダ切り替え**:
- メイン UI: プロバイダを選択 → 「Enable」をクリック
- システムトレイ: プロバイダ名をクリック(即時反映)
3. **反映**: ターミナルまたは対応する CLI ツールを再起動して適用(Claude Code は再起動不要)
4. **公式設定に戻す**: 「Official Login」プリセットを追加し、CLI ツールを再起動してログイン/OAuth フローを実行
### MCP、Prompts、Skills & Sessions
- **MCP**: 「MCP」ボタンをクリック → テンプレートまたはカスタム設定でサーバーを追加 → アプリごとの同期をトグルで切り替え
- **Prompts**: 「Prompts」をクリック → Markdown エディタでプリセットを作成 → 有効化してライブファイルに同期
- **Skills**: 「Skills」をクリック → GitHub リポジトリを閲覧 → ワンクリックですべてのアプリにインストール
- **Sessions**: 「Sessions」をクリック → すべてのアプリの会話履歴を閲覧・検索・復元
> **補足**: 初回起動時に、既存の CLI ツール設定を手動でインポートしてデフォルトプロバイダとして使用できます。
## ダウンロード & インストール
### システム要件
- **Windows**: Windows 10 以上
- **macOS**: macOS 10.15 (Catalina) 以上
- **macOS**: macOS 12 (Monterey) 以上
- **Linux**: Ubuntu 22.04+ / Debian 11+ / Fedora 34+ など主要ディストリビューション
### Windows ユーザー
@@ -192,7 +312,7 @@ brew upgrade --cask cc-switch
> **注意**: 開発者アカウント未登録のため、初回起動時に「開発元を確認できません」と表示される場合があります。一度閉じてから「システム設定」→「プライバシーとセキュリティ」→「このまま開く」をクリックしてください。以降は通常通り起動できます。
### ArchLinux ユーザー
### Arch Linux ユーザー
**paru でインストール(推奨)**
@@ -207,98 +327,11 @@ paru -S cc-switch-bin
- `CC-Switch-v{version}-Linux.deb`Debian/Ubuntu
- `CC-Switch-v{version}-Linux.rpm`Fedora/RHEL/openSUSE
- `CC-Switch-v{version}-Linux.AppImage`(汎用)
- `CC-Switch-v{version}-Linux.flatpak`Flatpak
Flatpak のインストールと起動:
> **Flatpak**:公式リリースには含まれていません。`.deb` から自分でビルドできます — 手順は [`flatpak/README.md`](flatpak/README.md) を参照してください。
```bash
flatpak install --user ./CC-Switch-v{version}-Linux.flatpak
flatpak run com.ccswitch.desktop
```
## クイックスタート
### 基本的な使い方
1. **プロバイダ追加**:「Add Provider」をクリック → プリセットを選ぶかカスタム設定を作成
2. **プロバイダ切り替え**:
- メイン UI: プロバイダを選択 → 「Enable」をクリック
- システムトレイ: プロバイダ名をクリック(即時反映)
3. **反映**: ターミナルや Claude Code / Codex / Gemini クライアントを再起動して適用
4. **公式設定に戻す**: 「Official Login」プリセット(Claude/Codex)または「Google Official」プリセット(Gemini)を選び、対応クライアントを再起動してログイン/OAuth を実行
### MCP 管理
- **入口**: 右上の「MCP」ボタンをクリック
- **サーバー追加**:
- 組み込みテンプレート(mcp-fetch、mcp-filesystem など)を使用
- stdio / http / sse の各トランスポートをサポート
- アプリごとに独立した MCP を設定可能
- **有効/無効**: トグルでライブ設定への同期を切り替え
- **同期**: 有効なサーバーは各アプリのライブファイルへ自動同期
- **インポート/エクスポート**: Claude/Codex/Gemini の設定ファイルから既存 MCP を取り込み
### Skills 管理 (v3.7.0 新機能)
- **入口**: 右上の「Skills」ボタンをクリック
- **スキル探索**:
- 事前設定済みの GitHub リポジトリを自動スキャン(Anthropic 公式、ComposioHQ、コミュニティなど)
- カスタムリポジトリを追加(サブディレクトリスキャン対応)
- **インストール**: 「Install」を押すだけで `~/.claude/skills/` に配置
- **アンインストール**: 「Uninstall」で安全に削除と状態クリーンアップ
- **リポジトリ管理**: カスタム GitHub リポジトリを追加/削除
### Prompts 管理 (v3.7.0 新機能)
- **入口**: 右上の「Prompts」ボタンをクリック
- **プリセット作成**:
- 無制限のシステムプロンプトプリセットを作成
- Markdown エディタで記述(シンタックスハイライト + リアルタイムプレビュー)
- **プリセット切り替え**: プリセットを選択 → 「Activate」で即適用
- **同期先**:
- Claude: `~/.claude/CLAUDE.md`
- Codex: `~/.codex/AGENTS.md`
- Gemini: `~/.gemini/GEMINI.md`
- **保護機構**: 切り替え前に現在の内容を自動保存し、手動変更を保持
### 設定ファイルパス
**Claude Code**
- ライブ設定: `~/.claude/settings.json`(または `claude.json`
- API キーフィールド: `env.ANTHROPIC_AUTH_TOKEN` または `env.ANTHROPIC_API_KEY`
- MCP サーバー: `~/.claude.json``mcpServers`
**Codex**
- ライブ設定: `~/.codex/auth.json`(必須)+ `config.toml`(任意)
- API キーフィールド: `auth.json` 内の `OPENAI_API_KEY`
- MCP サーバー: `~/.codex/config.toml``[mcp_servers]` テーブル
**Gemini**
- ライブ設定: `~/.gemini/.env`API キー)+ `~/.gemini/settings.json`(認証モード)
- API キーフィールド: `.env` 内の `GEMINI_API_KEY` または `GOOGLE_GEMINI_API_KEY`
- 環境変数: `GOOGLE_GEMINI_BASE_URL``GEMINI_MODEL` などをサポート
- MCP サーバー: `~/.gemini/settings.json``mcpServers`
- トレイでのクイックスイッチ: プロバイダ切り替えごとに `~/.gemini/.env` を書き換えるため Gemini CLI の再起動は不要
**CC Switch 保存先 (v3.8.0 新アーキテクチャ)**
- データベース (SSOT): `~/.cc-switch/cc-switch.db`SQLite。プロバイダ、MCP、Prompts、Skills を保存)
- ローカル設定: `~/.cc-switch/settings.json`(デバイスレベル設定)
- バックアップ: `~/.cc-switch/backups/`(自動ローテーション、最新 10 件を保持)
### クラウド同期の設定
1. 設定 → 「Custom Configuration Directory」へ進む
2. クラウド同期フォルダ(Dropbox、OneDrive、iCloud など)を選択
3. アプリを再起動して反映
4. 他のデバイスでも同じフォルダを指定すればクロスデバイス同期が有効に
> **補足**: 初回起動時に既存の Claude/Codex 設定をデフォルトプロバイダとして自動インポートします。
## アーキテクチャ概要
<details>
<summary><strong>アーキテクチャ概要</strong></summary>
### 設計原則
@@ -326,23 +359,22 @@ flatpak run com.ccswitch.desktop
- **二層ストレージ**: 同期データは SQLite、デバイスデータは JSON
- **双方向同期**: 切り替え時はライブファイルへ書き込み、編集時はアクティブプロバイダから逆同期
- **アトミック書き込み**: 一時ファイル + rename パターンで設定破損を防止
- **並行安全**: Mutex で保護された DB 接続でレースを防
- **並行安全**: Mutex で保護された DB 接続でレースコンディションを防
- **レイヤードアーキテクチャ**: Commands → Services → DAO → Database を明確に分離
**主要コンポーネント**
- **ProviderService**: プロバイダの CRUD、切り替え、バックフィル、ソート
- **McpService**: MCP サーバー管理、インポート/エクスポート、ライブファイル同期
- **ProxyService**: ローカル Proxy モードのホットスイッチとフォーマット変換
- **SessionManager**: 対応する全アプリの会話履歴閲覧
- **ConfigService**: 設定のインポート/エクスポート、バックアップローテーション
- **SpeedtestService**: API エンドポイントの遅延計測
**v3.6 リファクタリング**
</details>
- バックエンド: エラーハンドリング → コマンド分割 → テスト → サービス層 → 並行性の 5 フェーズ
- フロントエンド: テスト基盤 → hooks → コンポーネント → クリーンアップの 4 ステージ
- テスト: hooks 100% カバレッジ + 統合テスト(vitest + MSW
## 開発
<details>
<summary><strong>開発ガイド</strong></summary>
### 開発環境
@@ -403,7 +435,7 @@ cargo test test_name
cargo test --features test-hooks
```
### テストガイド (v3.6)
### テストガイド
**フロントエンドテスト**:
@@ -411,18 +443,6 @@ cargo test --features test-hooks
- **MSW (Mock Service Worker)** で Tauri API 呼び出しをモック
- コンポーネントテストに **@testing-library/react** を採用
**テストカバレッジ**:
- Hooks の単体テスト(100% カバレッジ)
- `useProviderActions` - プロバイダ操作
- `useMcpActions` - MCP 管理
- `useSettings` 系 - 設定管理
- `useImportExport` - インポート/エクスポート
- 統合テスト
- アプリのメインフロー
- SettingsDialog の一連操作
- MCP パネルの機能
**テスト実行**:
```bash
@@ -436,60 +456,68 @@ pnpm test:unit:watch
pnpm test:unit --coverage
```
## 技術スタック
### 技術スタック
**フロントエンド**: React 18 · TypeScript · Vite · TailwindCSS 4 · TanStack Query v5 · react-i18next · react-hook-form · zod · shadcn/ui · @dnd-kit
**フロントエンド**: React 18 · TypeScript · Vite · TailwindCSS 3.4 · TanStack Query v5 · react-i18next · react-hook-form · zod · shadcn/ui · @dnd-kit
**バックエンド**: Tauri 2.8 · Rust · serde · tokio · thiserror · tauri-plugin-updater/process/dialog/store/log
**テスト**: vitest · MSW · @testing-library/react
## プロジェクト構成
</details>
<details>
<summary><strong>プロジェクト構成</strong></summary>
```
├── src/ # フロントエンド (React + TypeScript)
│ ├── components/ # UI コンポーネント (providers/settings/mcp/ui)
│ ├── hooks/ # ビジネスロジック用カスタムフック
├── src/ # フロントエンド (React + TypeScript)
│ ├── components/
│ ├── providers/ # プロバイダ管理
│ │ ├── mcp/ # MCP パネル
│ │ ├── prompts/ # Prompts 管理
│ │ ├── skills/ # Skills 管理
│ │ ├── sessions/ # Session Manager
│ │ ├── proxy/ # Proxy モードパネル
│ │ ├── openclaw/ # OpenClaw 設定パネル
│ │ ├── settings/ # 設定 (Terminal/Backup/About)
│ │ ├── deeplink/ # Deep Link インポート
│ │ ├── env/ # 環境変数管理
│ │ ├── universal/ # クロスアプリ設定
│ │ ├── usage/ # 使用量統計
│ │ └── ui/ # shadcn/ui コンポーネントライブラリ
│ ├── hooks/ # カスタムフック(ビジネスロジック)
│ ├── lib/
│ │ ├── api/ # Tauri API ラッパー (型安全)
│ │ └── query/ # TanStack Query 設定
│ ├── i18n/locales/ # 翻訳 (zh/en)
│ ├── config/ # プリセット (providers/mcp)
│ └── types/ # TypeScript 型定義
├── src-tauri/ # バックエンド (Rust)
│ │ ├── api/ # Tauri API ラッパー型安全
│ │ └── query/ # TanStack Query 設定
│ ├── locales/ # 翻訳 (zh/en/ja)
│ ├── config/ # プリセット (providers/mcp)
│ └── types/ # TypeScript 型定義
├── src-tauri/ # バックエンド (Rust)
│ └── src/
│ ├── commands/ # Tauri コマンド層 (ドメイン別)
│ ├── services/ # ビジネスロジック層
│ ├── app_config.rs # 設定モデル
│ ├── provider.rs # プロバイダドメインモデ
│ ├── mcp.rs # MCP 同期 & 検証
── lib.rs # アプリエントリ & トレイメニュー
├── tests/ # フロントエンドテスト
│ ├── hooks/ # 単体テスト
│ └── components/ # 統合テスト
└── assets/ # スクリーンショット & スポンサーリソース
│ ├── commands/ # Tauri コマンド層ドメイン別
│ ├── services/ # ビジネスロジック層
│ ├── database/ # SQLite DAO 層
│ ├── proxy/ # Proxy モジュー
│ ├── session_manager/ # セッション管理
── deeplink/ # Deep Link 処理
│ └── mcp/ # MCP 同期モジュール
├── tests/ # フロントエンドテスト
└── assets/ # スクリーンショット & パートナーリソース
```
## 更新履歴
詳細は [CHANGELOG.md](CHANGELOG.md) をご覧ください。
## 旧 Electron 版
[Releases](../../releases) に v2.0.3 の Electron 旧版を残しています。
旧版コードが必要な場合は `electron-legacy` ブランチを取得してください。
</details>
## 貢献
Issue や提案を歓迎します!
PR を送る前に以下をご確認ください:
PR を送る前に以下をご確認ください
- 型チェック: `pnpm typecheck`
- フォーマットチェック: `pnpm format:check`
- 単体テスト: `pnpm test:unit`
- 💡 新機能の場合は、事前に Issue でディスカッションしていただけると助かります
新機能の場合は、PR を送る前に Issue でディスカッションしてください。プロジェクトに合わない機能の PR はクローズされる場合があります。
## Star History
+258 -228
View File
@@ -1,30 +1,41 @@
<div align="center">
# Claude Code / Codex / Gemini CLI 全方位辅助工具
# CC Switch
[![Version](https://img.shields.io/badge/version-3.10.2-blue.svg)](https://github.com/farion1231/cc-switch/releases)
### 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/endpoint?url=https://api.pinstudios.net/api/badges/downloads/farion1231/cc-switch/total)](https://github.com/farion1231/cc-switch/releases/latest)
[![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>
[English](README.md) | 中文 | [日本語](README_JA.md) | [更新日志](CHANGELOG.md) | [v3.9.0 发布说明](docs/release-note-v3.9.0-zh.md)
### 🌐 唯一官方网站:**[ccswitch.io](https://ccswitch.io)**
[English](README.md) | 中文 | [日本語](README_JA.md) | [更新日志](CHANGELOG.md)
</div>
## ❤️赞助商
[![智谱 GLM](assets/partners/banners/glm-zh.jpg)](https://www.bigmodel.cn/claude-code?ic=RRVJPB5SII)
> [想出现在这里?](mailto:farion1231@gmail.com)
感谢智谱AI的 GLM CODING PLAN 赞助了本项目!GLM CODING PLAN 是专为AI编码打造的订阅套餐,每月最低仅需20元,即可在十余款主流AI编码工具如 Claude Code、Cline 中畅享智谱旗舰模型 GLM-4.6,为开发者提供顶尖、高速、稳定的编码体验。CC Switch 已经预设了智谱GLM,只需要填写 key 即可一键导入编程工具。智谱AI为本软件的用户提供了特别优惠,使用[此链接](https://www.bigmodel.cn/claude-code?ic=RRVJPB5SII)购买可以享受九折优惠。
<details open>
<summary>点击折叠</summary>
[![MiniMax](assets/partners/banners/minimax-zh.jpeg)](https://platform.minimaxi.com/subscribe/coding-plan?code=7kYF2VoaCn&source=link)
MiniMax M2.7 是 MiniMax 首个深度参与自我迭代的模型,可自主构建复杂 Agent Harness,并基于 Agent Teams、复杂 Skills、Tool Search Tool 等能力完成高复杂度生产力任务;其在软件工程、端到端项目交付及办公场景中表现优异,多项评测接近行业领先水平,同时具备稳定的复杂任务执行、环境交互能力以及良好的情商与身份保持能力。
[点击此处](https://platform.minimaxi.com/subscribe/coding-plan?code=7kYF2VoaCn&source=link)享 MiniMax Token Plan 专属 88 折优惠!
---
<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>感谢 PackyCode 赞助了本项目!PackyCode 是一家稳定、高效的API中转服务商,提供 Claude Code、Codex、Gemini 等多种中转服务。PackyCode 为本软件的用户提供了特别优惠,使用<a href="https://www.packyapi.com/register?aff=cc-switch">此链接</a>注册并在充值时填写"cc-switch"优惠码,可以享受9折优惠!</td>
<td>感谢 PackyCode 赞助了本项目!PackyCode 是一家稳定、高效的API中转服务商,提供 Claude Code、Codex、Gemini 等多种中转服务。PackyCode 为本软件的用户提供了特别优惠,使用<a href="https://www.packyapi.com/register?aff=cc-switch">此链接</a>注册并在充值时填写"cc-switch"优惠码,首次充值可以享受9折优惠!</td>
</tr>
<tr>
@@ -32,12 +43,34 @@
<td>感谢 AIGoCode 赞助了本项目!AIGoCode 是一个集成了 Claude Code、Codex 以及 Gemini 最新模型的一站式平台,为你提供稳定、高效且高性价比的AI编程服务。本站提供灵活的订阅计划,零封号风险,国内直连,无需魔法,极速响应。AIGoCode 为 CC Switch 的用户提供了特别福利,通过<a href="https://aigocode.com/invite/CC-SWITCH">此链接</a>注册的用户首次充值可以获得额外10%奖励额度!</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>感谢胜算云赞助了本项目!胜算云是专为AI Native Teams服务的超级工厂,工业级AI任务并行执行平台,模型商城集采直供聚合接入了Claude、Chatgpt、Gemini等海内外LLM及图片视频多媒体模型算力,绝无逆向掺水、全站模型SLA可用性高达99.7%、<a href="https://watch.shengsuanyun.com/status/shengsuanyun">监测接口</a>日常全绿。更有企业级专属定制网关,实现团队精细化成本与权限管控,智能路由+安全防护+BYOK企业自带密钥托管。平台按量及tokens plan(即将上线)计费,可开票,使用<a href="https://www.shengsuanyun.com/?from=CH_4HHXMRYF">此链接</a>注册新用户可获10元模力及首充10%赠送。</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>感谢 AICodeMirror 赞助了本项目!AICodeMirror 提供 Claude Code / Codex / Gemini CLI 官方高稳定中转服务,支持企业级高并发、极速开票、7×24 专属技术支持。
Claude Code / Codex / Gemini 官方渠道低至 3.8 / 0.2 / 0.9 折,充值更有折上折!AICodeMirror 为 CCSwitch 的用户提供了特别福利,通过<a href="https://www.aicodemirror.com/register?invitecode=9915W3">此链接</a>注册的用户,可享受首充8折,企业客户最高可享 7.5 折!</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>感谢 PatewayAI 赞助了本项目!PatewayAI 是一家面向重度 AI 开发者、专注官方直连高品质模型 API 中转服务商。提供 Claude 全系列与 Codex 系列模型,100% 官方源直供,不掺假不注水,欢迎检验。计费透明,Token 级账单可逐笔核验。
同时支持企业级高并发,并为企业客户提供了专业的管理平台,企业客户可签订正式合同并开具发票,更多详情进入官网获取联系方式。
现在通过<a href="https://pateway.ai/?ch=etzpm8&aff=WB6M6F67#/">此链接</a>注册即送 $3 试用额度,用户充值低至 6 折,邀请好友双向赠送,邀请奖励可达 $150!</td>
</tr>
<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元起!<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>
<td width="180"><a href="https://cloud.siliconflow.cn/i/drGuwc9k"><img src="assets/partners/logos/silicon_zh.jpg" alt="SiliconFlow" width="150"></a></td>
<td>感谢硅基流动赞助了本项目!硅基流动是一个高性能 AI 基础设施与模型 API 平台,一站式提供语言、语音、图像、视频等多模态模型的快速、可靠访问。平台支持按量计费、丰富的多模态模型选择、高速推理和企业级稳定性,帮助开发者和团队更高效地构建和扩展 AI 应用。通过<a href="https://cloud.siliconflow.cn/i/drGuwc9k">此链接</a>注册并完成实名认证,即可获得 ¥16 奖励金,可在平台内跨模型使用。硅基流动现已兼容 OpenClaw,用户可接入硅基流动 API Key 免费调用主流 AI 模型。</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>感谢 Cubence 赞助本项目!Cubence 是一家可靠高效的 API 中继服务提供商,提供对 Claude Code、Codex、Gemini 等模型的中继服务,并提供按量、包月等灵活的计费方式。Cubence 为 CC Switch 的用户提供了特别优惠:使用 <a href="https://cubence.com/signup?code=CCSWITCH&source=ccs">此链接</a> 注册,并在充值时输入 "CCSWITCH" 优惠码,每次充值均可享受九折优惠!</td>
@@ -49,13 +82,83 @@ Claude Code / Codex / Gemini 官方渠道低至 3.8 / 0.2 / 0.9 折,充值更
为200多家企业用户提供全球大模型API服务。· 充值即开票 ·当天开票 ·并发不限制 ·1元起充 · 7x24 在线技术辅导,GPT/Claude/Gemini全部6.8折,国内模型5~8折,Claude Code 专属模型3.4折进行中!<a href="https://www.dmxapi.cn/register?aff=bUHu">点击这里注册</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="优云智算" width="150"></a></td>
<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>
</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>感谢 Right Code 赞助了本项目!Right Code 稳定提供 Claude Code、Codex、Gemini 等模型的中转服务,并可选按量、包月两种计费模式。充值即可开票,企业、团队用户一对一对接。同时为 CC Switch 的用户提供了特别优惠:通过<a href="https://www.right.codes/register?aff=CCSWITCH">此链接</a>注册,每次充值均可获得实付金额5%的按量额度!</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>感谢 SSSAiCode 赞助了本项目!SSSAiCode 是一家稳定可靠的API中转站,致力于提供稳定、可靠、平价的Claude、CodeX模型服务,支持当日快速开票,SSSAiCode为本软件的用户提供特别优惠,使用<a href="https://www.sssaicode.com/register?ref=DCP0SM">此链接</a>注册每次充值均可享受10$的额外奖励!</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>感谢 米醋API 赞助了本项目!米醋API 是一家致力于提供极致性价比与高稳定性的全球大模型中转服务商。米醋API 背后有实体企业做核心保障,杜绝跑路风险,支持极速正规开票!我们主打“试错零成本”:1 元起充低门槛,0 手续费随时退款!米醋API 为本软件的用户提供了特别优惠,使用<a href="https://www.micuapi.ai/register?aff=aOYQ">此链接</a>注册并在充值时填写"ccswitch"优惠码可享九折优惠!</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>感谢 LemonData 赞助了本项目!LemonData 是一个高性能 AI API 聚合平台——一个 API Key 即可访问 GPT、Claude、Gemini、DeepSeek 等 300+ 模型。所有模型定价为官方价格的 30%-70%,支持自动故障转移、智能路由和无限并发。新用户注册即获 $1 免费额度——通过<a href="https://lemondata.cc/r/FFX1ZDUP">此链接</a>注册即可领取奖励,立即开始开发!</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>感谢 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 Code、Codex 及 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://claudecn.top"><img src="assets/partners/logos/claudecn.jpg" alt="ClaudeCN" width="150"></a></td>
<td>感谢 ClaudeCN 赞助本项目!ClaudeCN 由是一家实体企业运营的企业级AI中转平台。平台可提供高可用性的商用API服务,提供Claude、GPT、Deepseek等热门模型,支持企业采购流程,可对公打款、签约,服务合规有保障。点击<a href="https://claudecn.top">此链接</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>感谢 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>
</table>
</details>
## 为什么选择 CC Switch
现代 AI 编程依赖于 Claude Code、Codex、Gemini CLI、OpenCode 和 OpenClaw 等 CLI 工具——但每个工具都有自己的配置格式。切换 API 供应商意味着手动编辑 JSON、TOML 或 `.env` 文件,而在多个工具之间缺乏一个统一管理 MCP, SKILLS 的方式。
**CC Switch** 为你提供一个桌面应用来管理所有五个 CLI 工具。无需手动编辑配置文件,你将获得一个可视化界面,一键将供应商导入应用,一键在不同的供应商之间进行切换,内置 50+ 供应商预设、统一的 MCP, SKILLS 管理以及系统托盘即时切换功能——所有操作都基于可靠的 SQLite 数据库和原子写入机制,保护你的配置不被损坏。
- **一个应用,五个 CLI 工具** — 在单一界面中管理 Claude Code、Codex、Gemini CLI、OpenCode 和 OpenClaw
- **告别手动编辑** — 50+ 供应商预设,包括 AWS Bedrock、NVIDIA NIM 和社区中转服务;一键即可切换
- **统一 MCP, SKILLS 管理** — 一个面板管理四个应用的 MCP, SKILLS, 支持双向同步
- **系统托盘快速切换** — 从托盘菜单即时切换供应商,无需打开完整应用
- **云同步** — 通过 Dropbox、OneDrive、iCloud 或 WebDAV 服务器在不同设备之间同步供应商数据
- **跨平台** — 基于 Tauri 2 构建的原生桌面应用,支持 Windows、macOS 和 Linux
- **小工具** - 内置了多种小工具来解决首次安装登录确认、禁止签名、插件拓展同步等多种功能
## 界面预览
| 主界面 | 添加供应商 |
@@ -64,113 +167,132 @@ Claude Code / Codex / Gemini 官方渠道低至 3.8 / 0.2 / 0.9 折,充值更
## 功能特性
### 当前版本:v3.10.2 | [完整更新日志](CHANGELOG.md) | [发布说明](docs/release-note-v3.9.0-zh.md)
[完整更新日志](CHANGELOG.md) | [发布说明](docs/release-notes/v3.15.0-zh.md)
**v3.8.0 重大更新(2025-11-28**
### 供应商管理
**持久化架构升级 & 全新用户界面**
- **5 个 CLI 工具,50+ 预设** — Claude Code、Codex、Gemini CLI、OpenCode、OpenClaw;复制 key 即可一键导入
- **通用供应商** — 一份配置同步到多个应用(OpenCode、OpenClaw
- 一键切换、系统托盘快速访问、拖拽排序、导入导出
- **SQLite + JSON 双层架构**
- 从 JSON 文件存储迁移到 SQLite + JSON 双层结构
- 可同步数据(供应商、MCP、Prompts、Skills)存入 SQLite
- 设备级数据(窗口状态、本地路径)保留在 JSON
- 为未来云同步功能奠定基础
- Schema 版本管理支持数据库迁移
### 代理与故障转移
- **全新用户界面**
- 完全重新设计的界面布局
- 统一的组件样式和更流畅的动画
- 优化的视觉层次
- Tailwind CSS 从 v4 降级到 v3.4 以提升浏览器兼容性
- **本地代理热切换** — 格式转换、自动故障转移、熔断器、供应商健康监控和整流器
- **应用级代理接管** — 独立为 Claude、Codex 或 Gemini 配置代理,具体到单个供应商
- **日语支持**
- 新增日语界面支持(现支持中文/英文/日语)
### MCP、Prompts 与 Skills
- **开机自启**
- 在设置中一键开启/关闭
- 使用平台原生 API(注册表/LaunchAgent/XDG autostart
- **统一 MCP 面板** — 管理 4 个应用的 MCP 服务器,双向同步,支持 Deep Link 导入
- **Prompts** — Markdown 编辑器,跨应用同步(CLAUDE.md / AGENTS.md / GEMINI.md),回填保护
- **Skills** — 从 GitHub 仓库或 ZIP 文件一键安装,自定义仓库管理,支持软连接和文件复制
- **Skills 递归扫描**
- 支持多层目录结构
- 允许不同仓库的同名技能
### 用量与成本追踪
- **关键 Bug 修复**
- 修复更新供应商时自定义端点丢失问题
- 修复 Gemini 配置写入问题
- 修复 Linux WebKitGTK 渲染问题
- **用量仪表盘** — 跨供应商追踪支出、请求数和 Token 用量,趋势图表、详细请求日志和自定义模型定价
**v3.7.0 亮点**
### 会话管理器与工作区
**六大核心功能,18,000+ 行新增代码**
- 浏览、搜索和恢复全部应用对话历史
- **工作区编辑器**OpenClaw)— 编辑 Agent 文件(AGENTS.md、SOUL.md 等),支持 Markdown 预览
- **Gemini CLI 集成**
- 第三个支持的 AI CLIClaude Code / Codex / Gemini
- 双文件配置支持(`.env` + `settings.json`
- 完整 MCP 服务器管理
- 预设:Google Official (OAuth) / PackyCode / 自定义
### 系统与平台
- **Claude Skills 管理系统**
- 从 GitHub 仓库自动扫描技能(预配置 3 个精选仓库)
- 一键安装/卸载到 `~/.claude/skills/`
- 自定义仓库支持 + 子目录扫描
- 完整生命周期管理(发现/安装/更新)
- **云同步** — 自定义配置目录(Dropbox、OneDrive、iCloud、坚果云、NAS)及 WebDAV 服务器同步
- **Deep Link** (`ccswitch://`) — 通过 URL 一键导入供应商、MCP 服务器、提示词和技能
- 深色 / 浅色 / 跟随系统主题、开机自启、自动更新、原子写入、自动备份、国际化(中/英/日)
- **Prompts 管理系统**
- 多预设系统提示词管理(无限数量,快速切换)
- 跨应用支持(Claude: `CLAUDE.md` / Codex: `AGENTS.md` / Gemini: `GEMINI.md`
- Markdown 编辑器(CodeMirror 6 + 实时预览)
- 智能回填保护,保留手动修改
## 常见问题
- **MCP v3.7.0 统一架构**
- 单一面板管理三个应用的 MCP 服务器
- 新增 SSE (Server-Sent Events) 传输类型
- 智能 JSON 解析器 + Codex TOML 格式自动修正
- 统一导入/导出 + 双向同步
<details>
<summary><strong>CC Switch 支持哪些 AI CLI 工具?</strong></summary>
- **深度链接协议**
- `ccswitch://` 协议注册(全平台)
- 通过共享链接一键导入供应商配置
- 安全验证 + 生命周期集成
CC Switch 支持五个工具:**Claude Code**、**Codex**、**Gemini CLI**、**OpenCode** 和 **OpenClaw**。每个工具都有专属的供应商预设和配置管理。
- **环境变量冲突检测**
- 自动检测跨应用配置冲突(Claude/Codex/Gemini/MCP
- 可视化冲突指示器 + 解决建议
- 覆盖警告 + 更改前备份
</details>
**核心功能**
<details>
<summary><strong>切换供应商后需要重启终端吗?</strong></summary>
- **供应商管理**:一键切换 Claude Code、Codex 与 Gemini 的 API 配置
- **速度测试**:测量 API 端点延迟,可视化连接质量指示器
- **导入导出**:备份和恢复配置,自动轮换(保留最近 10 个)
- **国际化支持**:完整的中英文本地化(UI、错误、托盘)
- **Claude 插件同步**:一键应用或恢复 Claude 插件配置
大多数工具需要重启终端或 CLI 工具才能使更改生效。例外的是 **Claude Code**,它目前支持供应商数据的热切换,无需重启。
**v3.6 亮点**
</details>
- 供应商复制 & 拖拽排序
- 多端点管理 & 自定义配置目录(支持云同步)
- 细粒度模型配置(四层:Haiku/Sonnet/Opus/自定义)
- WSL 环境支持,配置目录切换自动同步
- 100% hooks 测试覆盖 & 完整架构重构
<details>
<summary><strong>切换供应商之后我的插件配置怎么不见了?</strong></summary>
**系统功能**
CC Switch 使用“通用配置片段”功能,在不同的供应商之间传递 Key 和请求地址之外的通用数据,您可以在“编辑供应商”菜单的“通用配置面板”里,点击“从当前供应商提取”,把所有的通用数据提取到通用配置中,之后在新建“供应商”的时候,只要勾选“写入通用配置”(默认勾选),就会把插件等数据写入到新的供应商配置中。您的所有配置项都会保存在运行本软件的时候,第一次导入的默认供应商里面,不会丢失。
- 系统托盘快速切换
- 单实例守护
- 内置自动更新器
- 原子写入与回滚保护
</details>
<details>
<summary><strong>macOS 安装</strong></summary>
CC Switch macOS 版本已通过 Apple 代码签名和公证,可直接下载安装,无需额外操作。推荐使用 `.dmg` 安装包。
</details>
<details>
<summary><strong>为什么总有一个正在激活中的供应商无法删除?</strong></summary>
本软件的设计原则是“最小侵入性”,即使卸载本软件,也不会影响应用的正常使用。
所以系统总会保留一个正在激活中的配置,因为如果将所有配置全部删除,该应用将无法正常使用。如果你不经常使用某个对应的应用,可以在设置中关掉该应用的显示。如果你想切换回官方登录,可以参考下条。
</details>
<details>
<summary><strong>如何切换回官方登录?</strong></summary>
可以在预设供应商里面添加一个官方供应商。切换过去之后,执行一遍 Log out / Log in 流程,之后便可以在官方供应商和第三方供应商之间随意切换。CodeX 可以在不同官方供应商之间进行切换,方便多个 Plus 或者 Team 账号之间切换。
</details>
<details>
<summary><strong>我的数据存储在哪里?</strong></summary>
- **数据库**`~/.cc-switch/cc-switch.db`(SQLite — 供应商、MCP、提示词、技能)
- **本地设置**`~/.cc-switch/settings.json`(设备级 UI 偏好设置)
- **备份**`~/.cc-switch/backups/`(自动轮换,保留最近 10 个)
- **SKILLS**`~/.cc-switch/skills/`(默认通过软链接连接到对应应用)
- **技能备份**`~/.cc-switch/skill-backups/`(卸载前自动创建,保留最近 20 个)
</details>
## 文档
如需了解各项功能的详细使用方法,请查阅 **[用户手册](docs/user-manual/zh/README.md)** — 涵盖供应商管理、MCP/Prompts/Skills、代理与故障转移等全部功能。
## 快速开始
### 基本使用
1. **添加供应商**:点击"添加供应商" → 选择预设或创建自定义配置
2. **切换供应商**
- 主界面:选择供应商 → 点击"启用"
- 系统托盘:直接点击供应商名称(立即生效)
3. **生效方式**:重启终端或对应的 CLI 工具以应用更改(CLaude Code 无需重启)
4. **恢复官方登录**:添加"官方登录"预设,重启 CLI 工具后按照其登录/OAuth 流程操作
### MCP、Prompts、Skills 与会话
- **MCP**:点击"MCP"按钮 → 通过模板或自定义配置添加服务器 → 切换各应用同步开关
- **Prompts**:点击"Prompts" → 使用 Markdown 编辑器创建预设 → 激活后同步到 live 文件
- **Skills**:点击"Skills" → 浏览 GitHub 仓库 → 一键安装到全部应用
- **会话**:点击"Sessions" → 浏览和搜索和恢复全部应用对话历史
> **注意**:首次启动可以手动导入现有 CLI 工具配置作为默认供应商。
## 下载安装
### 系统要求
- **Windows**: Windows 10 及以上
- **macOS**: macOS 10.15 (Catalina) 及以上
- **Linux**: Ubuntu 22.04+ / Debian 11+ / Fedora 34+ 等主流发行版
- **Windows**Windows 10 及以上
- **macOS**macOS 12 (Monterey) 及以上
- **Linux**Ubuntu 22.04+ / Debian 11+ / Fedora 34+ 等主流发行版
### Windows 用户
从 [Releases](../../releases) 页面下载最新版本的 `CC-Switch-v{版本号}-Windows.msi` 安装包或 `CC-Switch-v{版本号}-Windows-Portable.zip` 绿色版。
从 [Releases](../../releases) 页面下载最新版本的 `CC-Switch-v{版本号}-Windows.msi` 安装包或 `CC-Switch-v{版本号}-Windows-Portable.zip` 绿色版。
### macOS 用户
@@ -189,11 +311,11 @@ brew upgrade --cask cc-switch
**方式二:手动下载**
从 [Releases](../../releases) 页面下载 `CC-Switch-v{版本号}-macOS.zip` 解压使用
从 [Releases](../../releases) 页面下载 `CC-Switch-v{版本号}-macOS.dmg`(推荐)或 `.zip`
> **注意**由于作者没有苹果开发者账号,首次打开可能出现"未知开发者"警告,请先关闭,然后前往"系统设置" → "隐私与安全性" → 点击"仍要打开",之后便可以正常打开
> **注意**CC Switch macOS 版本已通过 Apple 代码签名和公证,可直接安装打开
### ArchLinux 用户
### Arch Linux 用户
**通过 paru 安装(推荐)**
@@ -208,98 +330,11 @@ paru -S cc-switch-bin
- `CC-Switch-v{版本号}-Linux.deb`Debian/Ubuntu
- `CC-Switch-v{版本号}-Linux.rpm`Fedora/RHEL/openSUSE
- `CC-Switch-v{版本号}-Linux.AppImage`(通用)
- `CC-Switch-v{版本号}-Linux.flatpak`Flatpak
Flatpak 安装与运行:
> **Flatpak**:官方 Release 不包含 Flatpak 包。如需使用,可从 `.deb` 自行构建 — 参见 [`flatpak/README.md`](flatpak/README.md)。
```bash
flatpak install --user ./CC-Switch-v{版本号}-Linux.flatpak
flatpak run com.ccswitch.desktop
```
## 快速开始
### 基本使用
1. **添加供应商**:点击"添加供应商" → 选择预设或创建自定义配置
2. **切换供应商**
- 主界面:选择供应商 → 点击"启用"
- 系统托盘:直接点击供应商名称(立即生效)
3. **生效方式**:重启终端或 Claude Code / Codex / Gemini 客户端以应用更改
4. **恢复官方登录**:选择"官方登录"预设(Claude/Codex)或"Google 官方"预设(Gemini),重启对应客户端后按照其登录/OAuth 流程操作
### MCP 管理
- **位置**:点击右上角"MCP"按钮
- **添加服务器**
- 使用内置模板(mcp-fetch、mcp-filesystem 等)
- 支持 stdio / http / sse 三种传输类型
- 为不同应用配置独立的 MCP 服务器
- **启用/禁用**:切换开关以控制哪些服务器同步到 live 配置
- **同步**:启用的服务器自动同步到各应用的 live 文件
- **导入/导出**:支持从 Claude/Codex/Gemini 配置文件导入现有 MCP 服务器
### Skills 管理(v3.7.0 新增)
- **位置**:点击右上角"Skills"按钮
- **发现技能**
- 自动扫描预配置的 GitHub 仓库(Anthropic 官方、ComposioHQ、社区等)
- 添加自定义仓库(支持子目录扫描)
- **安装技能**:点击"安装"一键安装到 `~/.claude/skills/`
- **卸载技能**:点击"卸载"安全移除并清理状态
- **管理仓库**:添加/删除自定义 GitHub 仓库
### Prompts 管理(v3.7.0 新增)
- **位置**:点击右上角"Prompts"按钮
- **创建预设**
- 创建无限数量的系统提示词预设
- 使用 Markdown 编辑器编写提示词(语法高亮 + 实时预览)
- **切换预设**:选择预设 → 点击"激活"立即应用
- **同步机制**
- Claude: `~/.claude/CLAUDE.md`
- Codex: `~/.codex/AGENTS.md`
- Gemini: `~/.gemini/GEMINI.md`
- **保护机制**:切换前自动保存当前提示词内容,保留手动修改
### 配置文件
**Claude Code**
- Live 配置:`~/.claude/settings.json`(或 `claude.json`
- API key 字段:`env.ANTHROPIC_AUTH_TOKEN``env.ANTHROPIC_API_KEY`
- MCP 服务器:`~/.claude.json``mcpServers`
**Codex**
- Live 配置:`~/.codex/auth.json`(必需)+ `config.toml`(可选)
- API key 字段:`auth.json` 中的 `OPENAI_API_KEY`
- MCP 服务器:`~/.codex/config.toml``[mcp_servers]`
**Gemini**
- Live 配置:`~/.gemini/.env`API Key+ `~/.gemini/settings.json`(保存认证模式)
- API key 字段:`.env` 文件中的 `GEMINI_API_KEY``GOOGLE_GEMINI_API_KEY`
- 环境变量:支持 `GOOGLE_GEMINI_BASE_URL``GEMINI_MODEL` 等自定义变量
- MCP 服务器:`~/.gemini/settings.json``mcpServers`
- 托盘快速切换:每次切换供应商都会重写 `~/.gemini/.env`,无需重启 Gemini CLI 即可生效
**CC Switch 存储(v3.8.0 新架构)**
- 数据库(SSOT):`~/.cc-switch/cc-switch.db`SQLite,存储供应商、MCP、Prompts、Skills
- 本地设置:`~/.cc-switch/settings.json`(设备级设置)
- 备份:`~/.cc-switch/backups/`(自动轮换,保留 10 个)
### 云同步设置
1. 前往设置 → "自定义配置目录"
2. 选择您的云同步文件夹(Dropbox、OneDrive、iCloud、坚果云等)
3. 重启应用以应用
4. 在其他设备上重复操作以启用跨设备同步
> **注意**:首次启动会自动导入现有 Claude/Codex 配置作为默认供应商。
## 架构总览
<details>
<summary><strong>架构总览</strong></summary>
### 设计原则
@@ -334,16 +369,15 @@ flatpak run com.ccswitch.desktop
- **ProviderService**:供应商增删改查、切换、回填、排序
- **McpService**MCP 服务器管理、导入导出、live 文件同步
- **ProxyService**:本地 Proxy 模式,支持热切换和格式转换
- **SessionManager**:全应用会话历史浏览
- **ConfigService**:配置导入导出、备份轮换
- **SpeedtestService**API 端点延迟测量
**v3.6 重构**
</details>
- 后端:5 阶段重构(错误处理 → 命令拆分 → 测试 → 服务 → 并发)
- 前端:4 阶段重构(测试基础 → hooks → 组件 → 清理)
- 测试:100% hooks 覆盖 + 集成测试(vitest + MSW
## 开发
<details>
<summary><strong>开发指南</strong></summary>
### 环境要求
@@ -404,7 +438,7 @@ cargo test test_name
cargo test --features test-hooks
```
### 测试说明v3.6 新增)
### 测试说明
**前端测试**
@@ -412,18 +446,6 @@ cargo test --features test-hooks
- 使用 **MSW (Mock Service Worker)** 模拟 Tauri API 调用
- 使用 **@testing-library/react** 进行组件测试
**测试覆盖**
- Hooks 单元测试(100% 覆盖)
- `useProviderActions` - 供应商操作
- `useMcpActions` - MCP 管理
- `useSettings` 系列 - 设置管理
- `useImportExport` - 导入导出
- 集成测试
- App 主应用流程
- SettingsDialog 完整交互
- MCP 面板功能
**运行测试**
```bash
@@ -437,49 +459,56 @@ pnpm test:unit:watch
pnpm test:unit --coverage
```
## 技术栈
### 技术栈
**前端**React 18 · TypeScript · Vite · TailwindCSS 4 · TanStack Query v5 · react-i18next · react-hook-form · zod · shadcn/ui · @dnd-kit
**前端**React 18 · TypeScript · Vite · TailwindCSS 3.4 · TanStack Query v5 · react-i18next · react-hook-form · zod · shadcn/ui · @dnd-kit
**后端**Tauri 2.8 · Rust · serde · tokio · thiserror · tauri-plugin-updater/process/dialog/store/log
**测试**vitest · MSW · @testing-library/react
## 项目结构
</details>
<details>
<summary><strong>项目结构</strong></summary>
```
├── src/ # 前端 (React + TypeScript)
│ ├── components/ # UI 组件 (providers/settings/mcp/ui)
│ ├── hooks/ # 自定义 hooks (业务逻辑)
├── src/ # 前端 (React + TypeScript)
│ ├── components/
│ ├── providers/ # 供应商管理
│ │ ├── mcp/ # MCP 面板
│ │ ├── prompts/ # Prompts 管理
│ │ ├── skills/ # Skills 管理
│ │ ├── sessions/ # 会话管理器
│ │ ├── proxy/ # Proxy 模式面板
│ │ ├── openclaw/ # OpenClaw 配置面板
│ │ ├── settings/ # 设置(终端/备份/关于)
│ │ ├── deeplink/ # Deep Link 导入
│ │ ├── env/ # 环境变量管理
│ │ ├── universal/ # 跨应用配置
│ │ ├── usage/ # 用量统计
│ │ └── ui/ # shadcn/ui 组件库
│ ├── hooks/ # 自定义 hooks(业务逻辑)
│ ├── lib/
│ │ ├── api/ # Tauri API 封装(类型安全)
│ │ └── query/ # TanStack Query 配置
│ ├── i18n/locales/ # 翻译 (zh/en)
│ ├── config/ # 预设 (providers/mcp)
│ └── types/ # TypeScript 类型定义
├── src-tauri/ # 后端 (Rust)
│ │ ├── api/ # Tauri API 封装(类型安全)
│ │ └── query/ # TanStack Query 配置
│ ├── locales/ # 翻译 (zh/en/ja)
│ ├── config/ # 预设 (providers/mcp)
│ └── types/ # TypeScript 类型定义
├── src-tauri/ # 后端 (Rust)
│ └── src/
│ ├── commands/ # Tauri 命令层(按领域)
│ ├── services/ # 业务逻辑层
│ ├── app_config.rs # 配置数据模型
│ ├── provider.rs # 供应商领域模型
│ ├── mcp.rs # MCP 同步与校验
── lib.rs # 应用入口 & 托盘菜单
├── tests/ # 前端测试
│ ├── hooks/ # 单元测试
│ └── components/ # 集成测试
└── assets/ # 截图 & 合作商资源
│ ├── commands/ # Tauri 命令层(按领域)
│ ├── services/ # 业务逻辑层
│ ├── database/ # SQLite DAO 层
│ ├── proxy/ # Proxy 模块
│ ├── session_manager/ # 会话管理
── deeplink/ # Deep Link 处理
│ └── mcp/ # MCP 同步模块
├── tests/ # 前端测试
└── assets/ # 截图 & 合作商资源
```
## 更新日志
查看 [CHANGELOG.md](CHANGELOG.md) 了解版本更新详情。
## Electron 旧版
[Releases](../../releases) 里保留 v2.0.3 Electron 旧版
如果需要旧版 Electron 代码,可以拉取 electron-legacy 分支
</details>
## 贡献
@@ -490,7 +519,8 @@ pnpm test:unit --coverage
- 通过类型检查:`pnpm typecheck`
- 通过格式检查:`pnpm format:check`
- 通过单元测试:`pnpm test:unit`
- 💡 新功能开发前,欢迎先开 issue 讨论实现方案
新功能开发前,欢迎先开 Issue 讨论实现方案,不适合项目的功能性 PR 有可能会被关闭。
## Star History
+58
View File
@@ -0,0 +1,58 @@
# Security Policy / 安全策略
## Supported Versions / 支持的版本
Only the latest release of CC Switch receives security updates.
仅最新版本的 CC Switch 会收到安全更新。
| Version / 版本 | Supported / 是否支持 |
|----------------|---------------------|
| Latest 3.x | ✅ Yes / 是 |
| < 3.0 | ❌ No / 否 |
## Reporting a Vulnerability / 报告漏洞
**Please do NOT report security vulnerabilities through public GitHub issues.**
**请不要通过公开的 GitHub Issue 报告安全漏洞。**
Instead, please report them through [GitHub Security Advisories](https://github.com/farion1231/cc-switch/security/advisories/new).
请通过 [GitHub 安全公告](https://github.com/farion1231/cc-switch/security/advisories/new) 进行报告。
When reporting, please include:
报告时请包含以下信息:
- A description of the vulnerability / 漏洞描述
- Steps to reproduce / 复现步骤
- Potential impact / 潜在影响
- Affected versions / 受影响版本
## Response Timeline / 响应时间
- **Acknowledgment / 确认**: within 48 hours / 48 小时内
- **Initial assessment / 初步评估**: within 7 days / 7 天内
- **Fix for critical issues / 关键问题修复**: within 14 days / 14 天内
## Disclosure Policy / 披露政策
We follow a coordinated disclosure process:
我们遵循协调披露流程:
1. The reporter submits the vulnerability privately. / 报告者私下提交漏洞。
2. We confirm and work on a fix. / 我们确认并修复漏洞。
3. A patch release is published. / 发布修复版本。
4. The vulnerability is publicly disclosed. / 公开披露漏洞详情。
Reporters will be credited in the release notes unless they prefer to remain anonymous.
除非报告者希望匿名,否则将在发布说明中致谢。
## Security Updates / 安全更新
Security fixes are released as patch versions and announced via [GitHub Releases](https://github.com/farion1231/cc-switch/releases). We recommend always updating to the latest version.
安全修复通过补丁版本发布,并通过 [GitHub Releases](https://github.com/farion1231/cc-switch/releases) 通知。建议始终更新到最新版本。
+59
View File
@@ -0,0 +1,59 @@
# Support / 获取帮助
> [中文版本](#获取帮助)
## How to Get Help
CC Switch is an open-source project maintained by volunteers. We're happy to help, but please use the right channel so we can respond efficiently.
### Before Asking
1. **Read the [FAQ](https://github.com/farion1231/cc-switch#faq)** — most common questions are answered there.
2. **Search [existing issues](https://github.com/farion1231/cc-switch/issues)** (including closed ones) — someone may have had the same question.
### Asking a Question
- **Usage or configuration questions**: [Open a Question issue](https://github.com/farion1231/cc-switch/issues/new?template=question.yml)
- **General discussion**: [GitHub Discussions](https://github.com/farion1231/cc-switch/discussions)
### Reporting Problems
- **Bug reports**: [Open a Bug Report](https://github.com/farion1231/cc-switch/issues/new?template=bug_report.yml)
- **Documentation issues**: [Open a Doc Issue](https://github.com/farion1231/cc-switch/issues/new?template=doc_issue.yml)
- **Security vulnerabilities**: Please do NOT use public issues. See our [Security Policy](./SECURITY.md).
### Feature Requests
- [Submit a Feature Request](https://github.com/farion1231/cc-switch/issues/new?template=feature_request.yml)
- Please open an issue for discussion before submitting a PR for new features.
---
# 获取帮助
> [English Version](#support--获取帮助)
## 如何获取帮助
CC Switch 是一个由志愿者维护的开源项目。我们很乐意提供帮助,但请使用合适的渠道,以便我们高效响应。
### 提问之前
1. **阅读 [常见问题](https://github.com/farion1231/cc-switch#常见问题)** — 大多数常见问题都已在其中解答。
2. **搜索 [已有的 Issue](https://github.com/farion1231/cc-switch/issues)**(包括已关闭的) — 可能已经有人问过相同的问题。
### 提问
- **使用或配置问题**[提交问题 Issue](https://github.com/farion1231/cc-switch/issues/new?template=question.yml)
- **一般讨论**[GitHub 讨论区](https://github.com/farion1231/cc-switch/discussions)
### 报告问题
- **Bug 报告**[提交 Bug 报告](https://github.com/farion1231/cc-switch/issues/new?template=bug_report.yml)
- **文档问题**[提交文档问题](https://github.com/farion1231/cc-switch/issues/new?template=doc_issue.yml)
- **安全漏洞**:请不要使用公开 Issue。请参阅我们的[安全策略](./SECURITY.md)。
### 功能请求
- [提交功能请求](https://github.com/farion1231/cc-switch/issues/new?template=feature_request.yml)
- 提交新功能的 PR 之前,请先开 Issue 讨论。
Binary file not shown.

After

Width:  |  Height:  |  Size: 902 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 895 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

+63
View File
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="_图层_2" data-name="图层 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1075.78 240.6">
<defs>
<style>
.cls-1 {
fill: #068cde;
}
.cls-2 {
fill: #02a4fd;
}
.cls-3 {
fill: #fff;
}
.cls-4 {
fill: #02a6ff;
}
</style>
</defs>
<g id="_图层_1-2" data-name="图层 1">
<path class="cls-1" d="M226.14,157.63c-3.62,0-7.24,0-10.95,0v-24.96c5.2,0,10.17,0,15.13,0,5.55-.01,8.52-4.01,10.18-8.16,1.34-3.37,1.36-7.51-1.34-11.1-3.16-4.2-7.23-5.72-12.25-5.63-3.87.07-7.74.01-11.66.01v-24.79c6.56-.43,12.93.45,19.3-1.13.4-.42.85-1.05,1.44-1.49,4.61-3.47,6.48-9.22,4.67-14.51-1.63-4.76-6.67-8.03-12.22-7.99-4.37.03-8.74,0-13.42,0,0-5.79.1-11.16-.04-16.54-.08-3.23-1.09-6.23-3.22-8.79-7.6-9.17-17.84-6.02-28.13-6.29-.39-.23-.63-1.14-.45-2.35.73-4.72.37-9.44-.24-14.13-.51-3.95-5.79-9.24-9.1-9.56-10.42-1-15.88,5.21-15.83,14.89.02,3.54,0,7.08,0,10.92h-24.44c-.76-1.03-.45-2.13-.42-3.19.15-5.2.71-10.35-1.11-15.5-2.15-6.08-11.68-9.27-17.05-5.79-5.27,3.41-7.22,7.95-6.99,13.99.14,3.56.53,7.22-.44,10.6h-23.98c-.22-.38-.37-.51-.37-.66-.05-4.56,0-9.12-.14-13.68-.15-5.18-4.72-10.76-9.31-11.57-8.81-1.55-15.64,4.23-15.64,13.24,0,4.11,0,8.21,0,12.61-4.92,0-9.32.08-13.72-.02-10.41-.22-18.81,7.79-17.84,18.57.39,4.32.06,8.7.06,13.34-5.17,0-9.9-.05-14.63.01-5.36.07-11.08,5.57-11.83,10.1-1.39,8.44,6.23,15.25,14.55,14.78,3.86-.22,7.74-.04,11.75-.04v24.92c-4.45,0-8.67-.07-12.89.02-3.2.07-6.5.62-8.75,2.93-3.6,3.69-6.1,8.11-4.12,13.5,2.13,5.8,6.42,8.43,12.98,8.43,4.21,0,8.42,0,12.83,0v24.95c-3.48,0-6.79-.12-10.08.03-3.74.18-7.43.36-10.78,2.69-4.11,2.87-6.48,8.21-5.32,12.83,1.1,4.36,7.17,9.83,11.59,9.41,4.82-.46,9.72-.1,14.69-.1,0,5.18.51,9.88-.1,14.44-1.36,10,8.64,18.06,17.22,17.5,4.62-.3,9.28-.05,14.15-.05,1.26,9.11-3.28,19.95,9.5,25.9,10.27,1.43,15.74-3.33,15.75-15.14,0-3.45,0-6.9,0-10.55h24.94c0,3.39,0,6.6,0,9.8,0,3.81.26,7.41,2.73,10.76,3.09,4.2,8.64,6.68,14,4.87,3.62-1.22,8.31-5.43,8.3-10.7,0-4.85,0-9.7,0-14.7h24.92c0,3.98-.14,7.7.03,11.41.22,4.83,1.4,9.35,5.68,12.32,5.16,3.59,12.81,2.96,17.28-2.41,3.93-7.43,2.05-14.57,2.39-21.58,5.71,0,11.1.03,16.49-.02,1.98-.02,4.05-.06,5.8-1.09,6.78-3.99,9.8-9.94,9.36-17.81-.23-4.18-.04-8.39-.04-12.56,8.59-1.68,18.23,2.96,24.73-6.3.08-.31.31-1.1.5-1.9.97-4.19,1.82-8.06-1.59-12.01-3.49-4.05-7.66-5.05-12.52-5.04ZM168.3,160.54c0,3.41-1.48,4.58-4.69,4.49-4.41-.12-8.82-.09-13.23-.05-3.15.03-4.43-1.39-4.41-4.56.06-16.85.02-33.69-.03-50.54,0-.99.44-2.13-.73-3.15-4.49,13.97-8.94,27.8-13.44,41.79h-21.8c-4.39-13.78-8.8-27.62-13.55-42.54-.15,1.94-.29,2.89-.29,3.84-.01,16.68-.08,33.36.04,50.04.03,3.7-1.18,5.38-5.05,5.16-5.51-.31-11.08.38-16.22-.44-1.24-1.59-1.21-2.95-1.21-4.26.07-27.3.18-54.6.22-81.9,0-2.16.89-3.46,2.97-3.48,9.9-.06,19.8,0,29.7.05.31,0,.63.19,1.39.44,4.22,14.29,8.51,28.79,12.8,43.3.29.05.58.1.87.15,4.53-14.59,9.07-29.17,13.66-43.95,10.35,0,20.48-.03,30.62.03,1.76.01,2.38,1.37,2.42,2.92.08,2.57.1,5.14.1,7.71-.06,24.98-.16,49.95-.15,74.93Z"/>
<rect class="cls-4" x="48.86" y="48.46" width="143.67" height="143.67" rx="10.57" ry="10.57"/>
<path class="cls-3" d="M165.55,75.28c-10.14-.06-20.27-.03-30.62-.03-4.59,14.78-9.12,29.36-13.66,43.95-.29-.05-.58-.1-.87-.15-4.29-14.51-8.58-29.01-12.8-43.3-.77-.25-1.08-.44-1.39-.44-9.9-.04-19.8-.1-29.7-.05-2.08.01-2.96,1.32-2.97,3.48-.04,27.3-.15,54.6-.22,81.9,0,1.31-.03,2.67,1.21,4.26,5.13.82,10.7.13,16.22.44,3.87.22,5.07-1.46,5.05-5.16-.12-16.68-.06-33.36-.04-50.04,0-.95.14-1.9.29-3.84,4.75,14.91,9.16,28.76,13.55,42.54h21.8c4.5-13.99,8.94-27.82,13.44-41.79,1.18,1.01.73,2.16.73,3.15.04,16.85.09,33.69.03,50.54-.01,3.17,1.26,4.59,4.41,4.56,4.41-.04,8.82-.07,13.23.05,3.21.09,4.69-1.08,4.69-4.49-.01-24.98.09-49.95.15-74.93,0-2.57-.02-5.14-.1-7.71-.05-1.55-.67-2.91-2.42-2.92Z"/>
<g>
<path class="cls-2" d="M372.64,135.48c-.13-.49-.54-.78-.71-.89-7.15-4.87-14.15-9.95-21.35-14.75-4.85-3.24-7.95-5.93-8.98-6.85-3.54-3.13-6.16-6.05-7.88-8.11,18.27.05,31.65-.03,32.44-.05.12,0,.6-.03.98-.42.22-.22.31-.45.35-.59.02-4.96.04-9.91.06-14.87,0-.78-.62-1.42-1.39-1.42-8.12.04-16.23.08-24.35.12,4.03-4.67,7.45-8.18,9.86-10.55,2.43-2.39,4.46-5.14,6.77-7.64,1.93-2.09,4.11-4.37,3.5-6.38-.2-.66-.63-1.08-.87-1.29-3.46-2.9-6.93-5.8-10.39-8.7-.41-.25-1.2-.63-2.04-.42-.82.21-1.3.88-1.47,1.12-3.4,4.75-5.17,7.07-5.2,7.12,0,0-1.32,2.51-13.36,16.27-.12.14-.48.54-.48,1.08,0,.5.31.88.49,1.07,2.96,2.73,5.93,5.46,8.89,8.2h-10.94v-37.5c0-.78-.62-1.42-1.39-1.42h-15.19c-.77,0-1.39.64-1.39,1.42v37.5h-13.87l10.91-9.45c.55-.48.65-1.31.23-1.91-1.08-1.54-2.47-3.35-4.11-5.37-1.64-2.02-3.6-4.28-5.8-6.7-2.13-2.43-4.13-4.59-5.93-6.43-1.8-1.83-3.5-3.43-5.06-4.75-.53-.45-1.31-.43-1.82.04l-10.51,9.67c-.29.27-.46.65-.46,1.05s.17.78.46,1.05c.96.88,2.1,2.06,3.39,3.49,1.33,1.47,2.71,3.04,4.15,4.7,1.44,1.66,2.87,3.36,4.26,5.04,1.41,1.71,2.71,3.27,3.89,4.68,1.17,1.39,2.11,2.54,2.83,3.44.86,1.09,1.04,1.35,1.04,1.35.02.03.03.06.05.09h-23.14c-.77,0-1.39.64-1.39,1.42v14.45c0,.78.62,1.42,1.39,1.42,10.73.14,21.47.29,32.2.43-3.44,3.44-6.64,6.34-9.41,8.73-4.74,4.08-8.53,6.9-9.53,7.64-5.15,3.8-7.72,5.7-9.46,6.47,0,0-1.99,2.06-9.47,6.03-.37.2-.63.55-.72.96-.09.41.01.84.27,1.18,3.31,4.84,6.62,9.68,9.93,14.51,2.17-1.39,5.05-3.3,8.34-5.71,1.13-.83,4.24-3.11,8.34-6.5,6.58-5.43,8.21-7.48,15.62-13.59,1.43-1.18,2.61-2.13,3.36-2.73v32.48c0,.78.62,1.42,1.39,1.42h15.19c.77,0,1.39-.64,1.39-1.42v-32.91c2.78,2.65,6.21,5.83,10.21,9.33,10.52,9.2,9.2,6.82,12.78,10.6,0,0,7.52,6.23,12.33,9.29.65.41,1.5.21,1.91-.45l8.68-14c.21-.34.27-.75.17-1.13Z"/>
<g>
<path class="cls-2" d="M481.65,98.3h-43.96c-.78,0-1.42.63-1.42,1.42v51.72c0,.78.63,1.42,1.42,1.42h43.96c.78,0,1.42-.63,1.42-1.42v-51.72c0-.78-.63-1.42-1.42-1.42ZM467.34,137.4h-15.33v-4.1h15.33v4.1ZM467.34,118.08h-15.33v-4.1h15.33v4.1Z"/>
<path class="cls-2" d="M485.91,80.91h-8.67v-6.03h6.54c.78,0,1.42-.63,1.42-1.42v-13.3c0-.78-.63-1.42-1.42-1.42h-6.54v-9.15c0-.78-.63-1.42-1.42-1.42h-12.56c-.78,0-1.42.63-1.42,1.42v9.15h-4.46v-9.15c0-.78-.63-1.42-1.42-1.42h-12.45c-.78,0-1.42.63-1.42,1.42v9.15h-5.54c-.56,0-1.04.32-1.27.79v-5.86c0-.78-.63-1.42-1.42-1.42h-48.55c-.78,0-1.42.63-1.42,1.42v12.96c0,.78.63,1.42,1.42,1.42h11.48v5.24h-9.91c-.78,0-1.42.63-1.42,1.42v76.27c0,.78.63,1.42,1.42,1.42h46.2c.78,0,1.42-.63,1.42-1.42v-54.75c.26.29.63.46,1.05.46h50.35c.78,0,1.42-.63,1.42-1.42v-12.96c0-.78-.63-1.42-1.42-1.42ZM421.7,136.6h-23.18v-3.98h23.18v3.98ZM421.7,117.28h-19.16c1.54-2.24,2.74-4.23,3.57-5.91.83-1.69,1.57-3.33,2.19-4.91,1.19-3.22,1.77-7.95,1.77-14.47v-3.02h.08v13.36c0,3.98.93,7.04,2.78,9.08,1.84,2.04,4.77,3.29,8.61,3.69l.17.03v2.16ZM442.11,80.91h-6.54c-.42,0-.79.18-1.05.46v-6.66c0-.78-.63-1.42-1.42-1.42h-9.57v-5.24h10.36c.56,0,1.04-.32,1.27-.79v6.2c0,.78.63,1.42,1.42,1.42h5.54v6.03ZM461.85,80.91h-4.46v-6.03h4.46v6.03Z"/>
</g>
<path class="cls-2" d="M608.47,127.84c-4.56-1.17-9.11-2.33-13.67-3.5-.16-20.74-.33-41.47-.49-62.21,0-.79-.63-1.43-1.42-1.43h-34.31v-10.58c0-.79-.63-1.43-1.42-1.43h-14.6c-.78,0-1.42.64-1.42,1.43v10.58h-32.96c-.78,0-1.42.64-1.42,1.43v66c0,.79.63,1.43,1.42,1.43h32.96v6.12c0,3.15.28,5.89.83,8.12.57,2.35,1.57,4.34,2.95,5.92,1.39,1.59,3.28,2.81,5.6,3.61,2.2.76,4.97,1.27,8.25,1.51,1.43.07,3.35.15,5.76.23,2.44.08,4.95.11,7.46.11s5-.02,7.33-.06c2.4-.04,4.24-.14,5.62-.29,3.19-.31,5.93-.72,8.16-1.23,3.05-.7,5.13-2.13,5.99-2.65,1.51-.92,3.64-2.22,5.55-4.66,1.81-2.3,2.48-4.4,3.28-6.89.81-2.52,1.79-5.71,1.06-9.61-.15-.82-.35-1.48-.5-1.94ZM541.15,112.97h-17.16v-9.73h17.16v9.73ZM541.15,87.12h-17.16v-9.84h17.16v9.84ZM558.59,77.28h18.51v9.84h-18.51v-9.84ZM558.59,103.24h18.51v9.73h-18.51v-9.73ZM590.3,133.5c-.06.19-.43,1.31-.83,1.94-1.12,1.76-3.83,1.83-12.61,1.89-7.06.05-.21-.03-7.33-.06-5.89-.02-7.51.05-8.56-1.22-1.02-1.24-1.31-3.54-1.44-4.56-.1-.8-.12-1.48-.11-1.95,10.48.04,20.96.08,31.44.12.02.9-.05,2.27-.56,3.83Z"/>
<path class="cls-2" d="M721.16,93.62h-39.92v-.2c6.24-3.1,12.4-6.63,18.31-10.49,6.14-4.01,12.31-8.35,18.34-12.9.35-.27.56-.69.56-1.13v-14.44c0-.78-.63-1.42-1.42-1.42h-87.02c-.78,0-1.42.63-1.42,1.42v14.32c0,.78.63,1.42,1.42,1.42h54.17c-.81.75-2.1,1.91-3.75,3.22-3.49,2.77-5.95,4.13-9.75,6.58-1.85,1.19-4.54,2.98-7.75,5.33-.03,2.76-.06,5.52-.1,8.29h-41.41c-.78,0-1.41.63-1.41,1.42v15c0,.78.63,1.42,1.41,1.42h41.41v21.77c0,1.22-.04,2.25-.11,3.05-.05.57-.06,1.11-.42,1.34-.35.22-.82.04-1.08-.04-1.08-.36-2.28-.11-3.42-.17-2.27-.12-2.51.11-5,.04-2.39-.07-4.79.16-7.17-.08-.27-.03-.93-.1-1.29.29-.44.48-.17,1.38-.04,1.75,1.43,4.35,2.86,8.69,4.29,13.04.11.5.34,1.22.92,1.83,1.16,1.24,2.98,1.26,4.12,1.25,9.2-.06,11.21-.21,11.21-.21,4.83-.36,5.78-.39,7.58-.96,1.76-.56,3.69-1.19,5.38-2.95,1.68-1.74,2.36-3.6,2.76-5.45.44-2.03.66-4.52.66-7.4v-27.11h39.92c.78,0,1.41-.63,1.41-1.42v-15c0-.78-.63-1.42-1.41-1.42Z"/>
<path class="cls-2" d="M839.47,131.72h-40.52v-59.68h33.89c.78,0,1.42-.63,1.42-1.42v-15.57c0-.78-.63-1.42-1.42-1.42h-86.74c-.78,0-1.42.63-1.42,1.42v15.57c0,.78.63,1.42,1.42,1.42h33.55v59.68h-40.41c-.78,0-1.42.63-1.42,1.42v15.35c0,.78.63,1.42,1.42,1.42h100.22c.78,0,1.42-.63,1.42-1.42v-15.35c0-.78-.63-1.42-1.42-1.42Z"/>
<path class="cls-2" d="M955.36,61.13h-39.83c.46-1.11.9-2.22,1.3-3.32.65-1.74,1.31-3.52,2-5.34.14-.37.12-.79-.06-1.14-.18-.35-.5-.62-.88-.72l-14.29-3.98c-.73-.2-1.49.2-1.73.93-2.48,7.62-5.66,15.09-9.45,22.22-3,5.64-6.11,10.87-9.28,15.62v-12.58c1.19-3.03,2.37-6.23,3.52-9.52,1.16-3.3,2.38-6.9,3.73-10.99.12-.36.09-.76-.09-1.1-.18-.34-.48-.59-.85-.7l-13.84-4.21c-.36-.11-.76-.07-1.09.11-.33.18-.58.49-.68.86-1.13,4.04-2.62,8.43-4.42,13.05-1.81,4.65-3.82,9.34-5.97,13.95-2.16,4.62-4.45,9.15-6.82,13.44-2.37,4.3-4.71,8.14-6.96,11.42-.42.61-.3,1.43.27,1.9l11.21,9.21c.31.26.72.37,1.12.31.4-.06.75-.29.97-.63l1.97-3.03v46.25c0,.78.63,1.42,1.42,1.42h15.09c.78,0,1.42-.63,1.42-1.42v-57.07l8.02,6.03c.62.47,1.5.35,1.98-.27,2.9-3.8,5.62-7.74,8.08-11.71,2.03-3.29,3.95-6.68,5.73-10.12v73.83c0,.78.63,1.42,1.42,1.42h14.98c.78,0,1.42-.63,1.42-1.42v-20.29h27.52c.78,0,1.42-.63,1.42-1.42v-15.12c0-.78-.63-1.42-1.42-1.42h-27.52v-10.01h25.11c.78,0,1.42-.63,1.42-1.42v-14.89c0-.78-.63-1.42-1.42-1.42h-25.11v-9.21h30.6c.78,0,1.42-.63,1.42-1.42v-14.66c0-.78-.63-1.42-1.42-1.42Z"/>
<path class="cls-2" d="M1074.36,137.97h-41.39v-4.55h31.04c.78,0,1.42-.63,1.42-1.42v-13.19c0-.78-.63-1.42-1.42-1.42h-2.25l8.41-9.22c.49-.53.5-1.35.02-1.89-2.83-3.22-6.98-7.17-12.38-11.75l-3.96-3.29h9.69c.78,0,1.42-.63,1.42-1.42v-10.52h8.59c.78,0,1.42-.63,1.42-1.42v-19.1c0-.78-.63-1.42-1.42-1.42h-39.96l-2.28-8.83c-.17-.67-.81-1.12-1.49-1.06l-16.17,1.36c-.42.04-.8.25-1.04.59-.24.34-.32.77-.21,1.18.61,2.31,1.17,4.58,1.68,6.75h-39.86c-.78,0-1.42.63-1.42,1.42v19.1c0,.78.63,1.42,1.42,1.42h8.47v10.52c0,.78.63,1.42,1.42,1.42h11.51c-1.07.86-2.12,1.69-3.13,2.46-1.91,1.47-3.64,2.66-5.15,3.54-1.12.66-2.24,1.28-3.31,1.84-.94.49-1.91.8-2.9.93-.38.05-.71.25-.94.55-.23.3-.33.68-.28,1.06l1.63,11.71c.1.69.68,1.21,1.38,1.22,5.55.08,11.18.06,16.74-.06,5.06-.1,10.15-.22,15.25-.36v3.26h-31.39c-.78,0-1.42.63-1.42,1.42v13.19c0,.78.63,1.42,1.42,1.42h31.39v4.55h-41.86c-.78,0-1.42.63-1.42,1.42v12.62c0,.78.63,1.42,1.42,1.42h101.32c.78,0,1.42-.63,1.42-1.42v-12.62c0-.78-.63-1.42-1.42-1.42ZM1055.75,115.62c.57.62,1.11,1.21,1.64,1.77h-24.42v-3.81c3.26-.13,6.47-.27,9.64-.4,3.37-.14,6.82-.32,10.27-.53,1.04,1.03,2.01,2.03,2.87,2.97ZM990.4,76.13v-3.3h66.73v3.3h-66.73ZM1009.78,99.75c1.14-.79,2.29-1.62,3.43-2.48,2.38-1.78,4.82-3.8,7.26-6.03h15.11l-2.47,2.47c-.29.29-.44.7-.41,1.11s.24.79.58,1.03c.92.68,1.91,1.41,2.95,2.2.21.16.43.33.66.51-5.44.39-10.57.68-15.27.87-4.02.16-7.98.26-11.83.31Z"/>
</g>
<g>
<polygon class="cls-2" points="700.41 193.09 700.29 193.09 695.84 175.52 688.42 175.52 688.42 199.6 692.65 199.6 692.65 179.03 692.76 178.9 698.35 199.6 702.12 199.6 708.05 178.9 708.05 179.03 708.05 199.6 712.28 199.6 712.28 175.52 705.2 175.52 700.41 193.09"/>
<path class="cls-2" d="M727.36,178.51c3.04.09,4.65,1.61,4.83,4.56h5.64c-.36-5.47-3.85-8.24-10.47-8.33-6.62.26-10.07,4.47-10.33,12.63.18,7.98,3.62,12.06,10.33,12.23,6.71-.09,10.2-2.78,10.47-8.07h-5.64c-.09,2.95-1.7,4.47-4.83,4.56-2.95-.17-4.52-3.08-4.7-8.72.18-5.73,1.75-8.68,4.7-8.85Z"/>
<path class="cls-2" d="M756.74,188.14c.08,2.86-.24,4.82-.98,5.86-.73,1.22-2.03,1.82-3.9,1.82s-3.21-.61-4.02-1.82c-.73-1.04-1.06-2.99-.97-5.86v-13.15h-4.87v15.1c.16,5.99,3.45,9.07,9.87,9.24,6.25-.17,9.5-3.25,9.75-9.24v-15.1h-4.87v13.15Z"/>
<polygon class="cls-2" points="782.14 188.79 792.21 188.79 792.21 184.76 782.14 184.76 782.14 179.16 792.98 179.16 792.98 175.13 776.98 175.13 776.98 199.2 793.37 199.2 793.37 195.17 782.14 195.17 782.14 188.79"/>
<rect class="cls-2" x="797.64" y="174.74" width="4.33" height="24.08"/>
<path class="cls-2" d="M822.27,188.31c-.09-1.04-.4-2.04-.94-2.99-1.34-2.6-3.8-3.9-7.38-3.9-5.19.26-7.92,3.21-8.19,8.85-.09,5.81,2.64,8.68,8.19,8.59,4.83,0,7.47-1.73,7.92-5.21h-4.7c-.45,1.48-1.52,2.17-3.22,2.08-2.06.09-3.04-1.3-2.95-4.17h11.41c0-1.13-.05-2.21-.13-3.25ZM810.99,188.18c.09-2.34,1.07-3.51,2.95-3.51,2.06,0,3.09,1.17,3.09,3.51h-6.04Z"/>
<path class="cls-2" d="M831.26,189.46c.28-3.34,1.07-5.01,2.37-5.01,1.67,0,2.6,1.08,2.79,3.25h5.3c-.19-4.24-2.84-6.45-7.96-6.63-4.93.36-7.63,3.43-8.1,9.2.37,5.78,3.07,8.75,8.1,8.93,5.02,0,7.68-2.21,7.96-6.63h-5.3c-.09,2.26-.98,3.38-2.65,3.38-1.49,0-2.33-1.8-2.51-5.41v-1.08Z"/>
<path class="cls-2" d="M927.16,189.69c.28-3.34,1.07-5.01,2.37-5.01,1.67,0,2.6,1.08,2.79,3.25h5.3c-.19-4.24-2.84-6.45-7.96-6.63-4.93.36-7.63,3.43-8.1,9.2.37,5.78,3.07,8.75,8.1,8.93,5.02,0,7.68-2.21,7.96-6.63h-5.3c-.09,2.26-.98,3.38-2.65,3.38-1.49,0-2.33-1.8-2.51-5.41v-1.08Z"/>
<path class="cls-2" d="M854.41,195.73c-1.36.26-1.97-.65-1.8-2.73v-7.81h3.37v-3.38h-3.37v-5.08c-1.56,0-3.12,0-4.69,0,0,1.69,0,3.39,0,5.08h-3.13v3.38h3.13c0,3.23-.02,6.45-.03,9.68.03.49.17,2.15,1.47,3.24.82.7,1.73.84,2.75,1,.82.13,2.18.24,3.88-.17,0-1.11,0-2.23-.01-3.34-.48.09-1,.13-1.56.13Z"/>
<path class="cls-2" d="M999.9,195.61c-1.36.26-1.97-.65-1.8-2.73v-7.81h3.37v-3.38h-3.37v-5.08c-1.56,0-3.12,0-4.69,0,0,1.69,0,3.39,0,5.08h-3.13v3.38h3.13l-.03,9.68c.03.49.17,2.15,1.47,3.24.82.7,1.73.84,2.75,1,.82.13,2.18.24,3.88-.17v-3.34c-.5.09-1.02.13-1.58.13Z"/>
<path class="cls-2" d="M863.85,184.64h-.13v-3.25h-4.7c0,.54.04,1.31.13,2.3v15.17h5.1v-9.21c.18-1.08.4-1.94.67-2.57.45-.54,1.3-.95,2.55-1.22h2.28v-4.6c-2.95-.18-4.92.95-5.91,3.39Z"/>
<path class="cls-2" d="M881.19,181.41c-5.4.26-8.23,3.21-8.49,8.85.25,5.55,3.08,8.42,8.49,8.59,5.4-.17,8.23-3.04,8.49-8.59-.25-5.64-3.08-8.59-8.49-8.85ZM881.19,195.73c-2.28,0-3.42-1.82-3.42-5.47s1.14-5.6,3.42-5.6c2.45,0,3.63,1.87,3.55,5.6,0,3.64-1.18,5.47-3.55,5.47Z"/>
<path class="cls-2" d="M908.77,185.85c-.08-.78-.14-1.32-.38-1.9-.5-1.26-1.5-1.96-1.82-2.16-1.45-.93-2.93-.77-3.33-.71-.79-.01-2.53.08-4.12,1.26-.46.34-.82.71-1.1,1.06,0-.67,0-1.34-.01-2h-5.1v17.48h5.1v-10.43c.27-2.53,1.3-3.88,3.09-4.07,2.06,0,3.09,1.36,3.09,4.07v10.43c1.56,0,3.12,0,4.68.01,0-3.79-.02-7.57-.03-11.36.01-.42,0-.99-.07-1.67Z"/>
<rect class="cls-2" x="913.06" y="174.68" width="4.81" height="4.29"/>
<rect class="cls-2" x="913.18" y="181.97" width="4.58" height="16.79"/>
<path class="cls-2" d="M950.52,188.05c-2.08-.52-3.12-1.13-3.12-1.82,0-1.04.62-1.56,1.87-1.56,1.33.09,2.04.65,2.12,1.69h4.37c-.25-3.3-2.41-4.95-6.49-4.95-4.41.35-6.7,2-6.86,4.95-.17,2.86,1.79,4.69,5.86,5.47,2.08.44,3.16,1.13,3.24,2.08,0,1.22-.75,1.82-2.24,1.82-1.58-.09-2.45-.74-2.62-1.95h-4.49c.17,3.3,2.54,4.99,7.11,5.08,4.57-.35,6.99-2.08,7.24-5.21-.67-3.47-2.66-5.34-5.99-5.6Z"/>
<path class="cls-2" d="M980.42,184.99c-.32-.09-.51-.13-.59-.13-2.84-.43-4.18-1.56-4.02-3.38.08-1.91,1.26-2.95,3.55-3.12,2.29,0,3.47,1.22,3.55,3.64h4.5c-.24-4.69-2.72-7.16-7.45-7.42-5.84.35-8.87,2.99-9.11,7.94,0,3.21,2.4,5.42,7.22,6.64.16.09.43.17.83.26,2.76.61,4.14,1.74,4.14,3.38-.08,2-1.54,3.04-4.38,3.12-2.45-.17-3.67-1.65-3.67-4.43h-4.73c-.08,5.29,2.72,7.94,8.4,7.94,6.15-.17,9.26-2.78,9.34-7.81.08-3.3-2.45-5.51-7.57-6.64Z"/>
<path class="cls-2" d="M1020.78,181.81h-3.98c0,3.43.01,6.87.02,10.3,0,.19-.07,2.13-1.58,3.1-.96.62-2.02.54-2.38.52-.37-.03-1.06-.05-1.65-.47-.81-.57-1.24-1.68-1.29-3.31v-10.15h-4.23c-.01,3.67-.03,7.34-.04,11.01-.01.42.01,1.04.21,1.75.62,2.23,2.61,4.11,4.98,4.62,2.07.45,3.82-.28,4.27-.48.4-.17.72-.36.95-.5,0,.34,0,.68.01,1.02,1.58-.01,3.15-.03,4.73-.04,0-1.2-.01-2.39-.02-3.59v-13.8Z"/>
<path class="cls-2" d="M1042.61,174.52h-4.95v9.24c-1.1-1.47-2.58-2.26-4.44-2.34-4.74.26-7.27,3.21-7.61,8.85.34,5.55,2.71,8.42,7.1,8.59,2.37,0,4.01-.87,4.95-2.6,0,.26.04.65.13,1.17v1.17h4.95c-.09-1.04-.13-2.17-.13-3.38v-20.69ZM1034.24,195.73c-2.45,0-3.64-1.82-3.55-5.47-.09-3.73,1.1-5.6,3.55-5.6,2.11.17,3.25,2.04,3.42,5.6-.17,3.47-1.31,5.29-3.42,5.47Z"/>
<rect class="cls-2" x="1046.8" y="174.52" width="4.96" height="4.29"/>
<rect class="cls-2" x="1046.92" y="181.81" width="4.71" height="16.79"/>
<path class="cls-2" d="M1063.98,181.41c-5.35.26-8.14,3.21-8.39,8.85.25,5.55,3.05,8.42,8.39,8.59,5.34-.17,8.14-3.04,8.39-8.59-.25-5.64-3.05-8.59-8.39-8.85ZM1063.98,195.73c-2.25,0-3.38-1.82-3.38-5.47s1.13-5.6,3.38-5.6c2.42,0,3.59,1.87,3.51,5.6,0,3.64-1.17,5.47-3.51,5.47Z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

+1
View File
@@ -19,3 +19,4 @@
"hooks": "@/hooks"
}
}
-169
View File
@@ -1,169 +0,0 @@
# CC Switch Rust 后端重构方案
## 目录
- [背景与现状](#背景与现状)
- [问题确认](#问题确认)
- [方案评估](#方案评估)
- [渐进式重构路线](#渐进式重构路线)
- [测试策略](#测试策略)
- [风险与对策](#风险与对策)
- [总结](#总结)
## 背景与现状
- 前端已完成重构,后端 (Tauri + Rust) 仍维持历史结构。
- 核心文件集中在 `src-tauri/src/commands.rs``lib.rs` 等超大文件中,业务逻辑与界面事件耦合严重。
- 测试覆盖率低,只有零散单元测试,缺乏集成验证。
## 问题确认
| 提案问题 | 实际情况 | 严重程度 |
| --- | --- | --- |
| `commands.rs` 过长 | ✅ 1526 行,包含 32 个命令,职责混杂 | 🔴 高 |
| `lib.rs` 缺少服务层 | ✅ 541 行,托盘/事件/业务逻辑耦合 | 🟡 中 |
| `Result<T, String>` 泛滥 | ✅ 118 处,错误上下文丢失 | 🟡 中 |
| 全局 `Mutex` 阻塞 | ✅ 31 处 `.lock()` 调用,读写不分离 | 🟡 中 |
| 配置逻辑分散 | ✅ 分布在 5 个文件 (`config`/`app_config`/`app_store`/`settings`/`codex_config`) | 🟢 低 |
代码规模分布(约 5.4k SLOC):
- `commands.rs`: 1526 行(28%)→ 第一优先级 🎯
- `lib.rs`: 541 行(10%)→ 托盘逻辑与业务耦合
- `mcp.rs`: 732 行(14%)→ 相对清晰
- `migration.rs`: 431 行(8%)→ 一次性逻辑
- 其他文件合计:2156 行(40%)
## 方案评估
### ✅ 优点
1. **分层架构清晰**
- `commands/`Tauri 命令薄层
- `services/`:业务流程,如供应商切换、MCP 同步
- `infrastructure/`:配置读写、外设交互
- `domain/`:数据模型 (`Provider`, `AppType` 等)
→ 提升可测试性、降低耦合度、方便团队协作。
2. **统一错误处理**
- 引入 `AppError``thiserror`),保留错误链和上下文。
- Tauri 命令仍返回 `Result<T, String>`,通过 `From<AppError>` 自动转换。
- 改善日志可读性,利于排查。
3. **并发优化**
- `AppState` 切换为 `RwLock<MultiAppConfig>`
- 读多写少的场景提升吞吐(如频繁查询供应商列表)。
### ⚠️ 风险
1. **过度设计**
- 完整 DDD 四层在 5k 行项目中会增加 30-50% 维护成本。
- Rust trait + repository 样板较多,收益不足。
- 推荐“轻量分层”而非正统 DDD。
2. **迁移成本高**
- `commands.rs` 拆分、错误统一、锁改造触及多文件。
- 测试缺失导致重构风险高,需先补测试。
- 估算完整改造需 5-6 周;建议分阶段输出可落地价值。
3. **技术选型需谨慎**
- `parking_lot` 相比标准库 `RwLock` 提升有限,不必引入。
- `spawn_blocking` 仅用于 >100ms 的阻塞任务,避免滥用。
- 以现有依赖为主,控制复杂度。
## 实施进度
- **阶段 1:统一错误处理 ✅**
- 引入 `thiserror` 并在 `src-tauri/src/error.rs` 定义 `AppError`,提供常用构造函数和 `From<AppError> for String`,保留错误链路。
- 配置、存储、同步等核心模块(`config.rs``app_config.rs``app_store.rs``store.rs``codex_config.rs``claude_mcp.rs``claude_plugin.rs``import_export.rs``mcp.rs``migration.rs``speedtest.rs``usage_script.rs``settings.rs``lib.rs` 等)已统一返回 `Result<_, AppError>`,避免字符串错误丢失上下文。
- Tauri 命令层继续返回 `Result<_, String>`,通过 `?` + `Into<String>` 统一转换,前端无需调整。
- `cargo check` 通过,`rg "Result<[^>]+, String"` 巡检确认除命令层外已无字符串错误返回。
- **阶段 2:拆分命令层 ✅**
- 已将单一 `src-tauri/src/commands.rs` 拆分为 `commands/{provider,mcp,config,settings,misc,plugin}.rs` 并通过 `commands/mod.rs` 统一导出,保持对外 API 不变。
- 每个文件聚焦单一功能域(供应商、MCP、配置、设置、杂项、插件),命令函数平均 150-250 行,可读性与后续维护性显著提升。
- 相关依赖调整后 `cargo check` 通过,静态巡检确认无重复定义或未注册命令。
- **阶段 3:补充测试 ✅**
- `tests/import_export_sync.rs` 集成测试涵盖配置备份、Claude/Codex live 同步、MCP 投影与 Codex/Claude 双向导入流程,并新增启用项清理、非法 TOML 抛错等失败场景验证;统一使用隔离 HOME 目录避免污染真实用户环境。
- 扩展 `lib.rs` re-export,暴露 `AppType``MultiAppConfig``AppError`、配置 IO 以及 Codex/Claude MCP 路径与同步函数,方便服务层及测试直接复用核心逻辑。
- 新增负向测试验证 Codex 供应商缺少 `auth` 字段时的错误返回,并补充备份数量上限测试;顺带修复 `create_backup` 采用内存读写避免拷贝继承旧的修改时间,确保最新备份不会在清理阶段被误删。
- 针对 `codex_config::write_codex_live_atomic` 补充成功与失败场景测试,覆盖 auth/config 原子写入与失败回滚逻辑(模拟目标路径为目录时的 rename 失败),降低 Codex live 写入回归风险。
- 新增 `tests/provider_commands.rs` 覆盖 `switch_provider` 的 Codex 正常流程与供应商缺失分支,并抽取 `switch_provider_internal` 以复用 `AppError`,通过 `switch_provider_test_hook` 暴露测试入口;同时共享 `tests/support.rs` 提供隔离 HOME / 互斥工具函数。
- 补充 Claude 切换集成测试,验证 live `settings.json` 覆写、新旧供应商快照回填以及 `.cc-switch/config.json` 持久化结果,确保阶段四提取服务层时拥有可回归的用例。
- 增加 Codex 缺失 `auth` 场景测试,确认 `switch_provider_internal` 在关键字段缺失时返回带上下文的 `AppError`,同时保持内存状态未被污染。
- 为配置导入命令抽取复用逻辑 `import_config_from_path` 并补充成功/失败集成测试,校验备份生成、状态同步、JSON 解析与文件缺失等错误回退路径;`export_config_to_file` 亦具备成功/缺失源文件的命令级回归。
- 新增 `tests/mcp_commands.rs`,通过测试钩子覆盖 `import_default_config``import_mcp_from_claude``set_mcp_enabled` 等命令层行为,验证缺失文件/非法 JSON 的错误回滚以及成功路径落盘效果;阶段三目标达成,命令层关键边界已具备回归保障。
- **阶段 4:服务层抽象 🚧(进行中)**
- 新增 `services/provider.rs` 并实现 `ProviderService::switch` / `delete`,集中处理供应商切换、回填、MCP 同步等核心业务;命令层改为薄封装并在 `tests/provider_service.rs``tests/provider_commands.rs` 中完成成功与失败路径的集成验证。
- 新增 `services/mcp.rs` 提供 `McpService`,封装 MCP 服务器的查询、增删改、启用同步与导入流程;命令层改为参数解析 + 调用服务,`tests/mcp_commands.rs` 直接使用 `McpService` 验证成功与失败路径,阶段三测试继续适配。
- `McpService` 在内部先复制内存快照、释放写锁,再执行文件同步,避免阶段五升级后的 `RwLock` 在 I/O 场景被长时间占用;`upsert/delete/set_enabled/sync_enabled` 均已修正。
- 新增 `services/config.rs` 提供 `ConfigService`,统一处理配置导入导出、备份与 live 同步;命令层迁移至 `commands/import_export.rs`,在落盘操作前释放锁并复用现有集成测试。
- 新增 `services/speedtest.rs` 并实现 `SpeedtestService::test_endpoints`,将 URL 校验、超时裁剪与网络请求封装在服务层,命令改为薄封装;补充单元测试覆盖空列表与非法 URL 分支。
- 后续可选:应用设置(Store)命令仍较薄,可按需评估是否抽象;当前阶段四核心服务已基本齐备。
- **阶段 5:锁与阻塞优化 ✅(首轮)**
- `AppState` 已由 `Mutex<MultiAppConfig>` 切换为 `RwLock<MultiAppConfig>`,托盘、命令与测试均按读写语义区分 `read()` / `write()``cargo test` 全量通过验证并未破坏现有流程。
- 针对高开销 IO 的配置导入/导出命令提取 `load_config_for_import`,并通过 `tauri::async_runtime::spawn_blocking` 将文件读写与备份迁至阻塞线程,保持命令处理线程轻量。
- 其余命令梳理后确认仍属轻量同步操作,暂不额外引入 `spawn_blocking`;若后续出现新的长耗时流程,再按同一模式扩展。
## 渐进式重构路线
### 阶段 1:统一错误处理(高收益 / 低风险)
- 新增 `src-tauri/src/error.rs`,定义 `AppError`
- 底层文件 IO、配置解析等函数返回 `Result<T, AppError>`
- 命令层通过 `?` 自动传播,最终 `.map_err(Into::into)`
- 预估 3-5 天,立即启动。
### 阶段 2:拆分 `commands.rs`(高收益 / 中风险)
- 按业务拆分为 `commands/provider.rs``commands/mcp.rs``commands/config.rs``commands/settings.rs``commands/misc.rs`
- `commands/mod.rs` 统一导出和注册。
- 文件行数降低到 200-300 行/文件,职责单一。
- 预估 5-7 天,可并行进行部分重构。
### 阶段 3:补充测试(中收益 / 中风险)
- 引入 `tests/``src-tauri/tests/` 集成测试,覆盖供应商切换、MCP 同步、配置迁移。
- 使用 `tempfile`/`tempdir` 隔离文件系统,组合少量回归脚本。
- 预估 5-7 天,为后续重构提供安全网。
### 阶段 4:提取轻量服务层(中收益 / 中风险)
- 新增 `services/provider_service.rs``services/mcp_service.rs`
- 不强制使用 trait;直接以自由函数/结构体实现业务流程。
```rust
pub struct ProviderService;
impl ProviderService {
pub fn switch(config: &mut MultiAppConfig, app: AppType, id: &str) -> Result<(), AppError> {
// 业务流程:验证、回填、落盘、更新 current、触发事件
}
}
```
- 命令层负责参数解析,服务层处理业务逻辑,托盘逻辑重用同一接口。
- 预估 7-10 天,可在测试补齐后执行。
### 阶段 5:锁与阻塞优化(低收益 / 低风险)
- ✅ `AppState` 已从 `Mutex` 切换为 `RwLock`,命令与托盘读写按需区分,现有测试全部通过。
- ✅ 配置导入/导出命令通过 `spawn_blocking` 处理高开销文件 IO;其他命令维持同步执行以避免不必要调度。
- 🔄 持续监控:若后续引入新的批量迁移或耗时任务,再按相同模式扩展到阻塞线程;观察运行时锁竞争情况,必要时考虑进一步拆分状态或引入缓存。
## 测试策略
- **优先覆盖场景**
- 供应商切换:状态更新 + live 配置同步
- MCP 同步:enabled 服务器快照与落盘
- 配置迁移:归档、备份与版本升级
- **推荐结构**
```rust
#[cfg(test)]
mod integration {
use super::*;
#[test]
fn switch_provider_updates_live_config() { /* ... */ }
#[test]
fn sync_mcp_to_codex_updates_claude_config() { /* ... */ }
#[test]
fn migration_preserves_backup() { /* ... */ }
}
```
- 目标覆盖率:关键路径 >80%,文件 IO/迁移 >70%。
## 风险与对策
- **测试不足** → 阶段 3 强制补齐,建立基础集成测试。
- **重构跨度大** → 按阶段在独立分支推进(如 `refactor/backend-step1` 等)。
- **回滚困难** → 每阶段结束打 tag(如 `v3.6.0-backend-step1`),保留回滚点。
- **功能回归** → 重构后执行手动冒烟流程:供应商切换、托盘操作、MCP 同步、配置导入导出。
## 总结
- 当前规模下不建议整体引入完整 DDD/四层架构,避免过度设计。
- 建议遵循“错误统一 → 命令拆分 → 补测试 → 服务层抽象 → 锁优化”的渐进式策略。
- 完成阶段 1-3 后即可显著提升可维护性与可靠性;阶段 4-5 可根据资源灵活安排。
- 重构过程中同步维护文档与测试,确保团队成员对架构演进保持一致认知。
File diff suppressed because it is too large Load Diff
-490
View File
@@ -1,490 +0,0 @@
# CC Switch 重构实施清单
> 用于跟踪重构进度的详细检查清单
**开始日期**: ___________
**预计完成**: ___________
**当前阶段**: ___________
---
## 📋 阶段 0: 准备阶段 (预计 1 天)
### 环境准备
- [ ] 创建新分支 `refactor/modernization`
- [ ] 创建备份标签 `git tag backup-before-refactor`
- [ ] 备份用户配置文件 `~/.cc-switch/config.json`
- [ ] 通知团队成员重构开始
### 依赖安装
```bash
pnpm add @tanstack/react-query
pnpm add react-hook-form @hookform/resolvers
pnpm add zod
pnpm add sonner
pnpm add next-themes
pnpm add @radix-ui/react-dialog @radix-ui/react-dropdown-menu
pnpm add @radix-ui/react-label @radix-ui/react-select
pnpm add @radix-ui/react-slot @radix-ui/react-switch @radix-ui/react-tabs
pnpm add class-variance-authority clsx tailwind-merge tailwindcss-animate
```
- [ ] 安装核心依赖 (上述命令)
- [ ] 验证依赖安装成功 `pnpm install`
- [ ] 验证编译通过 `pnpm typecheck`
### 配置文件
- [ ] 创建 `components.json`
- [ ] 更新 `tsconfig.json` 添加路径别名
- [ ] 更新 `vite.config.mts` 添加路径解析
- [ ] 验证开发服务器启动 `pnpm dev`
**完成时间**: ___________
**遇到的问题**: ___________
---
## 📋 阶段 1: 基础设施 (预计 2-3 天)
### 1.1 工具函数和基础组件
- [ ] 创建 `src/lib/utils.ts` (cn 函数)
- [ ] 创建 `src/components/ui/button.tsx`
- [ ] 创建 `src/components/ui/dialog.tsx`
- [ ] 创建 `src/components/ui/input.tsx`
- [ ] 创建 `src/components/ui/label.tsx`
- [ ] 创建 `src/components/ui/textarea.tsx`
- [ ] 创建 `src/components/ui/select.tsx`
- [ ] 创建 `src/components/ui/switch.tsx`
- [ ] 创建 `src/components/ui/tabs.tsx`
- [ ] 创建 `src/components/ui/sonner.tsx`
- [ ] 创建 `src/components/ui/form.tsx`
**测试**:
- [ ] 验证所有 UI 组件可以正常导入
- [ ] 创建一个测试页面验证组件样式
### 1.2 Query Client 设置
- [ ] 创建 `src/lib/query/queryClient.ts`
- [ ] 配置默认选项 (retry, staleTime 等)
- [ ] 导出 queryClient 实例
### 1.3 API 层
- [ ] 创建 `src/lib/api/providers.ts`
- [ ] getAll
- [ ] getCurrent
- [ ] add
- [ ] update
- [ ] delete
- [ ] switch
- [ ] importDefault
- [ ] updateTrayMenu
- [ ] 创建 `src/lib/api/settings.ts`
- [ ] get
- [ ] save
- [ ] 创建 `src/lib/api/mcp.ts`
- [ ] getConfig
- [ ] upsertServer
- [ ] deleteServer
- [ ] 创建 `src/lib/api/index.ts` (聚合导出)
**测试**:
- [ ] 验证 API 调用不会出现运行时错误
- [ ] 确认类型定义正确
### 1.4 Query Hooks
- [ ] 创建 `src/lib/query/queries.ts`
- [ ] useProvidersQuery
- [ ] useSettingsQuery
- [ ] useMcpConfigQuery
- [ ] 创建 `src/lib/query/mutations.ts`
- [ ] useAddProviderMutation
- [ ] useSwitchProviderMutation
- [ ] useDeleteProviderMutation
- [ ] useUpdateProviderMutation
- [ ] useSaveSettingsMutation
- [ ] 创建 `src/lib/query/index.ts` (聚合导出)
**测试**:
- [ ] 在临时组件中测试每个 hook
- [ ] 验证 loading/error 状态正确
- [ ] 验证缓存和自动刷新工作
**完成时间**: ___________
**遇到的问题**: ___________
---
## 📋 阶段 2: 核心功能重构 (预计 3-4 天)
### 2.1 主题系统
- [ ] 创建 `src/components/theme-provider.tsx`
- [ ] 创建 `src/components/mode-toggle.tsx`
- [ ] 更新 `src/index.css` 添加主题变量
- [ ] 删除 `src/hooks/useDarkMode.ts`
- [ ] 更新所有组件使用新的主题系统
**测试**:
- [ ] 验证主题切换正常工作
- [ ] 验证系统主题跟随功能
- [ ] 验证主题持久化
### 2.2 更新 main.tsx
- [ ] 引入 QueryClientProvider
- [ ] 引入 ThemeProvider
- [ ] 添加 Toaster 组件
- [ ] 移除旧的 API 导入
**测试**:
- [ ] 验证应用可以正常启动
- [ ] 验证 Context 正确传递
### 2.3 重构 App.tsx
- [ ] 使用 useProvidersQuery 替代手动状态管理
- [ ] 移除所有 loadProviders 相关代码
- [ ] 移除手动 notification 状态
- [ ] 简化事件监听逻辑
- [ ] 更新对话框为新的 Dialog 组件
**目标**: 将 412 行代码减少到 ~100 行
**测试**:
- [ ] 验证供应商列表正常加载
- [ ] 验证切换 Claude/Codex 正常工作
- [ ] 验证事件监听正常工作
### 2.4 重构 ProviderList
- [ ] 创建 `src/components/providers/ProviderList.tsx`
- [ ] 使用 mutation hooks 处理操作
- [ ] 移除 onNotify prop
- [ ] 移除手动状态管理
**测试**:
- [ ] 验证供应商列表渲染
- [ ] 验证切换操作
- [ ] 验证删除操作
### 2.5 重构表单系统
- [ ] 创建 `src/lib/schemas/provider.ts` (Zod schema)
- [ ] 创建 `src/components/providers/ProviderForm.tsx`
- [ ] 使用 react-hook-form
- [ ] 使用 zodResolver
- [ ] 字段级验证
- [ ] 创建 `src/components/providers/AddProviderDialog.tsx`
- [ ] 使用新的 Dialog 组件
- [ ] 集成 ProviderForm
- [ ] 使用 useAddProviderMutation
- [ ] 创建 `src/components/providers/EditProviderDialog.tsx`
- [ ] 使用新的 Dialog 组件
- [ ] 集成 ProviderForm
- [ ] 使用 useUpdateProviderMutation
**测试**:
- [ ] 验证表单验证正常工作
- [ ] 验证错误提示显示正确
- [ ] 验证提交操作成功
- [ ] 验证表单重置功能
### 2.6 清理旧组件
- [x] 删除 `src/components/AddProviderModal.tsx`
- [x] 删除 `src/components/EditProviderModal.tsx`
- [x] 更新所有引用这些组件的地方
- [x] 删除 `src/components/ProviderForm.tsx``src/components/ProviderForm/`
**完成时间**: ___________
**遇到的问题**: ___________
---
## 📋 阶段 3: 设置和辅助功能 (预计 2-3 天)
### 3.1 重构 SettingsDialog
- [ ] 创建 `src/components/settings/SettingsDialog.tsx`
- [ ] 使用 Tabs 组件
- [ ] 集成各个设置子组件
- [ ] 创建 `src/components/settings/GeneralSettings.tsx`
- [ ] 语言设置
- [ ] 配置目录设置
- [ ] 其他通用设置
- [ ] 创建 `src/components/settings/AboutSection.tsx`
- [ ] 版本信息
- [ ] 更新检查
- [ ] 链接
- [ ] 创建 `src/components/settings/ImportExportSection.tsx`
- [ ] 导入功能
- [ ] 导出功能
**目标**: 将 643 行拆分为 4-5 个小组件,每个 100-150 行
**测试**:
- [ ] 验证设置保存功能
- [ ] 验证导入导出功能
- [ ] 验证更新检查功能
### 3.2 重构通知系统
- [ ] 在所有 mutations 中使用 `toast` 替代 `showNotification`
- [ ] 移除 App.tsx 中的 notification 状态
- [ ] 移除自定义通知组件
**测试**:
- [ ] 验证成功通知显示
- [ ] 验证错误通知显示
- [ ] 验证通知自动消失
### 3.3 重构确认对话框
- [ ] 更新 `src/components/ConfirmDialog.tsx` 使用新的 Dialog
- [ ] 或者直接使用 shadcn/ui 的 AlertDialog
**测试**:
- [ ] 验证删除确认对话框
- [ ] 验证其他确认场景
**完成时间**: ___________
**遇到的问题**: ___________
---
## 📋 阶段 4: 清理和优化 (预计 1-2 天)
### 4.1 移除旧代码
- [x] 删除 `src/lib/styles.ts`
- [x]`src/lib/tauri-api.ts` 移除 `window.api` 绑定
- [x] 精简 `src/lib/tauri-api.ts`,只保留事件监听相关
- [x] 删除或更新 `src/vite-env.d.ts` 中的过时类型
### 4.2 代码审查
- [ ] 检查所有 TODO 注释
- [x] 检查是否还有 `window.api` 调用
- [ ] 检查是否还有手动状态管理
- [x] 统一代码风格
### 4.3 类型检查
- [x] 运行 `pnpm typecheck` 确保无错误
- [x] 修复所有类型错误
- [x] 更新类型定义
### 4.4 性能优化
- [ ] 检查是否有不必要的重渲染
- [ ] 添加必要的 React.memo
- [ ] 优化 Query 缓存配置
**完成时间**: ___________
**遇到的问题**: ___________
---
## 📋 阶段 5: 测试和修复 (预计 2-3 天)
### 5.1 功能测试
#### 供应商管理
- [ ] 添加供应商 (Claude)
- [ ] 添加供应商 (Codex)
- [ ] 编辑供应商
- [ ] 删除供应商
- [ ] 切换供应商
- [ ] 导入默认配置
#### 应用切换
- [ ] Claude <-> Codex 切换
- [ ] 切换后数据正确加载
- [ ] 切换后托盘菜单更新
#### 设置
- [ ] 保存通用设置
- [ ] 切换语言
- [ ] 配置目录选择
- [ ] 导入配置
- [ ] 导出配置
#### UI 交互
- [ ] 主题切换 (亮色/暗色)
- [ ] 对话框打开/关闭
- [ ] 表单验证
- [ ] Toast 通知
#### MCP 管理
- [ ] 列表显示
- [ ] 添加 MCP
- [ ] 编辑 MCP
- [ ] 删除 MCP
- [ ] 启用/禁用 MCP
### 5.2 边界情况测试
- [ ] 空供应商列表
- [ ] 无效配置文件
- [ ] 网络错误
- [ ] 后端错误响应
- [ ] 并发操作
- [ ] 表单输入边界值
### 5.3 兼容性测试
- [ ] Windows 测试
- [ ] macOS 测试
- [ ] Linux 测试
### 5.4 性能测试
- [ ] 100+ 供应商加载速度
- [ ] 快速切换供应商
- [ ] 内存使用情况
- [ ] CPU 使用情况
### 5.5 Bug 修复
**Bug 列表** (发现后记录):
1. ___________
- [ ] 已修复
- [ ] 已验证
2. ___________
- [ ] 已修复
- [ ] 已验证
**完成时间**: ___________
**遇到的问题**: ___________
---
## 📋 最终检查
### 代码质量
- [ ] 所有 TypeScript 错误已修复
- [ ] 运行 `pnpm format` 格式化代码
- [ ] 运行 `pnpm typecheck` 通过
- [ ] 代码审查完成
### 文档更新
- [ ] 更新 `CLAUDE.md` 反映新架构
- [ ] 更新 `README.md` (如有必要)
- [ ] 添加 Migration Guide (可选)
### 性能基准
记录性能数据:
**旧版本**:
- 启动时间: _____ms
- 供应商加载: _____ms
- 内存占用: _____MB
**新版本**:
- 启动时间: _____ms
- 供应商加载: _____ms
- 内存占用: _____MB
### 代码统计
**代码行数对比**:
| 文件 | 旧版本 | 新版本 | 减少 |
|------|--------|--------|------|
| App.tsx | 412 | ~100 | -76% |
| tauri-api.ts | 712 | ~50 | -93% |
| ProviderForm.tsx | 271 | ~150 | -45% |
| settings 模块 | 1046 | ~470 (拆分) | -55% |
| **总计** | 2038 | ~700 | **-66%** |
---
## 📦 发布准备
### Pre-release 测试
- [ ] 创建 beta 版本 `v4.0.0-beta.1`
- [ ] 在测试环境验证
- [ ] 收集用户反馈
### 正式发布
- [ ] 合并到 main 分支
- [ ] 创建 Release Tag `v4.0.0`
- [ ] 更新 Changelog
- [ ] 发布 GitHub Release
- [ ] 通知用户更新
---
## 🚨 回滚触发条件
如果出现以下情况,考虑回滚:
- [ ] 重大功能无法使用
- [ ] 用户数据丢失
- [ ] 严重性能问题
- [ ] 无法修复的兼容性问题
**回滚命令**:
```bash
git reset --hard backup-before-refactor
# 或
git revert <commit-range>
```
---
## 📝 总结报告
### 成功指标
- [ ] 所有现有功能正常工作
- [ ] 代码量减少 40%+
- [ ] 无用户数据丢失
- [ ] 性能未下降
### 经验教训
**遇到的主要挑战**:
1. ___________
2. ___________
3. ___________
**解决方案**:
1. ___________
2. ___________
3. ___________
**未来改进**:
1. ___________
2. ___________
3. ___________
---
**重构完成日期**: ___________
**总耗时**: _____
**参与人员**: ___________
File diff suppressed because it is too large Load Diff
-834
View File
@@ -1,834 +0,0 @@
# 重构快速参考指南
> 常见模式和代码示例的速查表
---
## 📑 目录
1. [React Query 使用](#react-query-使用)
2. [react-hook-form 使用](#react-hook-form-使用)
3. [shadcn/ui 组件使用](#shadcnui-组件使用)
4. [代码迁移示例](#代码迁移示例)
---
## React Query 使用
### 基础查询
```typescript
// 定义查询 Hook
export const useProvidersQuery = (appId: AppId) => {
return useQuery({
queryKey: ['providers', appId],
queryFn: async () => {
const data = await providersApi.getAll(appId)
return data
},
})
}
// 在组件中使用
function MyComponent() {
const { data, isLoading, error } = useProvidersQuery('claude')
if (isLoading) return <div>Loading...</div>
if (error) return <div>Error: {error.message}</div>
return <div>{/* 使用 data */}</div>
}
```
### Mutation (变更操作)
```typescript
// 定义 Mutation Hook
export const useAddProviderMutation = (appId: AppId) => {
const queryClient = useQueryClient()
return useMutation({
mutationFn: async (provider: Provider) => {
return await providersApi.add(provider, appId)
},
onSuccess: () => {
// 重新获取数据
queryClient.invalidateQueries({ queryKey: ['providers', appId] })
toast.success('添加成功')
},
onError: (error: Error) => {
toast.error(`添加失败: ${error.message}`)
},
})
}
// 在组件中使用
function AddProviderDialog() {
const mutation = useAddProviderMutation('claude')
const handleSubmit = (data: Provider) => {
mutation.mutate(data)
}
return (
<button
onClick={() => handleSubmit(formData)}
disabled={mutation.isPending}
>
{mutation.isPending ? '添加中...' : '添加'}
</button>
)
}
```
### 乐观更新
```typescript
export const useSwitchProviderMutation = (appId: AppId) => {
const queryClient = useQueryClient()
return useMutation({
mutationFn: async (providerId: string) => {
return await providersApi.switch(providerId, appId)
},
// 乐观更新: 在请求发送前立即更新 UI
onMutate: async (providerId) => {
// 取消正在进行的查询
await queryClient.cancelQueries({ queryKey: ['providers', appId] })
// 保存当前数据(以便回滚)
const previousData = queryClient.getQueryData(['providers', appId])
// 乐观更新
queryClient.setQueryData(['providers', appId], (old: any) => ({
...old,
currentProviderId: providerId,
}))
return { previousData }
},
// 如果失败,回滚
onError: (err, providerId, context) => {
queryClient.setQueryData(['providers', appId], context?.previousData)
toast.error('切换失败')
},
// 无论成功失败,都重新获取数据
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ['providers', appId] })
},
})
}
```
### 依赖查询
```typescript
// 第二个查询依赖第一个查询的结果
const { data: providers } = useProvidersQuery(appId)
const currentProviderId = providers?.currentProviderId
const { data: currentProvider } = useQuery({
queryKey: ['provider', currentProviderId],
queryFn: () => providersApi.getById(currentProviderId!),
enabled: !!currentProviderId, // 只有当 ID 存在时才执行
})
```
---
## react-hook-form 使用
### 基础表单
```typescript
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'
// 定义验证 schema
const schema = z.object({
name: z.string().min(1, '请输入名称'),
email: z.string().email('邮箱格式不正确'),
age: z.number().min(18, '年龄必须大于18'),
})
type FormData = z.infer<typeof schema>
function MyForm() {
const form = useForm<FormData>({
resolver: zodResolver(schema),
defaultValues: {
name: '',
email: '',
age: 0,
},
})
const onSubmit = (data: FormData) => {
console.log(data)
}
return (
<form onSubmit={form.handleSubmit(onSubmit)}>
<input {...form.register('name')} />
{form.formState.errors.name && (
<span>{form.formState.errors.name.message}</span>
)}
<button type="submit"></button>
</form>
)
}
```
### 使用 shadcn/ui Form 组件
```typescript
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form'
import { Input } from '@/components/ui/input'
import { Button } from '@/components/ui/button'
function MyForm() {
const form = useForm<FormData>({
resolver: zodResolver(schema),
})
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormControl>
<Input placeholder="请输入名称" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit"></Button>
</form>
</Form>
)
}
```
### 动态表单验证
```typescript
// 根据条件动态验证
const schema = z.object({
type: z.enum(['official', 'custom']),
apiKey: z.string().optional(),
baseUrl: z.string().optional(),
}).refine(
(data) => {
// 如果是自定义供应商,必须填写 baseUrl
if (data.type === 'custom') {
return !!data.baseUrl
}
return true
},
{
message: '自定义供应商必须填写 Base URL',
path: ['baseUrl'],
}
)
```
### 手动触发验证
```typescript
function MyForm() {
const form = useForm<FormData>()
const handleBlur = async () => {
// 验证单个字段
await form.trigger('name')
// 验证多个字段
await form.trigger(['name', 'email'])
// 验证所有字段
const isValid = await form.trigger()
}
return <form>...</form>
}
```
---
## shadcn/ui 组件使用
### Dialog (对话框)
```typescript
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogDescription,
DialogFooter,
} from '@/components/ui/dialog'
import { Button } from '@/components/ui/button'
function MyDialog() {
const [open, setOpen] = useState(false)
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent>
<DialogHeader>
<DialogTitle></DialogTitle>
<DialogDescription></DialogDescription>
</DialogHeader>
{/* 内容 */}
<div></div>
<DialogFooter>
<Button variant="outline" onClick={() => setOpen(false)}>
</Button>
<Button onClick={handleConfirm}></Button>
</DialogFooter>
</DialogContent>
</Dialog>
)
}
```
### Select (选择器)
```typescript
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select'
function MySelect() {
const [value, setValue] = useState('')
return (
<Select value={value} onValueChange={setValue}>
<SelectTrigger>
<SelectValue placeholder="请选择" />
</SelectTrigger>
<SelectContent>
<SelectItem value="option1">1</SelectItem>
<SelectItem value="option2">2</SelectItem>
<SelectItem value="option3">3</SelectItem>
</SelectContent>
</Select>
)
}
```
### Tabs (标签页)
```typescript
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
function MyTabs() {
return (
<Tabs defaultValue="tab1">
<TabsList>
<TabsTrigger value="tab1">1</TabsTrigger>
<TabsTrigger value="tab2">2</TabsTrigger>
<TabsTrigger value="tab3">3</TabsTrigger>
</TabsList>
<TabsContent value="tab1">
<div>1</div>
</TabsContent>
<TabsContent value="tab2">
<div>2</div>
</TabsContent>
<TabsContent value="tab3">
<div>3</div>
</TabsContent>
</Tabs>
)
}
```
### Toast 通知 (Sonner)
```typescript
import { toast } from 'sonner'
// 成功通知
toast.success('操作成功')
// 错误通知
toast.error('操作失败')
// 加载中
const toastId = toast.loading('处理中...')
// 完成后更新
toast.success('处理完成', { id: toastId })
// 或
toast.dismiss(toastId)
// 自定义持续时间
toast.success('消息', { duration: 5000 })
// 带操作按钮
toast('确认删除?', {
action: {
label: '删除',
onClick: () => handleDelete(),
},
})
```
---
## 代码迁移示例
### 示例 1: 状态管理迁移
**旧代码** (手动状态管理):
```typescript
const [providers, setProviders] = useState<Record<string, Provider>>({})
const [currentProviderId, setCurrentProviderId] = useState('')
const [loading, setLoading] = useState(false)
const [error, setError] = useState<Error | null>(null)
useEffect(() => {
const load = async () => {
setLoading(true)
setError(null)
try {
const data = await window.api.getProviders(appType)
const currentId = await window.api.getCurrentProvider(appType)
setProviders(data)
setCurrentProviderId(currentId)
} catch (err) {
setError(err as Error)
} finally {
setLoading(false)
}
}
load()
}, [appId])
```
**新代码** (React Query):
```typescript
const { data, isLoading, error } = useProvidersQuery(appId)
const providers = data?.providers || {}
const currentProviderId = data?.currentProviderId || ''
```
**减少**: 从 20+ 行到 3 行
---
### 示例 2: 表单验证迁移
**旧代码** (手动验证):
```typescript
const [name, setName] = useState('')
const [nameError, setNameError] = useState('')
const [apiKey, setApiKey] = useState('')
const [apiKeyError, setApiKeyError] = useState('')
const validate = () => {
let valid = true
if (!name.trim()) {
setNameError('请输入名称')
valid = false
} else {
setNameError('')
}
if (!apiKey.trim()) {
setApiKeyError('请输入 API Key')
valid = false
} else if (apiKey.length < 10) {
setApiKeyError('API Key 长度不足')
valid = false
} else {
setApiKeyError('')
}
return valid
}
const handleSubmit = () => {
if (validate()) {
// 提交
}
}
return (
<form>
<input value={name} onChange={e => setName(e.target.value)} />
{nameError && <span>{nameError}</span>}
<input value={apiKey} onChange={e => setApiKey(e.target.value)} />
{apiKeyError && <span>{apiKeyError}</span>}
<button onClick={handleSubmit}></button>
</form>
)
```
**新代码** (react-hook-form + zod):
```typescript
const schema = z.object({
name: z.string().min(1, '请输入名称'),
apiKey: z.string().min(10, 'API Key 长度不足'),
})
const form = useForm({
resolver: zodResolver(schema),
})
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="apiKey"
render={({ field }) => (
<FormItem>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit"></Button>
</form>
</Form>
)
```
**减少**: 从 40+ 行到 30 行,且更健壮
---
### 示例 3: 通知系统迁移
**旧代码** (自定义通知):
```typescript
const [notification, setNotification] = useState<{
message: string
type: 'success' | 'error'
} | null>(null)
const [isVisible, setIsVisible] = useState(false)
const showNotification = (message: string, type: 'success' | 'error') => {
setNotification({ message, type })
setIsVisible(true)
setTimeout(() => {
setIsVisible(false)
setTimeout(() => setNotification(null), 300)
}, 3000)
}
return (
<>
{notification && (
<div className={`notification ${isVisible ? 'visible' : ''} ${notification.type}`}>
{notification.message}
</div>
)}
{/* 其他内容 */}
</>
)
```
**新代码** (Sonner):
```typescript
import { toast } from 'sonner'
// 在需要的地方直接调用
toast.success('操作成功')
toast.error('操作失败')
// 在 main.tsx 中只需添加一次
import { Toaster } from '@/components/ui/sonner'
<Toaster />
```
**减少**: 从 20+ 行到 1 行调用
---
### 示例 4: 对话框迁移
**旧代码** (自定义 Modal):
```typescript
const [isOpen, setIsOpen] = useState(false)
return (
<>
<button onClick={() => setIsOpen(true)}></button>
{isOpen && (
<div className="modal-backdrop" onClick={() => setIsOpen(false)}>
<div className="modal-content" onClick={e => e.stopPropagation()}>
<div className="modal-header">
<h2></h2>
<button onClick={() => setIsOpen(false)}>×</button>
</div>
<div className="modal-body">
{/* 内容 */}
</div>
<div className="modal-footer">
<button onClick={() => setIsOpen(false)}></button>
<button onClick={handleConfirm}></button>
</div>
</div>
</div>
)}
</>
)
```
**新代码** (shadcn/ui Dialog):
```typescript
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
const [isOpen, setIsOpen] = useState(false)
return (
<>
<Button onClick={() => setIsOpen(true)}></Button>
<Dialog open={isOpen} onOpenChange={setIsOpen}>
<DialogContent>
<DialogHeader>
<DialogTitle></DialogTitle>
</DialogHeader>
{/* 内容 */}
<DialogFooter>
<Button variant="outline" onClick={() => setIsOpen(false)}></Button>
<Button onClick={handleConfirm}></Button>
</DialogFooter>
</DialogContent>
</Dialog>
</>
)
```
**优势**:
- 无需自定义样式
- 内置无障碍支持
- 自动管理焦点和 ESC 键
---
### 示例 5: API 调用迁移
**旧代码** (window.api):
```typescript
// 添加供应商
const handleAdd = async (provider: Provider) => {
try {
await window.api.addProvider(provider, appType)
await loadProviders()
showNotification('添加成功', 'success')
} catch (error) {
showNotification('添加失败', 'error')
}
}
```
**新代码** (React Query Mutation):
```typescript
// 在组件中
const addMutation = useAddProviderMutation(appId)
const handleAdd = (provider: Provider) => {
addMutation.mutate(provider)
// 成功和错误处理已在 mutation 定义中处理
}
```
**优势**:
- 自动处理 loading 状态
- 统一的错误处理
- 自动刷新数据
- 更少的样板代码
---
## 常见问题
### Q: 如何在 mutation 成功后关闭对话框?
```typescript
const mutation = useAddProviderMutation(appId)
const handleSubmit = (data: Provider) => {
mutation.mutate(data, {
onSuccess: () => {
setIsOpen(false) // 关闭对话框
},
})
}
```
### Q: 如何在表单中使用异步验证?
```typescript
const schema = z.object({
name: z.string().refine(
async (name) => {
// 检查名称是否已存在
const exists = await checkNameExists(name)
return !exists
},
{ message: '名称已存在' }
),
})
```
### Q: 如何手动刷新 Query 数据?
```typescript
const queryClient = useQueryClient()
// 方式1: 使缓存失效,触发重新获取
queryClient.invalidateQueries({ queryKey: ['providers', appId] })
// 方式2: 直接刷新
queryClient.refetchQueries({ queryKey: ['providers', appId] })
// 方式3: 更新缓存数据
queryClient.setQueryData(['providers', appId], newData)
```
### Q: 如何在组件外部使用 toast?
```typescript
// 直接导入并使用即可
import { toast } from 'sonner'
export const someUtil = () => {
toast.success('工具函数中的通知')
}
```
---
## 调试技巧
### React Query DevTools
```typescript
// 在 main.tsx 中添加
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
<QueryClientProvider client={queryClient}>
<App />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
```
### 查看表单状态
```typescript
const form = useForm()
// 在开发模式下打印表单状态
console.log('Form values:', form.watch())
console.log('Form errors:', form.formState.errors)
console.log('Is valid:', form.formState.isValid)
```
---
## 性能优化建议
### 1. 避免不必要的重渲染
```typescript
// 使用 React.memo
export const ProviderCard = React.memo(({ provider, onEdit }: Props) => {
// ...
})
// 或使用 useMemo
const sortedProviders = useMemo(
() => Object.values(providers).sort(...),
[providers]
)
```
### 2. Query 配置优化
```typescript
const { data } = useQuery({
queryKey: ['providers', appId],
queryFn: fetchProviders,
staleTime: 1000 * 60 * 5, // 5分钟内不重新获取
gcTime: 1000 * 60 * 10, // 10分钟后清除缓存
})
```
### 3. 表单性能优化
```typescript
// 使用 mode 控制验证时机
const form = useForm({
mode: 'onBlur', // 失去焦点时验证
// mode: 'onChange', // 每次输入都验证(较慢)
// mode: 'onSubmit', // 提交时验证(最快)
})
```
---
**提示**: 将此文档保存在浏览器书签或编辑器中,方便随时查阅!
-73
View File
@@ -1,73 +0,0 @@
# 前端测试开发计划
## 1. 背景与目标
- **背景**:v3.5.0 起前端功能快速扩张(供应商管理、MCP、导入导出、端点测速、国际化),缺失系统化测试导致回归风险与人工验证成本攀升。
- **目标**:在 3 个迭代内建立覆盖关键业务的自动化测试体系,形成稳定的手动冒烟流程,并将测试执行纳入 CI/CD。
## 2. 范围与优先级
| 范围 | 内容 | 优先级 |
| --- | --- | --- |
| 供应商管理 | 列表、排序、预设/自定义表单、切换、复制、删除 | P0 |
| 配置导入导出 | JSON 校验、备份、进度反馈、失败回滚 | P0 |
| MCP 管理 | 列表、启停、模板、命令校验 | P1 |
| 设置面板 | 主题/语言切换、目录设置、关于、更新检查 | P1 |
| 端点速度测试 & 使用脚本 | 启动测试、状态指示、脚本保存 | P2 |
| 国际化 | 中英切换、缺省文案回退 | P2 |
## 3. 测试分层策略
- **单元测试(Vitest**:纯函数与 Hook`useProviderActions``useSettingsForm``useDragSort``useImportExport` 等)验证数据处理、错误分支、排序逻辑。
- **组件测试(React Testing Library**:关键组件(`ProviderList``AddProviderDialog``SettingsDialog``McpPanel`)模拟交互、校验、提示;结合 MSW 模拟 API。
- **集成测试(App 级别)**:挂载 `App.tsx`,覆盖应用切换、编辑模式、导入导出回调、语言切换,验证状态同步与 toast 提示。
- **端到端测试(Playwright**:依赖 `pnpm dev:renderer`,串联供应商 CRUD、排序拖拽、MCP 启停、语言切换即时刷新、更新检查跳转。
- **手动冒烟**Tauri 桌面包 + dev server 双通道,验证托盘、系统权限、真实文件写入。
## 4. 环境与工具
- 依赖:Node 18+、pnpm 8+、Vitest、React Testing Library、MSW、Playwright、Testing Library User Event、Playwright Trace Viewer。
- 配置要点:
-`tsconfig` 中共享别名,Vitest 配合 `vite.config.mts`
- `setupTests.ts` 统一注册 MSW/RTL、自定义 matcher。
- Playwright 使用多浏览器矩阵(Chromium 必选,WebKit 可选),并共享 `.env.test`
- Mock `@tauri-apps/api``providersApi`/`settingsApi`,隔离 Rust 层。
## 5. 自动化建设里程碑
| 周期 | 目标 | 交付 |
| --- | --- | --- |
| Sprint 1 | Vitest 基础设施、核心 Hook 单测(P0) | `pnpm test:unit`、覆盖率报告、10+ 用例 |
| Sprint 2 | 组件/集成测试、MSW Mock 层 | `pnpm test:component`、App 主流程用例 |
| Sprint 3 | Playwright E2E、CI 接入 | `pnpm test:e2e`、CI job、冒烟脚本 |
| 持续 | 回归用例补齐、视觉比对探索 | Playwright Trace、截图基线 |
## 6. 用例规划概览
- **供应商管理**:新增(预设+自定义)、编辑校验、复制排序、切换失败回退、删除确认、使用脚本保存。
- **导入导出**:成功、重复导入、校验失败、备份失败提示、导入后托盘刷新。
- **MCP**:模板应用、协议切换(stdio/http)、命令校验、启停状态持久化。
- **设置**:主题/语言即时生效、目录路径更新、更新检查按钮外链、关于信息渲染。
- **端点速度测试**:触发测试、loading/成功/失败状态、指示器颜色、测速数据排序。
- **国际化**:默认中文、切换英文后主界面/对话框文案变化、缺失 key fallback。
## 7. 数据与 Mock 策略
-`tests/fixtures/` 维护标准供应商、MCP、设置数据集。
- 使用 MSW 拦截 `providersApi``settingsApi``providersApi.onSwitched` 等调用;提供延迟/错误注入接口以覆盖异常分支。
- Playwright 端提供临时用户目录(`TMP_CC_SWITCH_HOME`)+ 伪配置文件,以验证真实文件交互路径。
## 8. 质量门禁与指标
- 覆盖率目标:单元 ≥75%,分支 ≥70%,逐步提升至 80%+。
- CI 阶段:`pnpm typecheck``pnpm format:check``pnpm test:unit``pnpm test:component``pnpm test:e2e`(可在 nightly 执行)。
- 缺陷处理:修复前补充最小复现测试;E2E 冒烟必须陪跑重大功能发布。
## 9. 工作流与职责
- **测试负责人**:前端工程师轮值;负责测试计划维护、PR 流水线健康。
- **开发者职责**:提交功能需附新增/更新测试、列出手动验证步骤、如涉及 UI 提交截图。
- **Code Review 检查**:测试覆盖说明、mock 合理性、易读性。
## 10. 风险与缓解
| 风险 | 影响 | 缓解 |
| --- | --- | --- |
| Tauri API Mock 难度高 | 单测无法稳定 | 抽象 API 适配层 + MSW 统一模拟 |
| Playwright 运行时间长 | CI 变慢 | 拆分冒烟/完整版,冒烟只跑关键路径 |
| 国际化文案频繁变化 | 用例脆弱 | 优先断言 data-testid/结构,文案使用翻译 key |
## 11. 输出与维护
- 文档维护者:前端团队;每个版本更新后检查测试覆盖清单。
- 交付物:测试报告(CI artifact)、Playwright Trace、覆盖率摘要。
- 复盘:每次发布后召开 30 分钟测试复盘,记录缺陷、补齐用例。
-485
View File
@@ -1,485 +0,0 @@
# OpenCode 第四应用支持实现计划
> **范围说明**:本计划暂不包含统一供应商(UniversalProvider)对 OpenCode 的支持,以降低初期实现复杂度。
## 概述
为 CC Switch 添加 OpenCode 支持,这是第四个受管理的 CLI 应用。OpenCode 的核心差异在于采用**累加式**供应商管理(多供应商共存,应用内热切换),而非现有三应用的**替换式**管理。
## 关键设计决策
| 特性 | Claude/Codex/Gemini | OpenCode |
|------|---------------------|----------|
| 供应商模式 | 替换式(单一活跃) | 累加式(多供应商共存) |
| UI 按钮 | 启用/切换 | 添加/删除 |
| is_current | 需要 | 不需要 |
| 代理/故障转移 | 支持 | 不支持 |
| API 格式字段 | 无 | 需要(npm 包名) |
| 配置文件 | 各自独立 | `~/.config/opencode/opencode.json` |
## 配置文件格式
### 供应商配置
```json
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"provider-id": {
"npm": "@ai-sdk/openai-compatible",
"name": "Provider Name",
"options": {
"baseURL": "https://api.example.com/v1",
"apiKey": "{env:API_KEY}"
},
"models": {
"model-id": { "name": "Model Name" }
}
}
}
}
```
### MCP 配置
```json
{
"mcp": {
"remote-server": {
"type": "remote",
"url": "https://example.com/mcp",
"enabled": true
},
"local-server": {
"type": "local",
"command": ["npx", "-y", "my-mcp-command"],
"enabled": true,
"environment": { "KEY": "value" }
}
}
}
```
---
## 实现步骤
### Phase 1: 后端数据结构扩展
#### 1.1 AppType 枚举扩展
**文件**: `src-tauri/src/app_config.rs`
```rust
pub enum AppType {
Claude,
Codex,
Gemini,
OpenCode, // 新增
}
```
#### 1.2 McpApps / SkillApps 扩展
**文件**: `src-tauri/src/app_config.rs`
```rust
pub struct McpApps {
pub claude: bool,
pub codex: bool,
pub gemini: bool,
pub opencode: bool, // 新增
}
pub struct SkillApps {
pub claude: bool,
pub codex: bool,
pub gemini: bool,
pub opencode: bool, // 新增
}
```
#### 1.3 数据库 Schema 迁移
**文件**: `src-tauri/src/database/schema.rs`
- `SCHEMA_VERSION` 递增
- 添加迁移:
```sql
ALTER TABLE mcp_servers ADD COLUMN enabled_opencode BOOLEAN NOT NULL DEFAULT 0;
ALTER TABLE skills ADD COLUMN enabled_opencode BOOLEAN NOT NULL DEFAULT 0;
```
### Phase 2: OpenCode 供应商数据结构
#### 2.1 OpenCode 专属配置结构
**文件**: `src-tauri/src/provider.rs`(或新建 `opencode_provider.rs`
```rust
/// OpenCode 供应商的 settings_config 结构
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OpenCodeProviderConfig {
/// AI SDK 包名,如 "@ai-sdk/openai-compatible"
pub npm: String,
/// 供应商选项
pub options: OpenCodeProviderOptions,
/// 模型定义
pub models: HashMap<String, OpenCodeModel>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OpenCodeProviderOptions {
#[serde(rename = "baseURL", skip_serializing_if = "Option::is_none")]
pub base_url: Option<String>,
#[serde(rename = "apiKey", skip_serializing_if = "Option::is_none")]
pub api_key: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub headers: Option<HashMap<String, String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OpenCodeModel {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<OpenCodeModelLimit>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OpenCodeModelLimit {
pub context: Option<u64>,
pub output: Option<u64>,
}
```
### Phase 3: OpenCode Live 配置读写
#### 3.1 新建 OpenCode 配置模块
**文件**: `src-tauri/src/opencode_config.rs`
核心功能:
- `get_opencode_config_path()` → `~/.config/opencode/opencode.json`
- `read_opencode_config()` → 读取整个配置文件
- `write_opencode_config()` → 原子写入配置文件
- `get_providers()` → 获取 `provider` 对象
- `set_provider(id, config)` → 添加/更新供应商
- `remove_provider(id)` → 删除供应商
- `get_mcp_servers()` → 获取 `mcp` 对象
- `set_mcp_server(id, config)` → 添加/更新 MCP 服务器
- `remove_mcp_server(id)` → 删除 MCP 服务器
### Phase 4: MCP 同步模块
#### 4.1 新建 OpenCode MCP 同步
**文件**: `src-tauri/src/mcp/opencode.rs`
```rust
/// 同步所有 enabled_opencode=true 的服务器到 OpenCode 配置
pub fn sync_enabled_to_opencode(config: &MultiAppConfig) -> Result<(), AppError>
/// 同步单个服务器
pub fn sync_single_server_to_opencode(
config: &MultiAppConfig,
id: &str,
server_spec: &Value
) -> Result<(), AppError>
/// 从 OpenCode 配置移除服务器
pub fn remove_server_from_opencode(id: &str) -> Result<(), AppError>
/// 从 OpenCode 配置导入服务器
pub fn import_from_opencode(config: &mut MultiAppConfig) -> Result<usize, AppError>
```
**格式转换**
| CC Switch 统一格式 | OpenCode 格式 |
|-------------------|---------------|
| `type: "stdio"` | `type: "local"` |
| `command` + `args` | `command: [cmd, ...args]` |
| `env` | `environment` |
| `type: "sse"/"http"` | `type: "remote"` |
| `url` | `url` |
### Phase 5: 供应商服务层
#### 5.1 OpenCode 供应商服务
**文件**: `src-tauri/src/services/provider/opencode.rs`
核心方法:
```rust
/// 获取所有 OpenCode 供应商
pub fn list(state: &AppState) -> Result<IndexMap<String, Provider>, AppError>
/// 添加供应商(同时写入 live 配置)
pub fn add(state: &AppState, provider: Provider) -> Result<bool, AppError>
/// 更新供应商
pub fn update(state: &AppState, provider: Provider) -> Result<bool, AppError>
/// 删除供应商(同时从 live 配置移除)
pub fn delete(state: &AppState, id: &str) -> Result<(), AppError>
/// 从 live 配置导入供应商到数据库
pub fn import_from_live(state: &AppState) -> Result<usize, AppError>
```
**关键差异**
- 不需要 `switch()` 方法
- 不需要 `is_current` 管理
- `add()` 自动写入 live
- `delete()` 自动从 live 移除
### Phase 6: Tauri 命令扩展
#### 6.1 更新现有命令
**文件**: `src-tauri/src/commands/providers.rs`
- 所有命令支持 `app_type = "opencode"`
- OpenCode 特定逻辑分支
#### 6.2 新增 OpenCode 专属命令(如需要)
```rust
#[tauri::command]
pub async fn opencode_sync_all_providers(state: State<'_, AppState>) -> Result<(), AppError>
```
### Phase 7: 前端类型定义
#### 7.1 TypeScript 类型扩展
**文件**: `src/types.ts`
```typescript
// AppId 扩展
type AppId = "claude" | "codex" | "gemini" | "opencode";
// OpenCode 专属配置
interface OpenCodeProviderConfig {
npm: string; // AI SDK 包名
options: {
baseURL?: string;
apiKey?: string;
headers?: Record<string, string>;
};
models: Record<string, OpenCodeModel>;
}
interface OpenCodeModel {
name: string;
limit?: {
context?: number;
output?: number;
};
}
```
#### 7.2 MCP 应用状态扩展
**文件**: `src/types.ts`
```typescript
interface McpApps {
claude: boolean;
codex: boolean;
gemini: boolean;
opencode: boolean; // 新增
}
```
### Phase 8: 前端预设配置
#### 8.1 新建 OpenCode 供应商预设
**文件**: `src/config/opencodeProviderPresets.ts`
```typescript
export const opencodeProviderPresets: ProviderPreset[] = [
{
name: "OpenAI",
npmPackage: "@ai-sdk/openai",
settingsConfig: {
npm: "@ai-sdk/openai",
options: { apiKey: "{env:OPENAI_API_KEY}" },
models: {
"gpt-4o": { name: "GPT-4o" },
"gpt-4o-mini": { name: "GPT-4o Mini" },
},
},
theme: { icon: "openai", iconColor: "#00A67E" },
},
{
name: "Anthropic",
npmPackage: "@ai-sdk/anthropic",
settingsConfig: {
npm: "@ai-sdk/anthropic",
options: { apiKey: "{env:ANTHROPIC_API_KEY}" },
models: {
"claude-sonnet-4-20250514": { name: "Claude Sonnet 4" },
},
},
},
{
name: "OpenAI Compatible",
npmPackage: "@ai-sdk/openai-compatible",
settingsConfig: {
npm: "@ai-sdk/openai-compatible",
options: {
baseURL: "",
apiKey: "{env:API_KEY}",
},
models: {},
},
isCustomTemplate: true,
},
// ... 更多预设
];
// npm 包选项
export const opencodeNpmPackages = [
{ value: "@ai-sdk/openai", label: "OpenAI" },
{ value: "@ai-sdk/anthropic", label: "Anthropic" },
{ value: "@ai-sdk/openai-compatible", label: "OpenAI Compatible" },
{ value: "@ai-sdk/google", label: "Google" },
{ value: "@ai-sdk/azure", label: "Azure OpenAI" },
{ value: "@ai-sdk/amazon-bedrock", label: "Amazon Bedrock" },
// ... 更多选项
];
```
### Phase 9: 前端 UI 组件
#### 9.1 OpenCode 供应商表单
**文件**: `src/components/providers/forms/OpenCodeFormFields.tsx`
新增字段:
- npm 包选择器(下拉框 + 自定义输入)
- options 编辑器(baseURL, apiKey, headers
- models 编辑器(动态添加/删除模型)
#### 9.2 供应商卡片按钮适配
**文件**: `src/components/providers/ProviderActions.tsx`
```tsx
// OpenCode 使用不同的主按钮
if (appId === "opencode") {
return (
<Button onClick={onAdd}>
{isInConfig ? t("provider.removeFromConfig") : t("provider.addToConfig")}
</Button>
);
}
```
#### 9.3 隐藏 OpenCode 不需要的功能
在以下组件中检查 `appId !== "opencode"`
- 代理设置面板
- 故障转移队列
- 供应商切换逻辑
### Phase 10: 国际化
#### 10.1 新增翻译 Key
**文件**: `src/locales/zh/translation.json` & `en/translation.json`
```json
{
"app.opencode": "OpenCode",
"provider.addToConfig": "添加到配置",
"provider.removeFromConfig": "从配置移除",
"provider.inConfig": "已添加",
"provider.npmPackage": "AI SDK 包",
"provider.models": "模型配置",
// ...
}
```
---
## 关键文件清单
### 后端(Rust
| 操作 | 文件路径 |
|------|---------|
| 修改 | `src-tauri/src/app_config.rs` |
| 修改 | `src-tauri/src/database/schema.rs` |
| 修改 | `src-tauri/src/database/dao/mcp.rs` |
| 修改 | `src-tauri/src/database/dao/providers.rs` |
| 修改 | `src-tauri/src/services/provider/mod.rs` |
| 修改 | `src-tauri/src/services/mcp.rs` |
| 修改 | `src-tauri/src/commands/providers.rs` |
| 修改 | `src-tauri/src/commands/mcp.rs` |
| 修改 | `src-tauri/src/mcp/mod.rs` |
| 新建 | `src-tauri/src/opencode_config.rs` |
| 新建 | `src-tauri/src/mcp/opencode.rs` |
| 新建 | `src-tauri/src/services/provider/opencode.rs` |
### 前端(TypeScript/React
| 操作 | 文件路径 |
|------|---------|
| 修改 | `src/types.ts` |
| 修改 | `src/lib/api/types.ts` |
| 修改 | `src/lib/api/providers.ts` |
| 修改 | `src/components/providers/ProviderActions.tsx` |
| 修改 | `src/components/providers/ProviderCard.tsx` |
| 修改 | `src/components/providers/AddProviderDialog.tsx` |
| 修改 | `src/components/providers/forms/ProviderForm.tsx` |
| 修改 | `src/App.tsx` |
| 新建 | `src/config/opencodeProviderPresets.ts` |
| 新建 | `src/components/providers/forms/OpenCodeFormFields.tsx` |
### 国际化
| 操作 | 文件路径 |
|------|---------|
| 修改 | `src/locales/zh/translation.json` |
| 修改 | `src/locales/en/translation.json` |
| 修改 | `src/locales/ja/translation.json` |
---
## 验证计划
### 单元测试
1. OpenCode 配置读写测试
2. MCP 格式转换测试(stdio ↔ local, sse ↔ remote
3. 供应商 CRUD 操作测试
### 集成测试
1. 添加 OpenCode 供应商 → 验证写入 `~/.config/opencode/opencode.json`
2. 删除供应商 → 验证从配置文件移除
3. MCP 同步测试 → 验证格式正确转换
4. 从 live 配置导入 → 验证正确解析
### 手动测试
1. UI 流程:添加预设 → 编辑 → 删除
2. 切换应用 Tab → OpenCode 显示正确的 UI(无代理/故障转移)
3. 托盘菜单正确显示 OpenCode 供应商
4. 深链接导入 OpenCode 供应商
---
## 风险评估
1. **数据库迁移**:需要在升级时自动执行 `ALTER TABLE` 语句
2. **配置文件冲突**:OpenCode 可能有自己的配置,需要合并而非覆盖
3. **MCP 格式差异**`stdio` → `local` 转换需要处理边界情况
4. **UI 一致性**OpenCode 的"添加/删除"模式需要与其他应用的"启用/切换"清晰区分
---
## 补充说明
### 托盘菜单特殊处理
由于 OpenCode 采用累加式管理,托盘菜单行为需要调整:
- **现有三应用**:托盘菜单显示 `CheckMenuItem`(单选,切换当前供应商)
- **OpenCode**:显示当前所有启用的供应商(普通 MenuItem,无勾选逻辑),点击打开主界面
**修改文件**`src-tauri/src/tray.rs``TRAY_SECTIONS` 常量)
### 数据库约束更新
`proxy_config` 表的 CHECK 约束需要扩展:
```sql
CHECK (app_type IN ('claude','codex','gemini','opencode'))
```
### Settings 结构体扩展
**文件**`src-tauri/src/settings.rs`
需要添加:
- `current_provider_opencode: Option<String>` - 对 OpenCode 可能无意义,但保持结构一致
- `opencode_config_dir: Option<String>` - 自定义配置目录
@@ -2,7 +2,7 @@
> OpenCode Support, Global Proxy, Claude Rectifier & Multi-App Experience Enhancements
**[中文版 →](release-note-v3.10.0-zh.md) | [日本語版 →](release-note-v3.10.0-ja.md)**
**[中文版 →](v3.10.0-zh.md) | [日本語版 →](v3.10.0-ja.md)**
---
@@ -2,7 +2,7 @@
> OpenCode サポート、グローバルプロキシ、Claude Rectifier とマルチアプリ体験の強化
**[中文版 →](release-note-v3.10.0-zh.md) | [English →](release-note-v3.10.0-en.md)**
**[中文版 →](v3.10.0-zh.md) | [English →](v3.10.0-en.md)**
---
@@ -2,7 +2,7 @@
> OpenCode 支持、全局代理、Claude Rectifier 与多应用体验增强
**[English →](release-note-v3.10.0-en.md) | [日本語版 →](release-note-v3.10.0-ja.md)**
**[English →](v3.10.0-en.md) | [日本語版 →](v3.10.0-ja.md)**
---
+302
View File
@@ -0,0 +1,302 @@
# CC Switch v3.11.0
> OpenClaw Support, Session Manager, Backup Management & 50+ Improvements
**[中文版 →](v3.11.0-zh.md) | [日本語版 →](v3.11.0-ja.md)**
---
## Overview
CC Switch v3.11.0 is a major update that adds full management support for **OpenClaw** as the fifth application, introduces a new **Session Manager** and **Backup Management** feature. Additionally, **Oh My OpenCode (OMO) integration**, the **partial key-field merging** architecture upgrade for provider switching, **settings page refactoring**, and many other improvements make the overall experience more polished.
**Release Date**: 2026-02-26
**Update Scale**: 147 commits | 274 files changed | +32,179 / -5,467 lines
---
## Highlights
- **OpenClaw Support**: Fifth managed application with 13 provider presets, Env/Tools/AgentsDefaults config editors, and Workspace file management
- **Session Manager**: Browse conversation history across all five apps with table-of-contents navigation and in-session search
- **Backup Management**: Independent backup panel with configurable policies, periodic backups, and pre-migration auto-backup
- **Oh My OpenCode Integration**: Full OMO config management with OMO Slim lightweight mode support
- **Partial Key-Field Merging (⚠️ Breaking Change)**: Provider switching now only replaces provider-related fields, preserving all other settings; the "Common Config Snippet" feature has been removed
- **Settings Page Refactoring**: 5-tab layout with ~40% code reduction
- **6 New Provider Presets**: AWS Bedrock, SSAI Code, CrazyRouter, AICoding, and more
- **Thinking Budget Rectifier**: Fine-grained thinking budget control
- **Theme Switch Animation**: Circular reveal transition animation
- **WebDAV Auto Sync**: Automatic sync with large file protection
---
## Main Features
### OpenClaw Support (New Fifth App)
Full management support for OpenClaw, the fifth managed application following Claude Code, Codex, Gemini CLI, and OpenCode.
- **Provider Management**: Add, edit, switch, and delete OpenClaw providers with 13 built-in presets
- **Config Editors**: Three dedicated panels for Env (environment variables), Tools, and AgentsDefaults
- **Workspace Panel**: HEARTBEAT/BOOTSTRAP/BOOT file management and daily memory
- **Additive Overlay Mode**: Support config overlay instead of overwrite
- **Default Model Button**: One-click to fill recommended models; auto-register suggested models to allowlist when adding providers
- **Brand & Interaction**: Dedicated brand icon, fade-in/fade-out transition animation when switching apps
- **Deep Link Support**: Import OpenClaw provider configurations via URL
- **Full Internationalization**: Complete Chinese/English/Japanese support
### Session Manager
A brand-new session manager to browse and search conversation history.
- Browse conversation history across Claude Code, Codex, Gemini CLI, OpenCode, and OpenClaw (#867, thanks @TinsFox)
- Table-of-contents navigation and in-session search
- Auto-filter by current app when entering the session page
- Parallel directory scanning + head-tail JSONL reading for optimized loading performance
### Backup Management
An independent backup management panel for better data safety.
- Configurable backup policy: maximum backup count and auto-cleanup rules
- Hourly automatic backup timer during runtime
- Auto-backup before database schema migrations with backfill warning
- Support backup rename and deletion (with confirmation dialog)
- Backup filenames use local time for better clarity
### Oh My OpenCode (OMO) Integration
Full Oh My OpenCode config file management.
- Agent model selection, category configuration, and recommended model fill (#972, thanks @yovinchen)
- Improved agent model selection UX with lowercase key fix (#1004, thanks @yovinchen)
- OMO Slim lightweight mode support
- OMO ↔ OMO Slim mutual exclusion (enforced at database level)
### Workspace
- Full-text search across daily memory files, sorted by date
- Clickable directory paths for quick file location access
### Toolbar
- AppSwitcher auto-collapses to compact mode based on available width
- Smooth transition animation for compact mode toggle
### Settings
- First-use confirmation dialogs for proxy and usage features to prevent accidental operations
- New `enableLocalProxy` switch to control proxy UI visibility on home page
- More granular local environment checks: CLI tool version detection (#870, thanks @kv-chiu), Volta path detection (#969, thanks @myjustify)
### Provider Presets
- **AWS Bedrock**: Support for AKSK and API Key authentication modes (#1047, thanks @keithyt06)
- **SSAI Code**: Partner preset across all five apps
- **CrazyRouter**: Partner preset with dedicated icon
- **AICoding**: Partner preset with i18n promotion text
- Updated domestic model provider presets to latest versions
- Renamed Qwen Coder to Bailian (#965, thanks @zhu-jl18)
### Other New Features
- **Thinking Budget Rectifier**: Fine-grained thinking budget allocation control (#1005, thanks @yovinchen)
- **WebDAV Auto Sync**: Automatic sync with large file protection (#923, thanks @clx20000410; #1043, thanks @SaladDay)
- **Theme Switch Animation**: Circular reveal transition for a smoother visual experience (#905, thanks @funnytime75)
- **Claude Config Editor Quick Toggles**: Quick toggle switches for common settings (#1012, thanks @JIA-ss)
- **Dynamic Endpoint Hint**: Context-aware hint text based on API format selection (#860, thanks @zhu-jl18)
- **Usage Dashboard Enhancement**: Auto-refresh control and robust formatting (#942, thanks @yovinchen)
- **New Pricing Data**: claude-opus-4-6 and gpt-5.3-codex (#943, thanks @yovinchen)
- **Silent Startup Optimization**: Silent startup option only shown when launch-on-startup is enabled
---
## Architecture Improvements
### Partial Key-Field Merging (⚠️ Breaking Change)
Provider switching now uses partial key-field merging instead of full config overwrite (#1098).
**Before**: Switching providers overwrote the entire `settings_config` to the live config file. This meant that any non-provider settings the user manually added to the live file (plugins, MCP config, permissions, etc.) would be lost on every switch. To work around this, previous versions offered a "Common Config Snippet" feature that let users define shared config to be merged on every switch.
**After**: Switching providers now only replaces provider-related key-values (API keys, endpoints, models, etc.), leaving all other settings intact. The "Common Config Snippet" feature is therefore no longer needed and has been removed.
**Impact & Migration**:
- If you **didn't use** Common Config Snippets, this change is fully transparent — switching just works better now
- If you **used** Common Config Snippets to preserve custom settings (MCP config, permissions, etc.), those settings are now automatically preserved during switches — no action needed
- If you used Common Config Snippets for other purposes (e.g., injecting extra config on every switch), please manually add those settings to your live config file after upgrading
This refactoring removed 6 frontend files (3 components + 3 hooks) and ~150 lines of backend dead code.
### Manual Import Replaces Auto-Import
Startup no longer auto-imports external configurations. Users now click "Import Current Config" manually, preventing accidental data overwrites.
### OmoVariant Parameterization
Eliminated ~250 lines of duplicated code in the OMO module via `OmoVariant` struct parameterization.
### OMO Common Config Removal
Removed the two-layer merge system, reducing ~1,733 lines of code and simplifying the architecture.
### ProviderForm Decomposition
Reduced ProviderForm component from 2,227 lines to 1,526 lines by extracting 5 independent modules (opencodeFormUtils, useOmoModelSource, useOpencodeFormState, useOmoDraftState, useOpenclawFormState), significantly improving maintainability.
### Shared MCP/Skills Components
Extracted AppCountBar, AppToggleGroup, and ListItemRow shared components to reduce duplication across MCP and Skills panels (#897, thanks @PeanutSplash).
### Settings Page Refactoring
Refactored settings page to a 5-tab layout (General | Proxy | Advanced | Usage | About), reducing SettingsPage code from ~716 to ~426 lines.
### Other Improvements
- Unified terminal selection via global settings with WezTerm support added
- Updated Claude model references from 4.5 to 4.6
---
## Bug Fixes
### Critical Fixes
- **Windows Home Dir Regression**: Restored default home directory resolution to prevent providers/settings "disappearing" when `HOME` env var differs from the real user profile directory in Git/MSYS environments
- **Linux White Screen**: Disabled WebKitGTK hardware acceleration on AMD GPUs (Cezanne/Radeon Vega) to prevent blank screen on startup (#986, thanks @ThendCN)
- **OpenAI Beta Parameter**: Stopped appending `?beta=true` to `/v1/chat/completions` endpoints, fixing request failures for Nvidia and other `apiFormat="openai_chat"` providers (#1052, thanks @jnorthrup)
- **Health Check Auth**: Health check now respects provider's `auth_mode` setting, preventing failures for proxy services that only support Bearer authentication (#824, thanks @Jassy930)
### Provider Preset Fixes
- Fixed OpenClaw `/v1` prefix causing double path (/v1/v1/messages)
- Corrected Opus pricing ($15/$75 → $5/$25) and upgraded to 4.6
- Unified AIGoCode URL to `https://api.aigocode.com` across all apps
- Removed outdated partner status from Zhipu GLM presets
- Restored API Key input visibility when creating new Claude providers
- Hide quick toggles for non-active providers, show context-aware JSON editor hints
### OMO Fixes
- Added missing omo-slim category checks across add/form/mutation paths
- Fixed OMO Slim query cache invalidation after provider mutations
- Synced OMO agent/category recommended models with upstream sources
- Added toast feedback for "Fill Recommended" button silent failures
- Removed last-provider deletion restriction for OMO/OMO Slim
- Reject saving OpenCode providers without configured models (#932, thanks @yovinchen)
### OpenClaw Fixes
- Fixed 25 missing i18n keys, replaced key={index} with stable IDs, added deep link additive merge, and other code review issues
- Enhanced EnvPanel robustness (NaN guards, entry key names instead of array indices)
- Merged duplicate i18n keys to restore provider form translations
### Platform Fixes
- Windows silent startup window flicker (#901, thanks @funnytime75)
- Title bar dark mode theme following (#903, thanks @funnytime75)
- Windows Skills path separator matching (#868, thanks @stmoonar)
- WSL helper functions conditional compilation
### UI Fixes
- Toolbar height clipping causing AppSwitcher to be obscured
- Show update badge instead of green checkmark when newer version available
- Session Manager button only visible for Claude/Codex apps
- Unified SQL import/export card dark mode styling (#1067, thanks @SaladDay)
### Other Fixes
- Replaced hardcoded Chinese strings in Session Manager with i18n keys
- Fixed Skill documentation URL branch and path resolution (#977, thanks @yovinchen)
- Added missing OpenCode install.sh installation path detection (#988, thanks @zhu-jl18)
- Fixed Skill ZIP symlink resolution (#1040, thanks @yovinchen)
- Added missing OpenCode checkbox in MCP add/edit form (#1026, thanks @yovinchen)
- Removed auto-import side effect from useProvidersQuery queryFn
---
## Performance
- Parallel directory scanning + head-tail JSONL reading for session panel, significantly improving session list loading speed
- Removed unnecessary TanStack Query cache overhead for Tauri local IPC calls
---
## Documentation
- Sponsor updates: SSSAiCode, Crazyrouter, AICoding, Right Code, MiniMax
- Added user manual documentation (#979, thanks @yovinchen)
---
## Notes & Considerations
- **OpenClaw is a newly supported app**: OpenClaw CLI must be installed first to use related features.
- **⚠️ Common Config Snippet feature has been removed**: Since provider switching now uses partial key-field merging (only replacing API keys, endpoints, models, etc.), user's other settings are automatically preserved, making Common Config Snippets unnecessary. See the "Architecture Improvements" section above for migration details.
- **Auto-import changed to manual**: External configurations are no longer auto-imported on startup. Click "Import Current Config" manually when needed.
- **OMO and OMO Slim are mutually exclusive**: Only one can be active at a time. Switching to one automatically disables the other.
- **Backup is enabled by default**: Automatic hourly backup during runtime. Adjust the policy in the Backup panel.
---
## Special Thanks
Thanks to all contributors for their contributions to this release!
@TinsFox @keithyt06 @kv-chiu @SaladDay @jnorthrup @JIA-ss @clx20000410 @ThendCN @yovinchen @zhu-jl18 @myjustify @funnytime75 @PeanutSplash @Jassy930 @stmoonar
---
## Download & Installation
Visit [Releases](https://github.com/farion1231/cc-switch/releases/latest) to download the appropriate version.
### System Requirements
| System | Minimum Version | Architecture |
| ------- | ------------------------------- | ----------------------------------- |
| Windows | Windows 10 or later | x64 |
| macOS | macOS 10.15 (Catalina) or later | Intel (x64) / Apple Silicon (arm64) |
| Linux | See table below | x64 |
### Windows
| File | Description |
| ---------------------------------------- | ---------------------------------------------------- |
| `CC-Switch-v3.11.0-Windows.msi` | **Recommended** - MSI installer with auto-update |
| `CC-Switch-v3.11.0-Windows-Portable.zip` | Portable version, extract and run, no registry write |
### macOS
| File | Description |
| -------------------------------- | -------------------------------------------------------------------- |
| `CC-Switch-v3.11.0-macOS.zip` | **Recommended** - Extract and drag to Applications, Universal Binary |
| `CC-Switch-v3.11.0-macOS.tar.gz` | For Homebrew installation and auto-update |
> **Note**: Since the author doesn't have an Apple Developer account, you may see an "unidentified developer" warning on first launch. Please close it, then go to "System Settings" → "Privacy & Security" → click "Open Anyway", and it will open normally afterwards.
### Homebrew (macOS)
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
Update:
```bash
brew upgrade --cask cc-switch
```
### Linux
| Distribution | Recommended Format | Installation Method |
| --------------------------------------- | ------------------ | ---------------------------------------------------------------------- |
| 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 directly, or use AUR |
| Other distributions / Unsure | `.AppImage` | `chmod +x CC-Switch-*.AppImage && ./CC-Switch-*.AppImage` |
+302
View File
@@ -0,0 +1,302 @@
# CC Switch v3.11.0
> OpenClaw サポート、セッションマネージャー、バックアップ管理と 50 以上の改善
**[中文版 →](v3.11.0-zh.md) | [English →](v3.11.0-en.md)**
---
## 概要
CC Switch v3.11.0 は大規模なアップデートです。5番目のアプリケーション **OpenClaw** の完全管理サポートを追加し、新しい**セッションマネージャー**と**バックアップ管理**機能を導入しました。さらに、**Oh My OpenCode (OMO) 統合**、プロバイダー切り替えの**部分キーフィールドマージ**アーキテクチャアップグレード、**設定ページのリファクタリング**など、多数の改善により全体的な体験がさらに向上しました。
**リリース日**: 2026-02-26
**更新規模**: 147 commits | 274 files changed | +32,179 / -5,467 lines
---
## ハイライト
- **OpenClaw サポート**: 5番目の管理対象アプリ、13 のプロバイダープリセット、Env/Tools/AgentsDefaults 設定エディター、Workspace ファイル管理
- **セッションマネージャー**: 5つのアプリの会話履歴を閲覧、目次ナビゲーションとセッション内検索
- **バックアップ管理**: 独立バックアップパネル、設定可能なポリシー、定期バックアップ、マイグレーション前自動バックアップ
- **Oh My OpenCode 統合**: 完全な OMO 設定管理、OMO Slim 軽量モードサポート
- **部分キーフィールドマージ(⚠️ 破壊的変更)**: プロバイダー切り替え時にプロバイダー関連フィールドのみ置換し、その他の設定を保持;「共通設定スニペット」機能は削除されました
- **設定ページリファクタリング**: 5タブレイアウト、コード量約 40% 削減
- **6つの新プロバイダープリセット**: AWS Bedrock、SSAI Code、CrazyRouter、AICoding など
- **Thinking Budget Rectifier**: より精密な thinking budget 制御
- **テーマ切り替えアニメーション**: 円形リビール遷移アニメーション
- **WebDAV 自動同期**: 自動同期と大容量ファイル保護
---
## 主な機能
### OpenClaw サポート(新しい5番目のアプリ)
Claude Code、Codex、Gemini CLI、OpenCode に続く5番目の管理対象アプリケーションとして OpenClaw の完全管理サポートを追加しました。
- **プロバイダー管理**: OpenClaw プロバイダーの追加、編集、切り替え、削除、13 の内蔵プリセット
- **設定エディター**: Env(環境変数)、Tools(ツール)、AgentsDefaults(エージェントデフォルト)の3つの専用パネル
- **Workspace パネル**: HEARTBEAT/BOOTSTRAP/BOOT ファイル管理とデイリーメモリ
- **Additive オーバーレイモード**: 上書きではなく設定の重ね合わせをサポート
- **デフォルトモデルボタン**: ワンクリックで推奨モデルを入力、プロバイダー追加時に候補モデルを allowlist に自動登録
- **ブランドとインタラクション**: 専用ブランドアイコン、アプリ切り替えフェード遷移アニメーション
- **ディープリンクサポート**: URL 経由で OpenClaw プロバイダー設定をインポート
- **完全な国際化**: 中/英/日 三言語完全対応
### セッションマネージャー
会話履歴を閲覧・検索できる新しいセッションマネージャーです。
- Claude Code、Codex、Gemini CLI、OpenCode、OpenClaw の5つのアプリの会話履歴を閲覧(#867@TinsFox に感謝)
- 目次ナビゲーションとセッション内検索
- セッションページに入ると現在のアプリで自動フィルター
- 並列ディレクトリスキャン + ヘッドテール JSONL 読み取りで読み込みパフォーマンスを最適化
### バックアップ管理
データの安全性を高める独立バックアップ管理パネルです。
- 設定可能なバックアップポリシー: 最大バックアップ数、自動クリーンアップルール
- ランタイム中の1時間ごとの定期自動バックアップ
- データベースマイグレーション前の自動バックアップ、バックフィル警告プロンプト
- バックアップのリネームと削除をサポート(確認ダイアログ付き)
- バックアップファイル名にローカルタイムを使用、より直感的に
### Oh My OpenCode (OMO) 統合
完全な Oh My OpenCode 設定ファイル管理です。
- エージェントモデル選択、カテゴリ設定、推奨モデル入力(#972@yovinchen に感謝)
- エージェントモデル選択 UX の改善、lowercase key 問題の修正(#1004@yovinchen に感謝)
- OMO Slim 軽量モードサポート
- OMO と OMO Slim の相互排他(データベースレベルで一貫性を保証)
### ワークスペース
- デイリーメモリファイルの全文検索、日付順ソート
- ディレクトリパスがクリック可能に、ファイル位置をすばやく開く
### ツールバー
- AppSwitcher がウィンドウ幅に応じて自動的にコンパクトモードに折りたたみ
- コンパクトモード切り替えのスムーズ遷移アニメーション
### 設定
- プロキシと使用量機能に初回使用確認ダイアログを追加、誤操作を防止
- `enableLocalProxy` スイッチを追加、ホーム画面のプロキシ UI 表示を制御
- より詳細なローカル環境チェック: CLI ツールバージョン検出(#870@kv-chiu に感謝)、Volta パス検出(#969@myjustify に感謝)
### プロバイダープリセット
- **AWS Bedrock**: AKSK と API Key の2種類の認証方式をサポート(#1047@keithyt06 に感謝)
- **SSAI Code**: パートナープリセット、5アプリ対応
- **CrazyRouter**: パートナープリセットと専用アイコン
- **AICoding**: パートナープリセットとプロモーションテキスト
- 国内モデルプロバイダープリセットを最新版に更新
- Qwen Coder を百炼 (Bailian) にリネーム(#965@zhu-jl18 に感謝)
### その他の新機能
- **Thinking Budget Rectifier**: より精密な thinking budget 制御(#1005@yovinchen に感謝)
- **WebDAV 自動同期**: 自動同期設定と大容量ファイル保護(#923@clx20000410 に感謝;#1043@SaladDay に感謝)
- **テーマ切り替えアニメーション**: 円形リビール遷移アニメーション(#905@funnytime75 に感謝)
- **Claude 設定エディタークイックトグル**: よく使う設定項目のクイック切り替え(#1012@JIA-ss に感謝)
- **動的エンドポイントヒント**: API フォーマット選択に基づく動的ヒントテキスト(#860@zhu-jl18 に感謝)
- **使用量ダッシュボード強化**: 自動更新、堅牢なフォーマット(#942@yovinchen に感謝)
- **新しい価格データ**: claude-opus-4-6 と gpt-5.3-codex#943@yovinchen に感謝)
- **サイレント起動の最適化**: サイレント起動オプションは自動起動が有効な場合のみ表示
---
## アーキテクチャ改善
### 部分キーフィールドマージ(⚠️ 破壊的変更)
プロバイダー切り替えを完全な設定上書きから部分キーフィールドマージ戦略に変更しました(#1098)。
**変更前**: プロバイダーを切り替えると、`settings_config` 全体がライブ設定ファイルに上書きされていました。つまり、ユーザーがライブファイルに手動で追加した非プロバイダー設定(プラグイン設定、MCP 設定、権限設定など)は、切り替えのたびに失われていました。この問題を補うため、以前のバージョンでは「共通設定スニペット」機能を提供し、毎回の切り替え時にマージされる共通設定を定義できました。
**変更後**: プロバイダー切り替え時に、プロバイダー関連のキー値(API キー、エンドポイント、モデルなど)のみが置換され、その他の設定はそのまま保持されます。そのため「共通設定スニペット」機能は不要となり、削除されました。
**影響と移行**:
- 共通設定スニペットを**使用していなかった**場合、この変更は完全に透過的で、切り替え体験が向上するだけです
- カスタム設定(MCP 設定、権限など)を保持するために共通設定スニペットを**使用していた**場合、それらの設定は切り替え時に自動的に保持されるようになり、追加の操作は不要です
- 共通設定スニペットを他の目的(切り替え時に追加設定を注入するなど)で使用していた場合は、アップグレード後にライブ設定ファイルに手動で設定を追加してください
このリファクタリングにより、フロントエンドファイル 6 つ(コンポーネント 3 つ + hooks 3 つ)と約 150 行のバックエンドデッドコードを削除しました。
### 手動インポートに変更
起動時の自動インポートを廃止し、手動の「現在の設定をインポート」ボタンに変更。意図しないユーザーデータの上書きを防止します。
### OmoVariant パラメータ化
`OmoVariant` 構造体によるパラメータ化で、OMO モジュールの約250行の重複コードを削除しました。
### OMO 共通設定の削除
2層マージシステムを削除し、約1,733行のコードを削減、アーキテクチャを簡素化しました。
### ProviderForm 分割
ProviderForm コンポーネントを2,227行から1,526行に削減し、5つの独立モジュール(opencodeFormUtils、useOmoModelSource、useOpencodeFormState、useOmoDraftState、useOpenclawFormState)に分離。保守性が大幅に向上しました。
### MCP/Skills 共有コンポーネント
AppCountBar、AppToggleGroup、ListItemRow などの共有コンポーネントを抽出し、MCP と Skills パネルの重複コードを削減(#897@PeanutSplash に感謝)。
### 設定ページリファクタリング
設定ページを5タブレイアウト(一般 | プロキシ | 詳細 | 使用量 | 情報)にリファクタリング。SettingsPage のコードを約716行から約426行に削減しました。
### その他の改善
- ターミナル統一: グローバル設定でターミナル選択を統一、WezTerm サポートを追加
- Claude モデル参照を 4.5 から 4.6 に更新
---
## バグ修正
### 重大な修正
- **Windows ホームディレクトリ回帰**: デフォルトのホームディレクトリ解決を復元し、Git/MSYS 環境でのデータベースパス変更によるデータ「消失」を防止
- **Linux 白画面**: AMD GPU の WebKitGTK ハードウェアアクセラレーションを無効化し、一部の Linux システムの起動白画面問題を解決(#986@ThendCN に感謝)
- **OpenAI Beta パラメータ**: `/v1/chat/completions``?beta=true` を追加しないように修正、Nvidia など OpenAI Chat 形式を使用するプロバイダーのリクエスト失敗を修正(#1052@jnorthrup に感謝)
- **ヘルスチェック認証**: プロバイダーの `auth_mode` 設定を尊重し、Bearer 認証のみをサポートするプロキシサービスのヘルスチェック失敗を回避(#824@Jassy930 に感謝)
### プロバイダープリセット修正
- OpenClaw `/v1` プレフィックスの二重パス問題を修正
- Opus 価格修正($15/$75 → $5/$25)と 4.6 へのアップグレード
- AIGoCode URL を `https://api.aigocode.com` に統一
- Zhipu GLM の古いパートナーステータスを削除
- 新規 Claude プロバイダー作成時の API Key 入力フィールドの表示を復元
- 非アクティブプロバイダーのクイックトグルを非表示、コンテキスト対応の JSON エディターヒントを表示
### OMO 修正
- omo-slim カテゴリチェックの補完(add/form/mutation パス)
- OMO Slim プロバイダー変更後のクエリキャッシュ無効化を修正
- OMO agent/category 推奨モデルをアップストリームソースと同期
- 「推奨を入力」ボタン失敗時の toast フィードバックを追加
- OMO/OMO Slim の最後のプロバイダー削除制限を撤廃
- OpenCode でモデル未設定時の保存を拒否(#932@yovinchen に感謝)
### OpenClaw 修正
- 25個の欠落 i18n キー、key={index} を安定 ID に置換、ディープリンク additive マージなどのコードレビュー問題を修正
- EnvPanel 堅牢性強化(NaN ガード、配列インデックスではなくエントリーキー名を使用)
- i18n 重複キーのマージ、プロバイダーフォーム翻訳を復元
### プラットフォーム修正
- Windows サイレント起動時のウィンドウフラッシュ(#901@funnytime75 に感謝)
- タイトルバーのダークモード追従(#903@funnytime75 に感謝)
- Windows の Skills パスセパレーターマッチング(#868@stmoonar に感謝)
- WSL ヘルパー関数の条件付きコンパイル
### UI 修正
- ツールバーの高さクリッピングによる AppSwitcher の遮蔽を修正
- 新バージョンがある場合、緑のチェックマークではなく更新バッジを表示
- セッションマネージャーボタンを Claude/Codex アプリでのみ表示
- SQL インポート/エクスポートカードのダークモードスタイルを統一(#1067@SaladDay に感謝)
### その他の修正
- セッションマネージャーのハードコードされた中国語文字列を i18n キーに置換
- Skill ドキュメント URL のブランチとパスを修正(#977@yovinchen に感謝)
- OpenCode install.sh インストールパス検出の補完(#988@zhu-jl18 に感謝)
- Skill ZIP シンボリックリンク解決の修正(#1040@yovinchen に感謝)
- MCP フォームに OpenCode チェックボックスを追加(#1026@yovinchen に感謝)
- useProvidersQuery の自動インポート副作用を削除
---
## パフォーマンス最適化
- セッションパネルの並列ディレクトリスキャン + ヘッドテール JSONL 読み取りで、セッションリスト読み込み速度を大幅向上
- Tauri ローカル IPC の不要な query cache を削除し、メモリ使用量を削減
---
## ドキュメント
- スポンサー更新: SSSAiCode、Crazyrouter、AICoding、Right Code、MiniMax
- ユーザーマニュアルを追加(#979@yovinchen に感謝)
---
## 注意事項
- **OpenClaw は新しくサポートされたアプリです**: 関連機能を使用するには、先に OpenClaw CLI をインストールする必要があります。
- **⚠️ 共通設定スニペット機能は削除されました**: プロバイダー切り替えが部分キーフィールドマージ(API キー、エンドポイント、モデルなどのみ置換)に変更されたため、ユーザーのその他の設定は自動的に保持され、共通設定スニペットは不要になりました。移行の詳細は上記「アーキテクチャ改善」セクションを参照してください。
- **自動インポートは手動に変更されました**: 起動時に外部設定を自動インポートしなくなりました。必要に応じて「現在の設定をインポート」を手動でクリックしてください。
- **OMO と OMO Slim は相互排他**: 同時に一つだけ有効にできます。切り替え時にもう一方は自動的に無効になります。
- **バックアップ機能はデフォルトで有効**: ランタイム中に1時間ごとに自動バックアップします。バックアップパネルでポリシーを調整できます。
---
## 特別な感謝
以下のコントリビューターの皆様、このリリースへの貢献に感謝します!
@TinsFox @keithyt06 @kv-chiu @SaladDay @jnorthrup @JIA-ss @clx20000410 @ThendCN @yovinchen @zhu-jl18 @myjustify @funnytime75 @PeanutSplash @Jassy930 @stmoonar
---
## ダウンロードとインストール
[Releases](https://github.com/farion1231/cc-switch/releases/latest) から適切なバージョンをダウンロードしてください。
### システム要件
| システム | 最小バージョン | アーキテクチャ |
| -------- | -------------------------------- | ----------------------------------- |
| Windows | Windows 10 以降 | x64 |
| macOS | macOS 10.15 (Catalina) 以降 | Intel (x64) / Apple Silicon (arm64) |
| Linux | 下表参照 | x64 |
### Windows
| ファイル | 説明 |
| ---------------------------------------- | ---------------------------------------------------- |
| `CC-Switch-v3.11.0-Windows.msi` | **推奨** - MSI インストーラー、自動更新対応 |
| `CC-Switch-v3.11.0-Windows-Portable.zip` | ポータブル版、解凍して実行、レジストリ書き込みなし |
### macOS
| ファイル | 説明 |
| -------------------------------- | ----------------------------------------------------------------- |
| `CC-Switch-v3.11.0-macOS.zip` | **推奨** - 解凍して Applications にドラッグ、Universal Binary |
| `CC-Switch-v3.11.0-macOS.tar.gz` | Homebrew インストールと自動更新用 |
> **注意**: 作者が Apple Developer アカウントを持っていないため、初回起動時に「開発元を確認できません」という警告が表示される場合があります。一度閉じてから、「システム設定」→「プライバシーとセキュリティ」→「このまま開く」をクリックすると、その後は正常に開けます。
### Homebrew (macOS)
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
| ディストリビューション | 推奨形式 | インストール方法 |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| 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` |
+302
View File
@@ -0,0 +1,302 @@
# CC Switch v3.11.0
> OpenClaw 支持、会话管理器、备份管理与 50+ 项改进
**[English →](v3.11.0-en.md) | [日本語版 →](v3.11.0-ja.md)**
---
## 概览
CC Switch v3.11.0 是一次大规模更新,新增第五个应用 **OpenClaw** 的完整管理支持,同时带来全新的**会话管理器**和**备份管理**功能。此外,**Oh My OpenCode (OMO) 集成**、供应商切换的**部分键值合并**架构升级、**设置页面重构**等多项改进使整体体验更加完善。
**发布日期**2026-02-26
**更新规模**147 commits | 274 files changed | +32,179 / -5,467 lines
---
## 重点内容
- **OpenClaw 支持**:第五个受管理应用,含 13 个供应商预设、Env/Tools/AgentsDefaults 配置编辑器、Workspace 文件管理
- **会话管理器**:浏览五个应用的历史会话,支持目录导航和会话内搜索
- **备份管理**:独立备份面板,可配置策略、定时备份、迁移前自动备份
- **Oh My OpenCode 集成**:完整 OMO 配置管理,支持 OMO Slim 轻量模式
- **部分键值合并(⚠️ 破坏性变更)**:供应商切换改为仅替换供应商相关字段,保留用户的其余设置;"通用配置片段"功能因此移除
- **设置页面重构**:5 标签页布局,代码量减少约 40%
- **6 组新供应商预设**AWS Bedrock、SSAI Code、CrazyRouter、AICoding 等
- **Thinking Budget Rectifier**:代理矫正器,更精细的 thinking budget 控制
- **主题切换动画**:圆形揭示过渡动画,视觉体验升级
- **WebDAV 自动同步**:支持自动同步与大文件防护
---
## 主要功能
### OpenClaw 支持(新增第五应用)
CC Switch 新增对 OpenClaw 的完整管理支持,这是继 Claude Code、Codex、Gemini CLI、OpenCode 之后的第五个受管理应用。
- **供应商管理**:新增、编辑、切换、删除 OpenClaw 供应商,含 13 个内置预设
- **配置编辑器**:Env(环境变量)、Tools(工具)、AgentsDefaults(代理默认值)三个专属配置面板
- **Workspace 面板**:支持 HEARTBEAT/BOOTSTRAP/BOOT 文件管理及每日记忆
- **Additive 叠加模式**:支持配置叠加而非覆盖
- **默认模型按钮**:一键填充推荐模型,添加供应商时自动将建议模型注册到 allowlist
- **品牌与交互**:专属品牌图标、应用切换淡入淡出过渡动画
- **深链接支持**:通过 URL 导入 OpenClaw 供应商配置
- **完整国际化**:中/英/日三语全面支持
### 会话管理器 Sessions
全新的会话管理器,帮助你浏览和检索历史会话记录。
- 支持浏览 Claude Code、Codex、Gemini CLI、OpenCode、OpenClaw 五个应用的历史会话(#867,感谢 @TinsFox
- 目录导航和会话内搜索
- 进入会话页面时默认过滤为当前应用,快速定位
- 并行目录扫描 + 头尾 JSONL 读取,优化加载性能
### 备份管理 Backup
独立的备份管理面板,让数据安全更有保障。
- 可配置备份策略:最大备份数量、自动清理规则
- 运行时每小时定期自动备份
- 数据库迁移前自动备份,带回填警告提示
- 支持备份重命名和删除(含确认对话框)
- 备份文件名使用本地时间,更直观
### Oh My OpenCode (OMO) 集成
完整的 Oh My OpenCode 配置文件管理。
- Agent 模型选择、Category 配置、推荐模型填充(#972,感谢 @yovinchen
- 改进 Agent 模型选择 UX,修复 lowercase key 问题(#1004,感谢 @yovinchen
- OMO Slim 轻量模式支持
- OMO 与 OMO Slim 互斥切换(数据库层级强制保证一致性)
### 工作空间 Workspace
- 每日记忆文件全文搜索,按日期排序
- 目录路径可点击跳转,快速打开文件位置
### 工具栏 Toolbar
- AppSwitcher 根据窗口宽度自动折叠为紧凑模式
- 紧凑模式切换平滑过渡动画
### 设置 Settings
- 代理和用量功能新增首次使用确认对话框,避免误操作
- 新增 `enableLocalProxy` 开关,控制主页代理 UI 显示
- 更精细的本地环境检查:CLI 工具版本检测(#870,感谢 @kv-chiu)、Volta 路径检测(#969,感谢 @myjustify
### 供应商预设 Preset
- **AWS Bedrock**:支持 AKSK 和 API Key 两种认证方式(#1047,感谢 @keithyt06
- **SSAI Code**:合作伙伴预设,覆盖五端
- **CrazyRouter**:合作伙伴预设及专属图标
- **AICoding**:合作伙伴预设及推广文案
- 更新国内模型供应商预设至最新版本
- Qwen Coder 重命名为百炼 (Bailian)#965,感谢 @zhu-jl18
### 其他新功能
- **Thinking Budget Rectifier**:代理矫正器,更精细地控制 thinking budget 分配(#1005,感谢 @yovinchen
- **WebDAV 自动同步**:支持自动同步配置,并增加大文件防护(#923,感谢 @clx20000410#1043,感谢 @SaladDay
- **主题切换动画**:圆形揭示过渡动画,视觉体验更流畅(#905,感谢 @funnytime75
- **Claude 配置编辑器快速开关**:快速切换常用配置项(#1012,感谢 @JIA-ss
- **动态端点提示**:根据 API 格式选择动态显示端点提示文本(#860,感谢 @zhu-jl18
- **用量仪表盘增强**:自动刷新、更强健的数据格式化(#942,感谢 @yovinchen
- **新增定价数据**claude-opus-4-6 和 gpt-5.3-codex#943,感谢 @yovinchen
- **静默启动优化**:静默启动选项仅在开机启动开启时显示
---
## 架构改进
### 部分键值合并(⚠️ 破坏性变更)
供应商切换从全量配置覆写改为部分键值合并策略(#1098)。
**变更前**:切换供应商时,整个 `settings_config` 会覆写到 live 配置文件。这意味着用户在 live 文件中手动添加的非供应商设置(插件配置、MCP 配置、权限设置等)会在每次切换时丢失。为了弥补这个问题,之前版本提供了"通用配置片段"功能,让用户定义每次切换时都会合并的公共配置。
**变更后**:切换供应商时,仅替换供应商相关的键值(API Key、端点、模型等),用户的其余设置完整保留。因此"通用配置片段"功能不再需要,已被移除。
**影响与迁移**
- 如果你之前**没有使用**通用配置片段功能,此变更对你完全透明,切换体验只会更好
- 如果你之前**使用了**通用配置片段功能来保留自定义设置(如 MCP 配置、权限等),升级后这些设置会在切换时自动保留,无需额外操作
- 如果你利用通用配置片段做其他用途(如在切换时注入额外配置),请在升级后手动将这些配置写入 live 配置文件中
此次重构删除了 6 个前端文件(3 个组件 + 3 个 hooks)、约 150 行后端死代码。
### 手动导入替代自动导入
启动时不再自动导入外部配置,改为手动点击"导入当前配置"按钮,避免意外覆盖用户数据。
### OMO Variant 参数化
通过 `OmoVariant` 结构体参数化消除 OMO 模块约 250 行重复代码。
### OMO 公共配置移除
删除二层合并系统,减少约 1,733 行代码,简化架构。
### ProviderForm 拆分
ProviderForm 组件从 2,227 行减至 1,526 行,提取 5 个独立模块(opencodeFormUtils、useOmoModelSource、useOpencodeFormState、useOmoDraftState、useOpenclawFormState),可维护性显著提升。
### MCP/Skills 共享组件
提取 AppCountBar、AppToggleGroup、ListItemRow 等共享组件,减少 MCP 和 Skills 面板的重复代码(#897,感谢 @PeanutSplash)。
### 设置页面重构
设置页面重构为 5 标签页布局(通用 | 代理 | 高级 | 用量 | 关于),SettingsPage 代码从约 716 行减至约 426 行。
### 其他改进
- 终端统一:全局设置统一终端选择,新增 WezTerm 支持
- Claude 模型引用从 4.5 更新到 4.6
---
## Bug 修复
### 严重修复
- **Windows 主目录回归**:恢复默认主目录解析,防止 Git/MSYS 环境下数据库路径变更导致数据"丢失"
- **Linux 白屏**:禁用 AMD GPU 的 WebKitGTK 硬件加速,解决部分 Linux 系统启动白屏问题(#986,感谢 @ThendCN
- **OpenAI Beta 参数**:不再为 `/v1/chat/completions` 添加 `?beta=true`,修复 Nvidia 等使用 OpenAI Chat 格式的供应商请求失败(#1052,感谢 @jnorthrup
- **健康检查认证**:尊重供应商 `auth_mode` 设置,避免仅支持 Bearer 认证的代理服务健康检查失败(#824,感谢 @Jassy930
### 供应商预设修复
- 修复 OpenClaw `/v1` 前缀双重路径问题
- Opus 定价修正($15/$75 → $5/$25)并升级到 4.6
- AIGoCode URL 统一为 `https://api.aigocode.com`
- Zhipu GLM 移除过时合作伙伴状态
- 新建 Claude 供应商时 API Key 输入框可见性恢复
- 非活跃供应商隐藏快速开关,显示上下文感知的 JSON 编辑器提示
### OMO 修复
- omo-slim 分类检查补齐(add/form/mutation 路径)
- OMO Slim 供应商变更后正确失效查询缓存
- OMO agent/category 推荐模型与上游源同步
- "填充推荐"按钮失败时增加 toast 反馈
- 移除 OMO/OMO Slim 最后一个供应商的删除限制
- OpenCode 未配置模型时拒绝保存(#932,感谢 @yovinchen
### OpenClaw 修复
- 修复 25 个缺失 i18n key、替换 key={index} 为稳定 ID、深链接 additive 合并等代码审查问题
- EnvPanel 健壮性增强(NaN 守卫、使用条目键名而非数组索引)
- i18n 重复键合并,恢复供应商表单翻译
### 平台修复
- Windows 静默启动时窗口闪烁(#901,感谢 @funnytime75
- 标题栏暗黑模式跟随主题(#903,感谢 @funnytime75
- Windows Skills 路径分隔符匹配(#868,感谢 @stmoonar
- WSL 辅助函数条件编译
### UI 修复
- 工具栏高度裁切导致 AppSwitcher 被遮挡
- 有新版本时显示更新徽章而非绿色对勾
- 仅 Claude/Codex 应用显示会话管理器按钮
- SQL 导入/导出卡片暗黑模式样式统一(#1067,感谢 @SaladDay
### 其他修复
- 会话管理器硬编码中文字符串替换为 i18n key
- Skill 文档 URL 分支和路径修正(#977,感谢 @yovinchen
- OpenCode install.sh 安装路径检测补齐(#988,感谢 @zhu-jl18
- Skill ZIP 符号链接解析修复(#1040,感谢 @yovinchen
- MCP 表单补齐 OpenCode 复选框(#1026,感谢 @yovinchen
- useProvidersQuery 中自动导入副作用移除
---
## 性能优化
- 会话面板并行目录扫描 + 头尾 JSONL 读取,大幅提升会话列表加载速度
- 移除 Tauri 本地 IPC 不必要的 query cache,减少内存占用
---
## 文档
- 赞助商更新:SSSAiCode、Crazyrouter、AICoding、Right Code、MiniMax
- 新增用户手册(#979,感谢 @yovinchen
---
## 说明与注意事项
- **OpenClaw 为新支持的应用**:需要先安装 OpenClaw CLI 才能使用相关功能。
- **⚠️ 通用配置片段功能已移除**:由于供应商切换改为部分键值合并(仅替换 API Key、端点、模型等字段),用户的其余设置会自动保留,"通用配置片段"功能不再需要。详见上方"架构改进"章节的迁移说明。
- **自动导入已改为手动**:启动时不再自动导入外部配置,请在需要时手动点击"导入当前配置"。
- **OMO 与 OMO Slim 互斥**:同一时间只能启用其中一个,切换时另一个会自动禁用。
- **备份功能默认开启**:运行时每小时自动备份,可在备份面板调整策略。
---
## 特别感谢
感谢以下贡献者为本版本做出的贡献!
@TinsFox @keithyt06 @kv-chiu @SaladDay @jnorthrup @JIA-ss @clx20000410 @ThendCN @yovinchen @zhu-jl18 @myjustify @funnytime75 @PeanutSplash @Jassy930 @stmoonar
---
## 下载与安装
访问 [Releases](https://github.com/farion1231/cc-switch/releases/latest) 下载对应版本。
### 系统要求
| 系统 | 最低版本 | 架构 |
| ------- | ----------------------------- | ----------------------------------- |
| Windows | Windows 10 及以上 | x64 |
| macOS | macOS 10.15 (Catalina) 及以上 | Intel (x64) / Apple Silicon (arm64) |
| Linux | 见下表 | x64 |
### Windows
| 文件 | 说明 |
| ---------------------------------------- | ----------------------------------- |
| `CC-Switch-v3.11.0-Windows.msi` | **推荐** - MSI 安装包,支持自动更新 |
| `CC-Switch-v3.11.0-Windows-Portable.zip` | 便携版,解压即用,不写入注册表 |
### macOS
| 文件 | 说明 |
| -------------------------------- | --------------------------------------------------------- |
| `CC-Switch-v3.11.0-macOS.zip` | **推荐** - 解压后拖入 Applications 即可,Universal Binary |
| `CC-Switch-v3.11.0-macOS.tar.gz` | 用于 Homebrew 安装和自动更新 |
> **注意**:由于作者没有苹果开发者账号,首次打开可能出现"未知开发者"警告,请先关闭,然后前往"系统设置" → "隐私与安全性" → 点击"仍要打开",之后便可以正常打开
### HomebrewmacOS
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
| 发行版 | 推荐格式 | 安装方式 |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| 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` |
+122
View File
@@ -0,0 +1,122 @@
# CC Switch v3.11.1
> Revert Partial Key-Field Merging, Restore Common Config Snippet & Bug Fixes
**[中文版 →](v3.11.1-zh.md) | [日本語版 →](v3.11.1-ja.md)**
---
## Overview
CC Switch v3.11.1 is a hotfix release that reverts the **Partial Key-Field Merging** architecture introduced in v3.11.0, restoring the proven "**full config overwrite + Common Config Snippet**" mechanism. It also includes several UI and platform compatibility fixes.
**Release Date**: 2026-02-28
**Update Scale**: 8 commits | 52 files changed | +3,948 / -1,411 lines
---
## Highlights
- **Restore Full Config Overwrite + Common Config Snippet**: Reverted partial key-field merging due to critical data loss issues; restores full config snapshot write and Common Config Snippet UI
- **Proxy Panel Improvements**: Proxy toggle moved into panel body for better discoverability of takeover options
- **Theme & Compact Mode Fixes**: "Follow System" theme now auto-updates; compact mode exit works correctly
- **Windows Compatibility**: Disabled env check and one-click install to prevent protocol handler side effects
---
## Reverted
### Restore Full Config Overwrite + Common Config Snippet
Reverted the partial key-field merging refactoring introduced in v3.11.0 (revert 992dda5c).
**Why reverted**: The partial key-field merging approach had three critical issues:
1. **Data loss on switch**: Non-whitelisted custom fields were silently dropped during provider switching
2. **Permanent backfill stripping**: Backfill permanently removed non-key fields from the database, causing irreversible data loss
3. **Maintenance burden**: The whitelist of "key fields" required constant maintenance as new config keys were added
**What's restored**:
- Full config snapshot write on provider switch (predictable, complete overwrite)
- Common Config Snippet UI and backend commands
- 6 frontend components/hooks (3 components + 3 hooks)
**Migration**:
- If you upgraded to v3.11.0 and your providers lost custom fields, re-import your config or manually re-add the missing fields
- Common Config Snippet is available again — use it to define shared config that should persist across provider switches
---
## Changed
- **Proxy Panel Layout**: Moved proxy on/off toggle from accordion header into panel content area, placed directly above app takeover options. This ensures users see takeover configuration immediately after enabling the proxy, avoiding the common mistake of enabling the proxy without configuring takeover
- **Manual Import for OpenCode/OpenClaw**: Removed auto-import on startup; empty state now shows an "Import Current Config" button, consistent with Claude/Codex/Gemini behavior
---
## Fixed
- **"Follow System" Theme Not Auto-Updating**: Delegated to Tauri's native theme tracking (`set_window_theme(None)`) so the WebView's `prefers-color-scheme` media query stays in sync with OS theme changes
- **Compact Mode Cannot Exit**: Restored `flex-1` on `toolbarRef` so `useAutoCompact`'s exit condition triggers correctly based on available width instead of content width
- **Proxy Takeover Toast Shows {{app}}**: Added missing `app` interpolation parameter to i18next `t()` calls for proxy takeover enabled/disabled messages
- **Windows Protocol Handler Side Effects**: Disabled environment check and one-click install on Windows to prevent unintended protocol handler registration
---
## Notes & Considerations
- **Common Config Snippet is back**: If you relied on this feature in v3.10.x and earlier, it works the same way again. Define shared config that should persist across all provider switches.
- **v3.11.0 Partial Key-Field Merging users**: If you noticed missing config fields after switching providers in v3.11.0, re-import your config to restore them.
---
## Download & Installation
Visit [Releases](https://github.com/farion1231/cc-switch/releases/latest) to download the appropriate version.
### System Requirements
| System | Minimum Version | Architecture |
| ------- | ------------------------------- | ----------------------------------- |
| Windows | Windows 10 or later | x64 |
| macOS | macOS 10.15 (Catalina) or later | Intel (x64) / Apple Silicon (arm64) |
| Linux | See table below | x64 |
### Windows
| File | Description |
| ---------------------------------------- | ---------------------------------------------------- |
| `CC-Switch-v3.11.1-Windows.msi` | **Recommended** - MSI installer with auto-update |
| `CC-Switch-v3.11.1-Windows-Portable.zip` | Portable version, extract and run, no registry write |
### macOS
| File | Description |
| -------------------------------- | -------------------------------------------------------------------- |
| `CC-Switch-v3.11.1-macOS.zip` | **Recommended** - Extract and drag to Applications, Universal Binary |
| `CC-Switch-v3.11.1-macOS.tar.gz` | For Homebrew installation and auto-update |
> **Note**: Since the author doesn't have an Apple Developer account, you may see an "unidentified developer" warning on first launch. Please close it, then go to "System Settings" → "Privacy & Security" → click "Open Anyway", and it will open normally afterwards.
### Homebrew (macOS)
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
Update:
```bash
brew upgrade --cask cc-switch
```
### Linux
| Distribution | Recommended Format | Installation Method |
| --------------------------------------- | ------------------ | ---------------------------------------------------------------------- |
| 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 directly, or use AUR |
| Other distributions / Unsure | `.AppImage` | `chmod +x CC-Switch-*.AppImage && ./CC-Switch-*.AppImage` |
+122
View File
@@ -0,0 +1,122 @@
# CC Switch v3.11.1
> 部分キーフィールドマージの撤回、共通設定スニペットの復元とバグ修正
**[中文版 →](v3.11.1-zh.md) | [English →](v3.11.1-en.md)**
---
## 概要
CC Switch v3.11.1 は修正リリースです。v3.11.0 で導入された**部分キーフィールドマージ**アーキテクチャを撤回し、実績のある「**完全設定上書き + 共通設定スニペット**」メカニズムを復元しました。また、複数の UI とプラットフォーム互換性の問題を修正しています。
**リリース日**: 2026-02-28
**更新規模**: 8 commits | 52 files changed | +3,948 / -1,411 lines
---
## ハイライト
- **完全設定上書き + 共通設定スニペットの復元**: 重大なデータ損失問題のため部分キーフィールドマージを撤回、完全設定スナップショット書き込みと共通設定スニペット UI を復元
- **プロキシパネルの改善**: プロキシトグルをパネル本体に移動し、テイクオーバーオプションの発見性を向上
- **テーマとコンパクトモードの修正**: 「システムに従う」テーマが正しく自動更新、コンパクトモードの終了が正常に動作
- **Windows 互換性**: プロトコルハンドラーの副作用を防ぐため、環境チェックとワンクリックインストールを無効化
---
## 撤回
### 完全設定上書き + 共通設定スニペットの復元
v3.11.0 で導入された部分キーフィールドマージリファクタリングを撤回しました(revert 992dda5c)。
**撤回理由**: 部分キーフィールドマージのアプローチには3つの重大な問題がありました:
1. **切り替え時のデータ損失**: ホワイトリストにないカスタムフィールドがプロバイダー切り替え時にサイレントに破棄された
2. **バックフィルによる永続的な剥離**: バックフィル操作がデータベースから非キーフィールドを永続的に削除し、不可逆なデータ損失を引き起こした
3. **メンテナンス負担**: 「キーフィールド」のホワイトリストは新しい設定キーが追加されるたびに継続的なメンテナンスが必要
**復元された内容**:
- プロバイダー切り替え時の完全設定スナップショット書き込み(予測可能な完全上書き)
- 共通設定スニペット UI およびバックエンドコマンド
- 6つのフロントエンドファイル(コンポーネント 3つ + hooks 3つ)
**移行ガイド**:
- v3.11.0 にアップグレードしてプロバイダーのカスタムフィールドが失われた場合は、設定を再インポートするか、欠落したフィールドを手動で追加してください
- 共通設定スニペット機能が再び利用可能です — プロバイダー切り替え時に保持すべき共有設定を定義するために使用してください
---
## 変更
- **プロキシパネルレイアウト**: プロキシのオン/オフトグルをアコーディオンヘッダーからパネルのコンテンツエリアに移動し、アプリテイクオーバーオプションの直上に配置。プロキシを有効にした後すぐにテイクオーバー設定が見えるようになり、「プロキシだけ有効にしてテイクオーバーを設定しない」というよくある誤操作を防止
- **OpenCode/OpenClaw の手動インポート**: 起動時の自動インポートを削除。空の状態ページに「現在の設定をインポート」ボタンを表示し、Claude/Codex/Gemini と同じ動作に統一
---
## 修正
- **「システムに従う」テーマが自動更新されない**: Tauri のネイティブテーマ追跡(`set_window_theme(None)`)に委譲し、WebView の `prefers-color-scheme` メディアクエリが OS テーマの変更に同期するように修正
- **コンパクトモードを終了できない**: `toolbarRef``flex-1` を復元し、`useAutoCompact` の終了条件がコンテンツ幅ではなく利用可能な幅に基づいて正しくトリガーされるように修正
- **プロキシテイクオーバー Toast に {{app}} が表示される**: プロキシテイクオーバーの有効/無効メッセージの i18next `t()` 呼び出しに欠落していた `app` 補間パラメータを追加
- **Windows プロトコルハンドラーの副作用**: 意図しないプロトコルハンドラー登録を防ぐため、Windows で環境チェックとワンクリックインストールを無効化
---
## 注意事項
- **共通設定スニペットが復活しました**: v3.10.x 以前でこの機能を使用していた場合、同じ方法で動作します。プロバイダー切り替え時に保持すべき共有設定を定義するために使用してください。
- **v3.11.0 部分キーフィールドマージユーザーの方へ**: v3.11.0 でプロバイダー切り替え後に設定フィールドが欠落していた場合は、設定を再インポートして復元してください。
---
## ダウンロードとインストール
[Releases](https://github.com/farion1231/cc-switch/releases/latest) から適切なバージョンをダウンロードしてください。
### システム要件
| システム | 最小バージョン | アーキテクチャ |
| -------- | -------------------------------- | ----------------------------------- |
| Windows | Windows 10 以降 | x64 |
| macOS | macOS 10.15 (Catalina) 以降 | Intel (x64) / Apple Silicon (arm64) |
| Linux | 下表参照 | x64 |
### Windows
| ファイル | 説明 |
| ---------------------------------------- | ---------------------------------------------------- |
| `CC-Switch-v3.11.1-Windows.msi` | **推奨** - MSI インストーラー、自動更新対応 |
| `CC-Switch-v3.11.1-Windows-Portable.zip` | ポータブル版、解凍して実行、レジストリ書き込みなし |
### macOS
| ファイル | 説明 |
| -------------------------------- | ----------------------------------------------------------------- |
| `CC-Switch-v3.11.1-macOS.zip` | **推奨** - 解凍して Applications にドラッグ、Universal Binary |
| `CC-Switch-v3.11.1-macOS.tar.gz` | Homebrew インストールと自動更新用 |
> **注意**: 作者が Apple Developer アカウントを持っていないため、初回起動時に「開発元を確認できません」という警告が表示される場合があります。一度閉じてから、「システム設定」→「プライバシーとセキュリティ」→「このまま開く」をクリックすると、その後は正常に開けます。
### Homebrew (macOS)
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
| ディストリビューション | 推奨形式 | インストール方法 |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| 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` |
+122
View File
@@ -0,0 +1,122 @@
# CC Switch v3.11.1
> 回退部分键值合并、恢复通用配置片段与多项修复
**[English →](v3.11.1-en.md) | [日本語版 →](v3.11.1-ja.md)**
---
## 概览
CC Switch v3.11.1 是一个修复版本,回退了 v3.11.0 中引入的**部分键值合并**架构,恢复经过验证的「**全量配置覆写 + 通用配置片段**」机制,同时修复了多个 UI 和平台兼容性问题。
**发布日期**2026-02-28
**更新规模**8 commits | 52 files changed | +3,948 / -1,411 lines
---
## 重点内容
- **恢复全量配置覆写 + 通用配置片段**:因关键数据丢失问题回退部分键值合并,恢复完整配置快照写入和通用配置片段 UI
- **代理面板交互优化**:代理开关移入面板内部,接管选项一目了然
- **主题与紧凑模式修复**:「跟随系统」主题现可正确自动更新,紧凑模式退出恢复正常
- **Windows 兼容性**:禁用环境检查和一键安装,防止协议处理程序副作用
---
## 回退
### 恢复全量配置覆写 + 通用配置片段
回退了 v3.11.0 中引入的部分键值合并重构(revert 992dda5c)。
**回退原因**:部分键值合并方案存在三个关键缺陷:
1. **切换时数据丢失**:非白名单的自定义字段在供应商切换时被静默丢弃
2. **回填永久剥离**:回填操作永久移除数据库中的非键字段,造成不可逆的数据丢失
3. **维护成本高**:「键字段」白名单需要随新配置项不断维护,容易遗漏
**恢复的内容**
- 供应商切换时的完整配置快照写入(可预测的全量覆写)
- 通用配置片段 UI 及后端命令
- 6 个前端文件(3 个组件 + 3 个 hooks
**迁移说明**
- 如果你在 v3.11.0 中切换供应商后丢失了自定义字段,请重新导入配置或手动补回缺失的字段
- 通用配置片段功能已恢复——用它来定义切换供应商时需要保留的共享配置
---
## 变更
- **代理面板交互优化**:将代理开关从折叠面板标题移入面板内部,紧邻应用接管选项。确保用户启用代理后能立即看到接管配置,避免「只开代理不接管」的常见误操作
- **OpenCode/OpenClaw 手动导入**:移除启动时自动导入供应商配置的行为,改为在空状态页显示「导入当前配置」按钮,与 Claude/Codex/Gemini 保持一致
---
## 修复
- **「跟随系统」主题不自动更新**:改用 Tauri 原生主题追踪(`set_window_theme(None)`),使 WebView 的 `prefers-color-scheme` 媒体查询能正确响应 OS 主题切换
- **紧凑模式无法退出**:恢复 `toolbarRef` 上的 `flex-1` class,修复 `useAutoCompact` 的退出条件因宽度计算错误而永远不触发的问题
- **代理接管 Toast 显示 {{app}}**:为 proxy takeover 的 i18next `t()` 调用补充缺失的 `app` 插值参数
- **Windows 协议处理副作用**:在 Windows 上禁用环境检查和一键安装功能,防止协议处理程序注册引发的意外副作用
---
## 说明与注意事项
- **通用配置片段已恢复**:如果你在 v3.10.x 及更早版本中使用了此功能,它的工作方式与之前完全一致。用它来定义切换供应商时需要保留的共享配置。
- **v3.11.0 部分键值合并用户**:如果你在 v3.11.0 中切换供应商后发现配置字段丢失,请重新导入配置以恢复。
---
## 下载与安装
访问 [Releases](https://github.com/farion1231/cc-switch/releases/latest) 下载对应版本。
### 系统要求
| 系统 | 最低版本 | 架构 |
| ------- | ----------------------------- | ----------------------------------- |
| Windows | Windows 10 及以上 | x64 |
| macOS | macOS 10.15 (Catalina) 及以上 | Intel (x64) / Apple Silicon (arm64) |
| Linux | 见下表 | x64 |
### Windows
| 文件 | 说明 |
| ---------------------------------------- | ----------------------------------- |
| `CC-Switch-v3.11.1-Windows.msi` | **推荐** - MSI 安装包,支持自动更新 |
| `CC-Switch-v3.11.1-Windows-Portable.zip` | 便携版,解压即用,不写入注册表 |
### macOS
| 文件 | 说明 |
| -------------------------------- | --------------------------------------------------------- |
| `CC-Switch-v3.11.1-macOS.zip` | **推荐** - 解压后拖入 Applications 即可,Universal Binary |
| `CC-Switch-v3.11.1-macOS.tar.gz` | 用于 Homebrew 安装和自动更新 |
> **注意**:由于作者没有苹果开发者账号,首次打开可能出现「未知开发者」警告,请先关闭,然后前往「系统设置」→「隐私与安全性」→ 点击「仍要打开」,之后便可以正常打开
### HomebrewmacOS
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
| 发行版 | 推荐格式 | 安装方式 |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| 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` |
+238
View File
@@ -0,0 +1,238 @@
# CC Switch v3.12.0
> Stream Check Returns, OpenAI Responses API Arrives, and OpenClaw / WebDAV Get a Major Upgrade
**[中文版 →](v3.12.0-zh.md) | [日本語版 →](v3.12.0-ja.md)**
---
## Overview
CC Switch v3.12.0 is a feature release focused on provider compatibility, OpenClaw editing, Common Config usability, and sync/data reliability. It restores the **Model Health Check (Stream Check)** UI with improved stability, adds **OpenAI Responses API** format conversion, expands provider presets for **Ucloud**, **Micu**, **X-Code API**, **Novita**, and **Bailian For Coding**, and upgrades **WebDAV sync** with dual-layer versioning.
**Release Date**: 2026-03-09
**Update Scale**: 56 commits | 221 files changed | +20,582 / -8,026 lines
---
## Highlights
- **Stream Check returns**: Restored the model health check UI, added first-run confirmation, and fixed `openai_chat` provider support
- **OpenAI Responses API**: Added `api_format = "openai_responses"` with bidirectional conversion and shared conversion cleanup — simply select the Responses API format when adding a provider and enable proxy takeover, and you can use GPT-series models in Claude Code!
- **OpenClaw overhaul**: Introduced JSON5 round-trip config editing, a config health banner, better agent model selection, and a User-Agent toggle
- **Preset expansion**: Added Ucloud, Micu, X-Code API, Novita, and Bailian For Coding updates, plus SiliconFlow partner badge and model-role badges
- **Sync and maintenance improvements**: Added WebDAV protocol v2 + db-v6 versioning, daily rollups, incremental auto-vacuum, and sync-aware backup
- **Common Config usability improvements**: After updating a Common Config Snippet, it is now automatically applied when switching providers — no more manual checkbox needed
---
## Main Features
### Model Health Check (Stream Check)
Restored the Stream Check panel for live provider validation, improving the reliability of provider management.
- Restored Stream Check UI panel with single and batch provider availability testing
- Added first-run confirmation dialog to prevent unsupported providers from showing misleading errors
- Fixed detection compatibility for `openai_chat` API format providers
### OpenAI Responses API
Added native support for providers using the OpenAI Responses API with a new `openai_responses` API format.
- New `api_format = "openai_responses"` provider format option
- Bidirectional Anthropic Messages <-> OpenAI Responses API format conversion
- Consolidated shared conversion logic to reduce code duplication
### Bedrock Request Optimizer
Added a PRE-SEND phase request optimizer for AWS Bedrock providers to improve compatibility and performance.
- PRE-SEND thinking + cache injection optimizer (#1301, thanks @keithyt06)
### OpenClaw Config Enhancements
Comprehensive upgrade to the OpenClaw configuration editing experience with richer management capabilities.
- JSON5 round-trip write-back: preserves comments and formatting when editing configs
- EnvPanel JSON editing mode and `tools.profile` selection support
- New config validation warnings and config health status checks
- Improved agent model dropdown with recommended model fill from provider presets
- User-Agent toggle: optionally append OpenClaw identifier to requests (defaults to off)
- Legacy timeout configuration auto-migration
### Provider Presets
New and expanded provider presets covering more providers and use cases.
- **Ucloud**: Added `endpointCandidates` and OpenClaw defaults, refreshed `templateValues` / `suggestedDefaults`
- **Micu**: Added preset defaults and OpenClaw recommended models
- **X-Code API**: Added Claude presets and `endpointCandidates`
- **Novita**: New provider preset (#1192, thanks @Alex-wuhu)
- **Bailian For Coding**: New provider preset (#1263, thanks @suki135246)
- **SiliconFlow**: Added partner badge
- **Model Role Badges**: Provider presets now support model-role badge display
### WebDAV Sync Enhancements
WebDAV sync introduces dual-layer versioning for improved sync reliability and data safety.
- New WebDAV protocol v2 + db-v6 dual-layer versioning
- Confirmation dialog when toggling WebDAV auto-sync on/off to prevent accidental changes
- Sync-aware backup: uses a sync-specific backup variant that skips local-only table data
### Usage & Data
Enhanced usage statistics and data maintenance capabilities for finer-grained data management, significantly reducing database growth rate.
- Daily rollups: aggregate usage data by day to reduce storage overhead
- Auto-vacuum: incremental database cleanup to maintain database health
- UsageFooter extra statistics fields (#1137, thanks @bugparty)
### Other New Features
- **Session Deletion**: Per-provider session cleanup with path safety validation
- **Claude Auth Field Selector**: Restored authentication field selector
- **Failover Toggle on Main Page**: Moved the failover toggle to display independently on the main page with a first-use confirmation dialog
- **Common Config Auto-Extract**: On first run, automatically extracts common config snippets from live config files
- **New Provider Page Improvements**: Improved new provider page experience (#1155, thanks @wugeer)
---
## Architecture Improvements
### Common Config Runtime Overlay
Common Config Snippets are now applied as a runtime overlay instead of being materialized into stored provider configs.
**Before**: Common Config content was merged directly into each provider's `settings_config` on save or switch. This caused shared configuration to be duplicated across every provider entry, requiring manual sync when changes were needed.
**After**: Common Config is only injected as a runtime overlay when switching providers and writing to the live file — provider entries themselves no longer contain shared configuration. This means modifying Common Config takes effect immediately without updating each provider individually.
### Common Config Auto-Extract
On first run, if no Common Config Snippet exists in the database, one is automatically extracted from the current live config. This ensures users upgrading from older versions do not lose their existing shared configuration settings.
### Periodic Maintenance Timer Consolidation
Consolidated daily rollups and auto-vacuum into a unified periodic maintenance timer, eliminating resource contention and complexity from multiple independent timers.
---
## Bug Fixes
### Proxy & Streaming
- Fixed OpenAI ChatCompletion -> Anthropic Messages streaming conversion
- Added Codex `/responses/compact` route support (#1194, thanks @Tsukumi233)
- Improved TOML config merge logic to prevent key-value loss
- Improved proxy forwarder failure logs with additional diagnostic information
### Provider & Preset Fixes
- Renamed X-Code to X-Code API for consistent branding
- Fixed SSSAiCode `/v1` path issue
- Removed incorrect `www` prefix from AICoding URLs
- Fixed new provider page line-break deletion issue (#1155, thanks @wugeer)
### Platform Fixes
- Fixed cache hit token statistics not being reported (#1244, thanks @a1398394385)
- Fixed minimize-to-tray causing auto exit after some time (#1245, thanks @YewFence)
### i18n Fixes
- Added 69 missing translation keys and removed remaining hardcoded Chinese strings
- Fixed model test panel i18n issues
- Normalized JSON5 slash escaping to prevent i18n string parsing errors
### UI Fixes
- Fixed Skills count display (#1295, thanks @fzzv)
- Removed HTTP status code display from endpoint speed test to reduce visual noise
- Fixed outline button styling (#1222, thanks @Sube-py)
---
## Performance
- Skip unnecessary OpenClaw config writes when config is unchanged, reducing disk I/O
---
## Documentation
- Restructured the user manual for i18n and added complete EN/JA coverage
- Added OpenClaw usage documentation and completed settings documentation
- Added UCloud sponsor information
- Reorganized the docs directory and synced README feature sections across EN/ZH/JA
---
## Notes & Considerations
- **Common Config now uses runtime overlay**: Common Config Snippets are no longer materialized into each provider's stored config. They are dynamically applied at switch time. Modifying Common Config takes effect immediately without updating each provider.
- **Stream Check requires first-use confirmation**: A confirmation dialog appears when using the model health check for the first time. Testing proceeds only after confirmation.
- **OpenClaw User-Agent toggle defaults to off**: The User-Agent identifier must be manually enabled in the OpenClaw configuration.
---
## Special Thanks
Thanks to all contributors for their contributions to this release!
@keithyt06 @bugparty @Alex-wuhu @suki135246 @Tsukumi233 @wugeer @fzzv @Sube-py @a1398394385 @YewFence
---
## Download & Installation
Visit [Releases](https://github.com/farion1231/cc-switch/releases/latest) to download the appropriate version.
### System Requirements
| System | Minimum Version | Architecture |
| ------- | ------------------------------- | ----------------------------------- |
| Windows | Windows 10 or later | x64 |
| macOS | macOS 10.15 (Catalina) or later | Intel (x64) / Apple Silicon (arm64) |
| Linux | See table below | x64 |
### Windows
| File | Description |
| ---------------------------------------- | ---------------------------------------------------- |
| `CC-Switch-v3.12.0-Windows.msi` | **Recommended** - MSI installer with auto-update |
| `CC-Switch-v3.12.0-Windows-Portable.zip` | Portable version, extract and run, no registry write |
### macOS
| File | Description |
| -------------------------------- | -------------------------------------------------------------------- |
| `CC-Switch-v3.12.0-macOS.zip` | **Recommended** - Extract and drag to Applications, Universal Binary |
| `CC-Switch-v3.12.0-macOS.tar.gz` | For Homebrew installation and auto-update |
> **Note**: Since the author doesn't have an Apple Developer account, you may see an "unidentified developer" warning on first launch. Please close it, then go to "System Settings" -> "Privacy & Security" -> click "Open Anyway", and it will open normally afterwards.
### Homebrew (macOS)
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
Update:
```bash
brew upgrade --cask cc-switch
```
### Linux
| Distribution | Recommended Format | Installation Method |
| --------------------------------------- | ------------------ | ---------------------------------------------------------------------- |
| 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 directly, or use AUR |
| Other distributions / Unsure | `.AppImage` | `chmod +x CC-Switch-*.AppImage && ./CC-Switch-*.AppImage` |
+238
View File
@@ -0,0 +1,238 @@
# CC Switch v3.12.0
> Stream Check が復活し、OpenAI Responses API に対応、OpenClaw と WebDAV も大幅強化
**[中文版 →](v3.12.0-zh.md) | [English →](v3.12.0-en.md)**
---
## 概要
CC Switch v3.12.0 は、プロバイダー互換性、OpenClaw の設定編集、共通設定の使い勝手、同期とデータ保守性を強化する機能リリースです。安定性を強化した **Model Health Check (Stream Check)** UI を復元し、**OpenAI Responses API** 形式変換を追加、**Ucloud**、**Micu**、**X-Code API**、**Novita**、**Bailian For Coding** などのプリセットを拡張し、**WebDAV 同期** に二層バージョニングを導入しました。
**リリース日**: 2026-03-09
**更新規模**: 56 commits | 221 files changed | +20,582 / -8,026 lines
---
## ハイライト
- **Stream Check 復活**: モデルヘルスチェック UI を復元し、初回確認ダイアログを追加、`openai_chat` プロバイダー対応も修正
- **OpenAI Responses API**: `api_format = "openai_responses"` を追加し、双方向変換と共有変換ロジックの整理を実施 — プロバイダー追加時に Responses API フォーマットを選択してプロキシテイクオーバーを有効にするだけで、Claude Code で GPT シリーズモデルが使えます!
- **OpenClaw パネル強化**: JSON5 round-trip 編集、設定ヘルスバナー、改良された Agent Model 選択、User-Agent トグルを導入
- **プリセット拡張**: Ucloud、Micu、X-Code API、Novita、Bailian For Coding を追加・更新し、SiliconFlow partner badge とモデルロールバッジも追加
- **同期と保守の改善**: WebDAV protocol v2 + db-v6、daily rollups、incremental auto-vacuum、sync-aware backup を追加
- **共通設定の使い勝手向上**: 共通設定スニペットを更新すると、プロバイダー切り替え時に自動的に反映されるようになりました。手動でチェックを入れ直す必要はありません
---
## 主な機能
### モデルヘルスチェック (Stream Check)
Stream Check パネルを復元し、プロバイダーの可用性をリアルタイムで検証できるようにしました。
- Stream Check UI パネルを復元し、単一またはバッチでのプロバイダー可用性検出をサポート
- 初回使用確認ダイアログを追加、ヘルスチェック非対応プロバイダーの誤検出によるユーザー混乱を防止
- `openai_chat` API フォーマットプロバイダーの検出互換性を修正
### OpenAI Responses API
新しい `openai_responses` API フォーマットを追加し、OpenAI Responses API を使用するプロバイダーのネイティブサポートを提供します。
- `api_format = "openai_responses"` プロバイダーフォーマットオプションを追加
- Anthropic Messages <-> OpenAI Responses API の双方向フォーマット変換をサポート
- 共有変換ロジックを整理し、重複コードを削減
### Bedrock リクエストオプティマイザー
AWS Bedrock プロバイダー向けに PRE-SEND フェーズのリクエスト最適化を追加し、互換性とパフォーマンスを向上させました。
- PRE-SEND thinking + cache injection オプティマイザー(#1301@keithyt06 に感謝)
### OpenClaw 設定強化
OpenClaw の設定編集体験を全面的にアップグレードし、より豊富な設定管理をサポートします。
- JSON5 round-trip 書き戻し: 編集時にコメントとフォーマットを保持
- EnvPanel の JSON 編集モードと `tools.profile` 選択をサポート
- 設定検証バナーと設定ヘルスステータスチェックを追加
- Agent モデルのドロップダウン改善、プロバイダープリセットから推奨モデルを自動入力
- User-Agent トグル: リクエストに OpenClaw 識別子を付加する機能(デフォルトオフ)
- Legacy timeout 設定の自動マイグレーション
### プロバイダープリセット
新規および既存のプロバイダープリセットを拡張し、より多くのプロバイダーとユースケースをカバーします。
- **Ucloud**: `endpointCandidates` および OpenClaw デフォルト値を追加、`templateValues` / `suggestedDefaults` を更新
- **Micu**: プリセットデフォルト値および OpenClaw 推奨モデルを追加
- **X-Code API**: Claude プリセットおよび `endpointCandidates` を追加
- **Novita**: プロバイダープリセットを追加(#1192@Alex-wuhu に感謝)
- **Bailian For Coding**: プロバイダープリセットを追加(#1263@suki135246 に感謝)
- **SiliconFlow**: partner badge 識別を追加
- **モデルロールバッジ**: プロバイダープリセットでモデルロール badge 表示をサポート
### WebDAV 同期強化
WebDAV 同期に二層バージョン管理を導入し、同期の信頼性とデータ安全性を向上させました。
- WebDAV protocol v2 + db-v6 二層バージョン管理を追加
- WebDAV auto-sync の切り替え時に確認ダイアログを表示し、誤操作を防止
- sync-aware backup: 同期時にローカル専用テーブルを除外した sync バリアントバックアップを使用
### 使用量とデータ
使用量統計とデータ保守機能を強化し、より精密なデータ管理を実現、データベースの増加速度を大幅に抑制します。
- Daily rollups: 日次で使用量データを集計し、ストレージ使用量を削減
- Auto-vacuum: インクリメンタルなデータベースクリーンアップ、データベースの健全性を維持
- UsageFooter に追加統計フィールドを追加(#1137@bugparty に感謝)
### その他の新機能
- **セッション削除**: プロバイダー単位のクリーンアップとパス安全性検証付きのセッション削除
- **Claude auth field selector 復元**: 認証フィールドセレクターを復元
- **Failover トグルをメインページへ移動**: failover toggle を設定パネルからメインページに独立表示し、初回確認ダイアログを追加
- **共通設定の自動抽出**: 初回起動時に live config から共通設定スニペットを自動抽出
- **新規プロバイダーページの改善**: 新規プロバイダーページの体験を最適化(#1155@wugeer に感謝)
---
## アーキテクチャ改善
### Common Config ランタイムオーバーレイ
共通設定スニペット(Common Config Snippet)をランタイムオーバーレイ方式に変更し、保存済みプロバイダー設定への物理マージを廃止しました。
**変更前**: Common Config の内容は保存時または切り替え時に各プロバイダーの `settings_config` に直接マージされていました。これにより共通設定が各プロバイダーエントリーにコピーされ、変更時には一つずつ同期する必要がありました。
**変更後**: Common Config はプロバイダー切り替え時に live ファイルへ書き込む際のみ runtime overlay として注入され、プロバイダーエントリー自体には共通設定を含みません。つまり Common Config の変更は即座に反映され、各プロバイダーを個別に更新する必要はありません。
### Common Config 初回自動抽出
初回起動時にデータベースに Common Config Snippet がまだ存在しない場合、現在の live config から自動抽出します。これにより旧バージョンからアップグレードしたユーザーの既存の共通設定が失われないことを保証します。
### 定期メンテナンスタイマー統合
daily rollups と auto-vacuum を統一の定期メンテナンスタイマーに統合し、複数の独立タイマーによるリソース競合と複雑さを回避しました。
---
## バグ修正
### プロキシとストリーミング
- OpenAI ChatCompletion -> Anthropic Messages のストリーミング変換問題を修正
- Codex `/responses/compact` ルーティングをサポート(#1194@Tsukumi233 に感謝)
- TOML 設定マージロジックを改善し、キー値の欠落を回避
- proxy forwarder の失敗ログを改善し、診断情報を追加
### プロバイダーとプリセットの修正
- X-Code を X-Code API にリネームし、ブランド名称を統一
- SSSAiCode の `/v1` パス問題を修正
- AICoding URL の誤った `www` プレフィックスを削除
- 新規プロバイダーページの改行削除問題を修正(#1155@wugeer に感謝)
### プラットフォーム修正
- cache hit token の統計欠落を修正(#1244@a1398394385 に感謝)
- 最小化後しばらくすると自動終了する問題を修正(#1245@YewFence に感謝)
### i18n 修正
- 69 個の欠落翻訳キーを補完し、残りのハードコード中国語を除去
- model test panel の i18n 問題を修正
- JSON5 slash escaping を正規化し、国際化文字列の解析異常を回避
### UI 修正
- Skills カウント表示の問題を修正(#1295@fzzv に感謝)
- endpoint speed test から HTTP ステータスコード表示を削除し、視覚的ノイズを軽減
- outline button のスタイル問題を修正(#1222@Sube-py に感謝)
---
## パフォーマンス
- OpenClaw 設定が未変更の場合に不要な書き込みをスキップし、ディスク I/O を削減
---
## ドキュメント
- ユーザーマニュアルを i18n 対応で再構成し、EN/JA の内容を拡充
- OpenClaw の説明を追加し、設定ドキュメントを補完
- UCloud スポンサー情報を追加
- docs ディレクトリを再編成し、EN/ZH/JA の README 機能説明を同期
---
## 注意事項
- **Common Config はランタイムオーバーレイに変更**: 共通設定スニペットは各プロバイダー設定への物理マージではなく、切り替え時に動的にオーバーレイされます。Common Config の変更は即座に反映され、各プロバイダーを個別に更新する必要はありません。
- **Stream Check は初回使用時に確認が必要**: 初回使用時にモデルヘルスチェックの確認ダイアログが表示され、確認後に使用可能になります。
- **OpenClaw の User-Agent トグルはデフォルトオフ**: OpenClaw 設定で User-Agent 識別子の付加機能を手動で有効にする必要があります。
---
## 謝辞
以下のコントリビューターの皆様、このリリースへの貢献に感謝します!
@keithyt06 @bugparty @Alex-wuhu @suki135246 @Tsukumi233 @wugeer @fzzv @Sube-py @a1398394385 @YewFence
---
## ダウンロードとインストール
[Releases](https://github.com/farion1231/cc-switch/releases/latest) から適切なバージョンをダウンロードしてください。
### システム要件
| システム | 最小バージョン | アーキテクチャ |
| -------- | -------------------------------- | ----------------------------------- |
| Windows | Windows 10 以降 | x64 |
| macOS | macOS 10.15 (Catalina) 以降 | Intel (x64) / Apple Silicon (arm64) |
| Linux | 下表参照 | x64 |
### Windows
| ファイル | 説明 |
| ---------------------------------------- | ---------------------------------------------------- |
| `CC-Switch-v3.12.0-Windows.msi` | **推奨** - MSI インストーラー、自動更新対応 |
| `CC-Switch-v3.12.0-Windows-Portable.zip` | ポータブル版、解凍して実行、レジストリ書き込みなし |
### macOS
| ファイル | 説明 |
| -------------------------------- | ----------------------------------------------------------------- |
| `CC-Switch-v3.12.0-macOS.zip` | **推奨** - 解凍して Applications にドラッグ、Universal Binary |
| `CC-Switch-v3.12.0-macOS.tar.gz` | Homebrew インストールと自動更新用 |
> **注意**: 作者が Apple Developer アカウントを持っていないため、初回起動時に「開発元を確認できません」という警告が表示される場合があります。一度閉じてから、「システム設定」→「プライバシーとセキュリティ」→「このまま開く」をクリックすると、その後は正常に開けます。
### Homebrew (macOS)
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
| ディストリビューション | 推奨形式 | インストール方法 |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| 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` |
+238
View File
@@ -0,0 +1,238 @@
# CC Switch v3.12.0
> Stream Check 回归,OpenAI Responses API 上线,OpenClaw 与 WebDAV 迎来一次大升级
**[English →](v3.12.0-en.md) | [日本語版 →](v3.12.0-ja.md)**
---
## 概览
CC Switch v3.12.0 是一个功能版本,重点提升供应商兼容性、OpenClaw 配置编辑体验、通用配置功能使用体验,以及同步与数据维护能力。本次恢复了增强稳定性后的 **模型健康检查(Stream Check** UI,新增 **OpenAI Responses API** 格式转换,扩展了 **Ucloud**、**Micu**、**X-Code API**、**Novita**、**Bailian For Coding** 等供应商预设,并为 **WebDAV 同步** 引入双层版本控制。
**发布日期**2026-03-09
**更新规模**56 commits | 221 files changed | +20,582 / -8,026 lines
---
## 重点内容
- **Stream Check 回归**:恢复模型健康检查 UI,新增首次使用确认,并修复 `openai_chat` 供应商检测
- **OpenAI Responses API**:新增 `api_format = "openai_responses"`,支持双向格式转换并整理共享转换逻辑,只需要在添加供应商的时候选择 Response 接口格式并开启代理接管,您就可以在 Claude Code 中使用 gpt 系列模型了!
- **OpenClaw 面板升级**:引入 JSON5 round-trip 配置编辑、配置健康提示、改进后的 Agent Model 选择和 User-Agent 开关
- **预设扩展**:补充 Ucloud、Micu、X-Code API、Novita、Bailian For Coding 预设,并新增 SiliconFlow partner badge 与模型角色标识
- **同步与维护增强**:新增 WebDAV protocol v2 + db-v6 双层版本、daily rollups、增量 auto-vacuum 和 sync-aware backup
- **通用配置功能使用体验优化**:现在通用配置片段更新之后,会在切换供应商时自动同步到新的供应商,不需要再手动勾选。
---
## 主要功能
### 模型健康检查 Stream Check
恢复 Stream Check 面板,用于实时验证供应商可用性,增强供应商管理的可靠性。
- 恢复 Stream Check UI 面板,支持单个或批量检测供应商可用性
- 新增首次使用确认对话框,避免不支持健康检查的供应商报错误导用户
- 修复 `openai_chat` API 格式供应商的检测兼容性
### OpenAI Responses API
新增 `openai_responses` API 格式,为使用 OpenAI Responses API 的供应商提供原生支持。
- 新增 `api_format = "openai_responses"` 供应商格式选项
- 支持 Anthropic Messages <-> OpenAI Responses API 双向格式转换
- 整理共享转换逻辑,减少重复代码
### Bedrock 请求优化器
为 AWS Bedrock 供应商新增 PRE-SEND 阶段请求优化器,提升兼容性和性能。
- PRE-SEND thinking + cache injection 优化器(#1301,感谢 @keithyt06
### OpenClaw 配置增强
OpenClaw 配置编辑体验全面升级,支持更丰富的配置管理。
- JSON5 round-trip 写回:编辑配置时保留注释和格式
- EnvPanel 支持 JSON 编辑模式和 `tools.profile` 选择
- 新增配置校验提示和配置健康状态检查
- Agent 模型下拉框改进,支持从供应商预设填充推荐模型
- User-Agent 开关:可选在请求中附加 User-Agent 标识(默认关闭)
- Legacy timeout 配置自动迁移
### 供应商预设 Preset
新增和扩展多组供应商预设,覆盖更多供应商和使用场景。
- **Ucloud**:新增 `endpointCandidates` 以及 OpenClaw 默认值,刷新 `templateValues` / `suggestedDefaults`
- **Micu**:新增预设默认值及 OpenClaw 推荐模型
- **X-Code API**:新增 Claude 预设及 `endpointCandidates`
- **Novita**:新增供应商预设(#1192,感谢 @Alex-wuhu
- **Bailian For Coding**:新增供应商预设(#1263,感谢 @suki135246
- **SiliconFlow**:新增 partner badge 标识
- **模型角色标识**:供应商预设支持模型角色 badge 显示
### WebDAV 同步增强
WebDAV 同步引入双层版本控制,提升同步可靠性和数据安全性。
- 新增 WebDAV protocol v2 + db-v6 双层版本控制
- 切换 WebDAV auto-sync 时弹出确认对话框,防止误操作
- sync-aware backupWebDAV 同步时使用 sync 变体备份,跳过仅本地使用的表数据
### 用量与数据
用量统计和数据维护能力增强,数据管理更精细,极大降低数据库增长速度。
- Daily rollups:按天汇总用量数据,减少存储占用
- Auto-vacuum:增量式数据库清理,保持数据库健康
- UsageFooter 新增额外统计字段(#1137,感谢 @bugparty
### 其他新功能
- **会话删除**:按供应商清理会话记录,带路径安全校验
- **Claude auth field selector 恢复**:恢复认证字段选择器
- **Failover 开关独立显示**:将 failover toggle 从设置面板移到主页独立展示,并新增首次确认对话框
- **通用配置自动抽取**:首次运行时自动从 live config 中抽取通用配置片段
- **新供应商页面改进**:优化新建供应商页面体验(#1155,感谢 @wugeer
---
## 架构改进
### Common Config 运行时叠加
通用配置片段(Common Config Snippet)改为运行时叠加方式应用,不再物化写入每个供应商配置。
**变更前**Common Config 内容在保存或切换时直接合并写入每个供应商的 `settings_config`。这导致公共配置被复制到每个供应商条目中,修改时需要逐一同步。
**变更后**Common Config 仅在切换供应商写入 live 文件时以 runtime overlay 方式注入,供应商条目本身不包含公共配置。这意味着修改 Common Config 后立即生效,无需逐一更新每个供应商。
### 通用配置首次自动抽取
首次运行时,如果数据库中尚无 Common Config Snippet,会自动从当前 live config 中抽取通用配置。这确保了从旧版本升级的用户不会丢失已有的通用配置设置。
### 定期维护定时器整合
将 daily rollups 和 auto-vacuum 整合到统一的定期维护定时器中,避免多个独立定时器带来的资源竞争和复杂度。
---
## Bug 修复
### 代理与流式转换
- 修复 OpenAI ChatCompletion -> Anthropic Messages 流式转换问题
- 新增 Codex `/responses/compact` 路由支持(#1194,感谢 @Tsukumi233
- 改进 TOML 配置合并逻辑,避免键值丢失
- 改进 proxy forwarder 失败日志,增加更多诊断信息
### 供应商预设修复
- X-Code 更名为 X-Code API,统一品牌命名
- 修复 SSSAiCode `/v1` 路径问题
- 移除 AICoding URL 错误的 `www` 前缀
- 优化新建供应商页面换行删除问题(#1155,感谢 @wugeer
### 平台修复
- 修复 cache hit token 统计缺失(#1244,感谢 @a1398394385
- 修复最小化到托盘后一段时间自动退出的问题(#1245,感谢 @YewFence
### i18n 修复
- 补齐 69 个缺失翻译 key,清理剩余硬编码中文
- 修复 model test panel 的 i18n 问题
- 规范 JSON5 slash escaping,避免国际化字符串解析异常
### UI 修复
- 修复 Skills 计数显示问题(#1295,感谢 @fzzv
- 移除 endpoint speed test 的 HTTP 状态码显示,减少视觉噪音
- 修复 outline button 样式问题(#1222,感谢 @Sube-py
---
## 性能优化
- OpenClaw 配置未变化时跳过无意义写入,减少磁盘 I/O
---
## 文档
- 重构用户手册以支持国际化,补齐 EN/JA 完整内容
- 新增 OpenClaw 使用说明,补完设置章节
- 新增 UCloud 赞助商信息
- 重组 docs 目录结构,同步 EN/ZH/JA README 的功能说明
---
## 说明与注意事项
- **Common Config 改为运行时叠加**:通用配置片段不再物化写入每个供应商配置,而是在切换时动态叠加。修改 Common Config 后立即生效,无需逐一更新供应商。
- **Stream Check 首次使用需确认**:首次使用模型健康检查时会弹出确认对话框,确认后方可使用。
- **OpenClaw User-Agent 开关默认关闭**:需要在 OpenClaw 配置中手动开启 User-Agent 标识附加功能。
---
## 特别感谢
感谢以下贡献者为本版本做出的贡献!
@keithyt06 @bugparty @Alex-wuhu @suki135246 @Tsukumi233 @wugeer @fzzv @Sube-py @a1398394385 @YewFence
---
## 下载与安装
访问 [Releases](https://github.com/farion1231/cc-switch/releases/latest) 下载对应版本。
### 系统要求
| 系统 | 最低版本 | 架构 |
| ------- | ----------------------------- | ----------------------------------- |
| Windows | Windows 10 及以上 | x64 |
| macOS | macOS 10.15 (Catalina) 及以上 | Intel (x64) / Apple Silicon (arm64) |
| Linux | 见下表 | x64 |
### Windows
| 文件 | 说明 |
| ---------------------------------------- | ----------------------------------- |
| `CC-Switch-v3.12.0-Windows.msi` | **推荐** - MSI 安装包,支持自动更新 |
| `CC-Switch-v3.12.0-Windows-Portable.zip` | 便携版,解压即用,不写入注册表 |
### macOS
| 文件 | 说明 |
| -------------------------------- | --------------------------------------------------------- |
| `CC-Switch-v3.12.0-macOS.zip` | **推荐** - 解压后拖入 Applications 即可,Universal Binary |
| `CC-Switch-v3.12.0-macOS.tar.gz` | 用于 Homebrew 安装和自动更新 |
> **注意**:由于作者没有苹果开发者账号,首次打开可能出现"未知开发者"警告,请先关闭,然后前往"系统设置" → "隐私与安全性" → 点击"仍要打开",之后便可以正常打开
### HomebrewmacOS
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
| 发行版 | 推荐格式 | 安装方式 |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| 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` |
+146
View File
@@ -0,0 +1,146 @@
# CC Switch v3.12.1
> Stability Fixes, StepFun Presets, OpenClaw authHeader, and New Sponsor Partners
**[中文版 →](v3.12.1-zh.md) | [日本語版 →](v3.12.1-ja.md)**
---
## Overview
CC Switch v3.12.1 is a patch release focused on stability improvements and bug fixes. It resolves a Common Config modal infinite reopen loop, a WebDAV sync foreign key constraint failure, and several i18n interpolation issues. It also adds **StepFun** provider presets, **OpenClaw input type selection** and **authHeader** support, upgrades the default Gemini model to **3.1-pro**, and welcomes four new sponsor partners.
**Release Date**: 2026-03-12
**Update Scale**: 19 commits | 56 files changed | +1,429 / -396 lines
---
## Highlights
- **Common Config modal fix**: Resolved an infinite reopen loop in the Common Config modal and added draft editing support
- **WebDAV sync reliability**: Fixed a foreign key constraint failure when restoring `provider_health` during WebDAV sync
- **StepFun presets**: Added StepFun (阶跃星辰) provider presets including the step-3.5-flash model
- **OpenClaw enhancements**: Added input type selection for model Advanced Options and `authHeader` field for vendor-specific auth header support
- **Gemini model upgrade**: Upgraded default Gemini model to 3.1-pro in provider presets
- **New sponsors**: Welcomed Micu API, XCodeAPI, SiliconFlow, and CTok as sponsor partners
---
## New Features
### StepFun Provider Presets
Added provider presets for StepFun (阶跃星辰), a leading Chinese AI model provider.
- New preset entries for StepFun across supported applications
- Includes the step-3.5-flash model (#1369, thanks @hengm3467)
### OpenClaw Enhancements
Enhanced the OpenClaw configuration with more granular control and better vendor compatibility.
- Added input type selection dropdown for model Advanced Options (#1368, thanks @liuxxxu)
- Added optional `authHeader` boolean to `OpenClawProviderConfig` for vendor-specific auth header support (e.g. Longcat), and refactored form state to reuse the shared type
### Sponsor Partners
- **Micu API**: Added Micu API as sponsor partner with affiliate links
- **XCodeAPI**: Added XCodeAPI as sponsor partner
- **SiliconFlow**: Added SiliconFlow (硅基流动) as sponsor partner with affiliate links
- **CTok**: Added CTok as sponsor partner
---
## Changes
- **UCloud → Compshare**: Renamed UCloud provider to Compshare (优云智算) with full i18n support across all three locales (EN/ZH/JA)
- **Compshare Links**: Updated Compshare sponsor registration links to coding-plan page
- **Gemini Model Upgrade**: Upgraded default Gemini model from 2.5-pro to 3.1-pro in provider presets
---
## Bug Fixes
### Common Config & UI
- Fixed an infinite reopen loop in the Common Config modal and added draft editing support to prevent data loss during edits
- Fixed toolbar compact mode not triggering on Windows due to left-side overflow (#1375, thanks @zuoliangyu)
- Fixed session search index not syncing with query data, causing stale list display after session deletion
### Sync & Data
- Fixed foreign key constraint failure when restoring `provider_health` table during WebDAV sync
### Provider & Preset
- Added missing `authHeader: true` to Longcat provider preset (#1377, thanks @wavever)
- Aligned OpenClaw tool permission profiles with upstream schema (#1355, thanks @bigsongeth)
- Corrected X-Code API URL from `www.x-code.cn` to `x-code.cc`
### i18n & Localization
- Fixed stream check toast i18n interpolation keys not matching translation placeholders
- Fixed proxy startup toast not interpolating address and port values (#1399, thanks @Mason-mengze)
- Renamed OpenCode API format label from "OpenAI" to "OpenAI Responses" for accuracy
---
## Special Thanks
Thanks to all contributors for their contributions to this release!
@hengm3467 @liuxxxu @bigsongeth @zuoliangyu @wavever @Mason-mengze
---
## Download & Installation
Visit [Releases](https://github.com/farion1231/cc-switch/releases/latest) to download the appropriate version.
### System Requirements
| System | Minimum Version | Architecture |
| ------- | ------------------------------- | ----------------------------------- |
| Windows | Windows 10 or later | x64 |
| macOS | macOS 10.15 (Catalina) or later | Intel (x64) / Apple Silicon (arm64) |
| Linux | See table below | x64 |
### Windows
| File | Description |
| ------------------------------------------ | ---------------------------------------------------- |
| `CC-Switch-v3.12.1-Windows.msi` | **Recommended** - MSI installer with auto-update |
| `CC-Switch-v3.12.1-Windows-Portable.zip` | Portable version, extract and run, no registry write |
### macOS
| File | Description |
| ---------------------------------- | -------------------------------------------------------------------- |
| `CC-Switch-v3.12.1-macOS.zip` | **Recommended** - Extract and drag to Applications, Universal Binary |
| `CC-Switch-v3.12.1-macOS.tar.gz` | For Homebrew installation and auto-update |
> **Note**: Since the author doesn't have an Apple Developer account, you may see an "unidentified developer" warning on first launch. Please close it, then go to "System Settings" -> "Privacy & Security" -> click "Open Anyway", and it will open normally afterwards.
### Homebrew (macOS)
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
Update:
```bash
brew upgrade --cask cc-switch
```
### Linux
| Distribution | Recommended Format | Installation Method |
| --------------------------------------- | ------------------ | ---------------------------------------------------------------------- |
| 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 directly, or use AUR |
| Other distributions / Unsure | `.AppImage` | `chmod +x CC-Switch-*.AppImage && ./CC-Switch-*.AppImage` |
+146
View File
@@ -0,0 +1,146 @@
# CC Switch v3.12.1
> 安定性修正、StepFun プリセット、OpenClaw authHeader 対応、新スポンサーパートナー
**[中文版 →](v3.12.1-zh.md) | [English →](v3.12.1-en.md)**
---
## 概要
CC Switch v3.12.1 は、安定性の改善とバグ修正に焦点を当てたパッチリリースです。共通設定モーダルの無限再オープンループ、WebDAV 同期時の外部キー制約エラー、複数の i18n 補間問題を修正しました。また、**StepFun(阶跃星辰)** プロバイダープリセットの追加、OpenClaw の**入力タイプ選択**と **authHeader** サポート、デフォルト Gemini モデルの **3.1-pro** へのアップグレード、4 つの新スポンサーパートナーの追加が含まれます。
**リリース日**: 2026-03-12
**更新規模**: 19 commits | 56 files changed | +1,429 / -396 lines
---
## ハイライト
- **共通設定モーダル修正**: 共通設定モーダルの無限再オープンループを解決し、下書き編集サポートを追加
- **WebDAV 同期の信頼性向上**: WebDAV 同期で `provider_health` 復元時の外部キー制約エラーを修正
- **StepFun プリセット**: StepFun(阶跃星辰)プロバイダープリセットを追加、step-3.5-flash モデルを含む
- **OpenClaw 強化**: モデル詳細設定に入力タイプ選択を追加、ベンダー固有の認証ヘッダーサポート用 `authHeader` フィールドを追加
- **Gemini モデルアップグレード**: プロバイダープリセットのデフォルト Gemini モデルを 3.1-pro にアップグレード
- **新スポンサー**: Micu API、XCodeAPI、SiliconFlow、CTok をスポンサーパートナーとして追加
---
## 新機能
### StepFun プロバイダープリセット
中国の主要 AI モデルプロバイダーである StepFun(阶跃星辰)のプロバイダープリセットを追加しました。
- サポート対象アプリケーション全体に StepFun プリセットエントリーを追加
- step-3.5-flash モデルを含む(#1369@hengm3467 に感謝)
### OpenClaw 強化
OpenClaw 設定をより細かく制御でき、ベンダー互換性を向上させました。
- モデル詳細設定に入力タイプ(input type)選択ドロップダウンを追加(#1368@liuxxxu に感謝)
- `OpenClawProviderConfig` にオプションの `authHeader` ブール値を追加し、ベンダー固有の認証ヘッダー(例: Longcat)をサポート。フォーム状態を共有型の再利用にリファクタリング
### スポンサーパートナー
- **Micu API**: Micu API をスポンサーパートナーとして追加、アフィリエイトリンク付き
- **XCodeAPI**: XCodeAPI をスポンサーパートナーとして追加
- **SiliconFlow**: SiliconFlow(硅基流动)をスポンサーパートナーとして追加、アフィリエイトリンク付き
- **CTok**: CTok をスポンサーパートナーとして追加
---
## 変更
- **UCloud → Compshare**: UCloud プロバイダーを Compshare(优云智算)にリネームし、3 言語(EN/ZH/JA)の完全な i18n サポートを追加
- **Compshare リンク**: Compshare スポンサー登録リンクを coding-plan ページに更新
- **Gemini モデルアップグレード**: プロバイダープリセットのデフォルト Gemini モデルを 2.5-pro から 3.1-pro にアップグレード
---
## バグ修正
### 共通設定と UI
- 共通設定モーダルの無限再オープンループを修正し、編集中のデータ損失を防ぐための下書き編集サポートを追加
- Windows でツールバーコンパクトモードが左側のオーバーフローにより機能しない問題を修正(#1375@zuoliangyu に感謝)
- セッション削除後にクエリデータと検索インデックスが同期されず、リストが更新されない問題を修正
### 同期とデータ
- WebDAV 同期で `provider_health` テーブルを復元する際の外部キー制約エラーを修正
### プロバイダーとプリセット
- Longcat プロバイダープリセットに欠落していた `authHeader: true` を追加(#1377@wavever に感謝)
- OpenClaw のツール権限プロファイルをアップストリームスキーマに合わせて修正(#1355@bigsongeth に感謝)
- X-Code API の URL を `www.x-code.cn` から `x-code.cc` に修正
### i18n とローカリゼーション
- Stream Check トーストの i18n 補間キーが翻訳プレースホルダーと一致しない問題を修正
- プロキシ起動トーストでアドレスとポート値が補間されない問題を修正(#1399@Mason-mengze に感謝)
- OpenCode の API フォーマットラベルを「OpenAI」から「OpenAI Responses」にリネームし、正確性を向上
---
## 謝辞
以下のコントリビューターの皆様、このリリースへの貢献に感謝します!
@hengm3467 @liuxxxu @bigsongeth @zuoliangyu @wavever @Mason-mengze
---
## ダウンロードとインストール
[Releases](https://github.com/farion1231/cc-switch/releases/latest) から適切なバージョンをダウンロードしてください。
### システム要件
| システム | 最小バージョン | アーキテクチャ |
| -------- | -------------------------------- | ----------------------------------- |
| Windows | Windows 10 以降 | x64 |
| macOS | macOS 10.15 (Catalina) 以降 | Intel (x64) / Apple Silicon (arm64) |
| Linux | 下表参照 | x64 |
### Windows
| ファイル | 説明 |
| ------------------------------------------ | ---------------------------------------------------- |
| `CC-Switch-v3.12.1-Windows.msi` | **推奨** - MSI インストーラー、自動更新対応 |
| `CC-Switch-v3.12.1-Windows-Portable.zip` | ポータブル版、解凍して実行、レジストリ書き込みなし |
### macOS
| ファイル | 説明 |
| ---------------------------------- | ----------------------------------------------------------------- |
| `CC-Switch-v3.12.1-macOS.zip` | **推奨** - 解凍して Applications にドラッグ、Universal Binary |
| `CC-Switch-v3.12.1-macOS.tar.gz` | Homebrew インストールと自動更新用 |
> **注意**: 作者が Apple Developer アカウントを持っていないため、初回起動時に「開発元を確認できません」という警告が表示される場合があります。一度閉じてから、「システム設定」→「プライバシーとセキュリティ」→「このまま開く」をクリックすると、その後は正常に開けます。
### Homebrew (macOS)
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
| ディストリビューション | 推奨形式 | インストール方法 |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| 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` |
+146
View File
@@ -0,0 +1,146 @@
# CC Switch v3.12.1
> 稳定性修复、StepFun 预设、OpenClaw authHeader 支持,以及新赞助商伙伴
**[English →](v3.12.1-en.md) | [日本語版 →](v3.12.1-ja.md)**
---
## 概览
CC Switch v3.12.1 是一个以稳定性改进和 Bug 修复为主的补丁版本。修复了通用配置弹窗无限重复打开的循环问题、WebDAV 同步时的外键约束失败以及多个 i18n 插值问题。同时新增了 **StepFun(阶跃星辰)** 供应商预设、OpenClaw **输入类型选择****authHeader** 支持,将默认 Gemini 模型升级到 **3.1-pro**,并欢迎四位新赞助商伙伴加入。
**发布日期**2026-03-12
**更新规模**19 commits | 56 files changed | +1,429 / -396 lines
---
## 重点内容
- **通用配置弹窗修复**:解决了通用配置弹窗无限重复打开的循环问题,并新增草稿编辑支持
- **WebDAV 同步可靠性**:修复了 WebDAV 同步恢复 `provider_health` 时的外键约束失败
- **StepFun 预设**:新增 StepFun(阶跃星辰)供应商预设,包含 step-3.5-flash 模型
- **OpenClaw 增强**:新增模型高级选项的输入类型选择和 `authHeader` 字段,支持供应商特定的认证头
- **Gemini 模型升级**:供应商预设中的默认 Gemini 模型升级到 3.1-pro
- **新赞助商**:欢迎 Micu API、XCodeAPI、SiliconFlow、CTok 加入赞助伙伴
---
## 新功能
### StepFun 供应商预设
新增 StepFun(阶跃星辰)供应商预设,阶跃星辰是领先的中国 AI 模型提供商。
- 在各支持应用中新增 StepFun 预设条目
- 包含 step-3.5-flash 模型(#1369,感谢 @hengm3467
### OpenClaw 增强
增强 OpenClaw 配置能力,提供更细粒度的控制和更好的供应商兼容性。
- 新增模型高级选项的输入类型(input type)选择下拉框(#1368,感谢 @liuxxxu
-`OpenClawProviderConfig` 中新增可选的 `authHeader` 布尔字段,支持供应商特定的认证头(如 Longcat),并重构表单状态以复用共享类型
### 赞助商伙伴
- **Micu API**:新增 Micu API 赞助商及推广链接
- **XCodeAPI**:新增 XCodeAPI 赞助商
- **SiliconFlow**:新增 SiliconFlow(硅基流动)赞助商及推广链接
- **CTok**:新增 CTok 赞助商
---
## 变更
- **UCloud → Compshare**:将 UCloud 供应商更名为 Compshare(优云智算),支持三种语言(中/英/日)的完整国际化
- **Compshare 链接**:更新 Compshare 赞助商注册链接指向 coding-plan 页面
- **Gemini 模型升级**:供应商预设中的默认 Gemini 模型从 2.5-pro 升级到 3.1-pro
---
## Bug 修复
### 通用配置与 UI
- 修复通用配置弹窗无限重复打开的循环问题,并新增草稿编辑支持以防止编辑过程中数据丢失
- 修复 Windows 下因左侧溢出导致工具栏紧凑模式不触发的问题(#1375,感谢 @zuoliangyu
- 修复会话删除后搜索索引未与查询数据同步,导致列表显示过期的问题
### 同步与数据
- 修复 WebDAV 同步恢复 `provider_health` 表时的外键约束失败
### 供应商与预设
- 为 Longcat 供应商预设补充缺失的 `authHeader: true`#1377,感谢 @wavever
- 对齐 OpenClaw 工具权限配置与上游 schema(#1355,感谢 @bigsongeth
- 修正 X-Code API URL,从 `www.x-code.cn` 改为 `x-code.cc`
### i18n 与本地化
- 修复 Stream Check Toast 的 i18n 插值 key 与翻译占位符不匹配
- 修复代理启动 Toast 未正确插值地址和端口的问题(#1399,感谢 @Mason-mengze
- 将 OpenCode API 格式标签从 "OpenAI" 改为 "OpenAI Responses",更准确地反映实际格式
---
## 特别感谢
感谢以下贡献者为本版本做出的贡献!
@hengm3467 @liuxxxu @bigsongeth @zuoliangyu @wavever @Mason-mengze
---
## 下载与安装
访问 [Releases](https://github.com/farion1231/cc-switch/releases/latest) 下载对应版本。
### 系统要求
| 系统 | 最低版本 | 架构 |
| ------- | ----------------------------- | ----------------------------------- |
| Windows | Windows 10 及以上 | x64 |
| macOS | macOS 10.15 (Catalina) 及以上 | Intel (x64) / Apple Silicon (arm64) |
| Linux | 见下表 | x64 |
### Windows
| 文件 | 说明 |
| ------------------------------------------ | ----------------------------------- |
| `CC-Switch-v3.12.1-Windows.msi` | **推荐** - MSI 安装包,支持自动更新 |
| `CC-Switch-v3.12.1-Windows-Portable.zip` | 便携版,解压即用,不写入注册表 |
### macOS
| 文件 | 说明 |
| ---------------------------------- | --------------------------------------------------------- |
| `CC-Switch-v3.12.1-macOS.zip` | **推荐** - 解压后拖入 Applications 即可,Universal Binary |
| `CC-Switch-v3.12.1-macOS.tar.gz` | 用于 Homebrew 安装和自动更新 |
> **注意**:由于作者没有苹果开发者账号,首次打开可能出现"未知开发者"警告,请先关闭,然后前往"系统设置" → "隐私与安全性" → 点击"仍要打开",之后便可以正常打开
### HomebrewmacOS
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
| 发行版 | 推荐格式 | 安装方式 |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| 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` |
+138
View File
@@ -0,0 +1,138 @@
# CC Switch v3.12.2
> Common Config Protection During Proxy Takeover, Snippet Lifecycle Stability, Section-Aware Codex TOML Editing
**[中文版 →](v3.12.2-zh.md) | [日本語版 →](v3.12.2-ja.md)**
---
## Overview
CC Switch v3.12.2 is a reliability-focused patch release that addresses Common Config loss during proxy takeover and improves Codex TOML editing accuracy. Proxy takeover hot-switches and provider sync now update the restore backup instead of overwriting live config files; the startup sequence has been reordered so snippets are extracted from clean live files before takeover state is restored; and Codex `base_url` editing has been refactored into a section-aware model that no longer appends to the end of the file.
**Release Date**: 2026-03-12
**Update Scale**: 5 commits | 22 files changed | +1,716 / -288 lines
---
## Highlights
- **Empty state guidance**: Provider list empty state now shows detailed import instructions with a conditional Common Config snippet hint for Claude/Codex/Gemini
- **Proxy takeover restore flow rework**: Hot-switches and provider sync now refresh the restore backup instead of overwriting live config files, preserving the full user configuration on rollback
- **Snippet lifecycle stability**: Introduced a `cleared` flag to prevent auto-extraction from resurrecting cleared snippets, and reordered startup to extract from clean state
- **Section-aware Codex TOML editing**: `base_url` and `model` field reads/writes now target the correct `[model_providers.<name>]` section
- **Codex MCP config protection**: Existing `mcp_servers` blocks in restore snapshots survive provider hot-switches via per-server-id merge instead of wholesale replacement, with provider/common-config definitions winning on conflict
---
## New Features
### Empty State Guidance
Improved the first-run experience with helpful guidance when the provider list is empty.
- Empty state page shows step-by-step import instructions
- Conditionally displays a Common Config snippet hint for Claude/Codex/Gemini providers (not shown for OpenCode/OpenClaw)
---
## Changes
### Proxy Takeover Restore Flow
The proxy takeover hot-switch and provider sync logic has been reworked to protect Common Config throughout the takeover lifecycle.
- Provider sync now updates the restore backup instead of writing directly to live config files when takeover is active
- Effective provider settings are rebuilt with Common Config applied before saving restore snapshots, so rollback restores the real user configuration
- Legacy providers with inferred common config usage are automatically marked with `commonConfigEnabled=true`
### Codex TOML Editing Engine
Codex `config.toml` update logic has been refactored onto shared section-aware TOML helpers.
- New Rust module `codex_config.rs` with `update_codex_toml_field` and `remove_codex_toml_base_url_if`
- New frontend utilities `getTomlSectionRange` / `getCodexProviderSectionName` for section-aware operations
- Inline TOML editing logic scattered across `proxy.rs` now delegates to the new module
### Common Config Initialization Lifecycle
The startup sequence has been reordered for more robust snippet extraction and migration.
- Startup now auto-extracts Common Config snippets from clean live files before restoring proxy takeover state
- Introduced a snippet `cleared` flag to track whether a user intentionally cleared a snippet
- Persisted a one-time legacy migration flag to avoid repeated `commonConfigEnabled` backfills
---
## Bug Fixes
### Common Config Loss
- Fixed multiple scenarios where Common Config could be dropped during proxy takeover: sync overwriting live files, hot-switches producing incomplete restore snapshots, and provider switches losing config changes
### Codex Restore Snapshot Preservation
- Fixed Codex takeover restore backups discarding existing `mcp_servers` blocks during provider hot-switches; changed MCP backup preservation from wholesale table replacement to per-server-id merge so provider/common-config MCP updates win on conflict while backup-only servers are retained
### Cleared Snippet Resurrection
- Fixed startup auto-extraction recreating Common Config snippets that users had intentionally cleared
### Codex `base_url` Misplacement
- Fixed Codex `base_url` extraction and editing not targeting the correct `[model_providers.<name>]` section, causing it to append to the file tail or confuse `mcp_servers.*.base_url` entries for provider endpoints
---
## Download & Installation
Visit [Releases](https://github.com/farion1231/cc-switch/releases/latest) to download the appropriate version.
### System Requirements
| System | Minimum Version | Architecture |
| ------- | ------------------------------- | ----------------------------------- |
| Windows | Windows 10 or later | x64 |
| macOS | macOS 10.15 (Catalina) or later | Intel (x64) / Apple Silicon (arm64) |
| Linux | See table below | x64 |
### Windows
| File | Description |
| ------------------------------------------ | ---------------------------------------------------- |
| `CC-Switch-v3.12.2-Windows.msi` | **Recommended** - MSI installer with auto-update |
| `CC-Switch-v3.12.2-Windows-Portable.zip` | Portable version, extract and run, no registry write |
### macOS
| File | Description |
| ---------------------------------- | -------------------------------------------------------------------- |
| `CC-Switch-v3.12.2-macOS.zip` | **Recommended** - Extract and drag to Applications, Universal Binary |
| `CC-Switch-v3.12.2-macOS.tar.gz` | For Homebrew installation and auto-update |
> **Note**: Since the author doesn't have an Apple Developer account, you may see an "unidentified developer" warning on first launch. Please close it, then go to "System Settings" -> "Privacy & Security" -> click "Open Anyway", and it will open normally afterwards.
### Homebrew (macOS)
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
Update:
```bash
brew upgrade --cask cc-switch
```
### Linux
| Distribution | Recommended Format | Installation Method |
| --------------------------------------- | ------------------ | ---------------------------------------------------------------------- |
| 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 directly, or use AUR |
| Other distributions / Unsure | `.AppImage` | `chmod +x CC-Switch-*.AppImage && ./CC-Switch-*.AppImage` |
+138
View File
@@ -0,0 +1,138 @@
# CC Switch v3.12.2
> プロキシテイクオーバー中の共通設定保護、Snippet ライフサイクルの安定化、Codex TOML セクション対応編集
**[中文版 →](v3.12.2-zh.md) | [English →](v3.12.2-en.md)**
---
## 概要
CC Switch v3.12.2 は、信頼性を重視したパッチリリースです。プロキシテイクオーバーモードでの共通設定(Common Config)の消失問題を解決し、Codex TOML 設定の編集精度を改善しました。テイクオーバーのホットスイッチとプロバイダー同期は、ライブ設定ファイルを上書きする代わりにリストアバックアップを更新するようになりました。起動シーケンスを再整理し、テイクオーバー状態を復元する前にクリーンなライブファイルから Snippet を抽出するようにしました。また Codex の `base_url` 編集をセクション対応モデルにリファクタリングし、ファイル末尾への誤追加を防止しました。
**リリース日**: 2026-03-12
**更新規模**: 5 commits | 22 files changed | +1,716 / -288 lines
---
## ハイライト
- **空状態ガイダンスの改善**: プロバイダーリストが空の場合に詳細なインポート手順を表示し、Claude/Codex/Gemini には共通設定 Snippet のヒントを条件付きで表示
- **プロキシテイクオーバーリストアフロー刷新**: ホットスイッチとプロバイダー同期がライブ設定ファイルの上書きではなくリストアバックアップの更新を行うようになり、ロールバック時に完全なユーザー設定を保持
- **Snippet ライフサイクルの安定化**: `cleared` フラグを導入し、クリア済み Snippet の自動再抽出を防止。起動順序を調整してクリーンな状態から抽出
- **Codex TOML セクション対応編集**: `base_url``model` フィールドの読み書きが正しい `[model_providers.<name>]` セクションを対象にするように改善
- **Codex MCP 設定の保護**: プロバイダーホットスイッチ時にリストアスナップショット内の既存 `mcp_servers` ブロックが保持されるように修正。テーブル全体の置換からサーバー ID ごとのマージに変更し、プロバイダー/共通設定の MCP 定義が競合時に優先
---
## 新機能
### 空状態ガイダンスの改善
プロバイダーリストが空の場合の初回利用体験を改善しました。
- 空状態ページにプロバイダーインポートの操作ガイドを表示
- Claude/Codex/Gemini アプリケーションに共通設定 Snippet のヒントを条件付きで表示(OpenCode/OpenClaw には非表示)
---
## 変更
### プロキシテイクオーバーリストアフロー
テイクオーバーのホットスイッチとプロバイダー同期ロジックをリファクタリングし、テイクオーバーライフサイクル全体で共通設定を保護します。
- テイクオーバーがアクティブな場合、プロバイダー同期がライブ設定ファイルへの直接書き込みではなくリストアバックアップを更新
- リストアスナップショットの保存前に共通設定を適用した実効プロバイダー設定を再構築し、ロールバックで実際のユーザー設定を復元
- 共通設定の使用が推測されるレガシープロバイダーに `commonConfigEnabled=true` を自動マーク
### Codex TOML 編集エンジン
Codex `config.toml` の更新ロジックを共有のセクション対応 TOML ヘルパーにリファクタリングしました。
- Rust 側に新モジュール `codex_config.rs` を追加(`update_codex_toml_field``remove_codex_toml_base_url_if`
- フロントエンドにセクション対応ユーティリティ `getTomlSectionRange` / `getCodexProviderSectionName` を追加
- `proxy.rs` に散在していたインライン TOML 編集ロジックを新モジュールに委譲
### 共通設定初期化ライフサイクル
Snippet の抽出とマイグレーションをより堅牢にするため、起動シーケンスを再整理しました。
- 起動時にプロキシテイクオーバー状態を復元する前に、クリーンなライブファイルから共通設定 Snippet を自動抽出
- Snippet の `cleared` フラグを導入し、ユーザーが意図的にクリアしたかどうかを追跡
- 一回限りのレガシーマイグレーションフラグを永続化し、`commonConfigEnabled` のバックフィルの繰り返しを防止
---
## バグ修正
### 共通設定の消失
- プロキシテイクオーバー中に共通設定が消失する複数のシナリオを修正:同期によるライブファイルの上書き、ホットスイッチによる不完全なリストアスナップショット、プロバイダー切り替え時の設定変更の消失
### Codex リストアスナップショットの保護
- プロバイダーホットスイッチ時に Codex テイクオーバーリストアバックアップが既存の `mcp_servers` ブロックを破棄する問題を修正。MCP バックアップ保持をテーブル全体の置換からサーバー ID ごとのマージに変更し、プロバイダー/共通設定の MCP 更新が競合時に優先され、バックアップのみのサーバーも保持
### クリア済み Snippet の復活
- 起動時の自動抽出が、ユーザーが意図的にクリアした共通設定 Snippet を再作成する問題を修正
### Codex `base_url` の配置エラー
- Codex `base_url` の抽出と編集が正しい `[model_providers.<name>]` セクションを対象にせず、ファイル末尾に追加されたり `mcp_servers.*.base_url` をプロバイダーエンドポイントと誤認する問題を修正
---
## ダウンロードとインストール
[Releases](https://github.com/farion1231/cc-switch/releases/latest) から適切なバージョンをダウンロードしてください。
### システム要件
| システム | 最小バージョン | アーキテクチャ |
| -------- | -------------------------------- | ----------------------------------- |
| Windows | Windows 10 以降 | x64 |
| macOS | macOS 10.15 (Catalina) 以降 | Intel (x64) / Apple Silicon (arm64) |
| Linux | 下表参照 | x64 |
### Windows
| ファイル | 説明 |
| ------------------------------------------ | ---------------------------------------------------- |
| `CC-Switch-v3.12.2-Windows.msi` | **推奨** - MSI インストーラー、自動更新対応 |
| `CC-Switch-v3.12.2-Windows-Portable.zip` | ポータブル版、解凍して実行、レジストリ書き込みなし |
### macOS
| ファイル | 説明 |
| ---------------------------------- | ----------------------------------------------------------------- |
| `CC-Switch-v3.12.2-macOS.zip` | **推奨** - 解凍して Applications にドラッグ、Universal Binary |
| `CC-Switch-v3.12.2-macOS.tar.gz` | Homebrew インストールと自動更新用 |
> **注意**: 作者が Apple Developer アカウントを持っていないため、初回起動時に「開発元を確認できません」という警告が表示される場合があります。一度閉じてから、「システム設定」→「プライバシーとセキュリティ」→「このまま開く」をクリックすると、その後は正常に開けます。
### Homebrew (macOS)
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
| ディストリビューション | 推奨形式 | インストール方法 |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| 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` |
+138
View File
@@ -0,0 +1,138 @@
# CC Switch v3.12.2
> 代理接管期间通用配置保护、Snippet 生命周期稳定性、Codex TOML Section 感知编辑
**[English →](v3.12.2-en.md) | [日本語版 →](v3.12.2-ja.md)**
---
## 概览
CC Switch v3.12.2 是一个以可靠性为核心的补丁版本,重点解决代理(Proxy)接管模式下通用配置(Common Config)丢失的问题,并改进了 Codex TOML 配置的编辑准确性。代理接管的热切换和供应商同步现在会更新恢复备份而非直接覆盖 live 文件;启动流程重新排序,确保先从干净的 live 文件提取 Snippet 再恢复接管状态;Codex 的 `base_url` 编辑重构为 Section 感知模式,不再错误追加到文件末尾。
**发布日期**2026-03-12
**更新规模**5 commits | 22 files changed | +1,716 / -288 lines
---
## 重点内容
- **首次使用引导优化**:供应商列表空状态显示详细的导入说明,Claude/Codex/Gemini 还会提示通用配置 Snippet 功能
- **代理接管恢复流程重构**:热切换和供应商同步现在刷新恢复备份,而非覆盖 live 配置文件,回滚时保留完整的用户配置
- **Snippet 生命周期稳定**:引入 `cleared` 标志防止已清除的 Snippet 被自动重新提取,启动顺序调整确保从干净状态提取
- **Codex TOML Section 感知编辑**`base_url``model` 字段的读写现在定位到正确的 `[model_providers.<name>]` Section
- **Codex MCP 配置保护**:热切换供应商时保留恢复快照中已有的 `mcp_servers` 配置块,按 server id 合并而非整表替换,供应商/通用配置的 MCP 定义优先
---
## 新功能
### 空状态引导优化
改善首次使用体验,当供应商列表为空时显示详细的导入说明。
- 空状态页面展示导入供应商的操作指引
- 对 Claude/Codex/Gemini 应用有条件地显示通用配置 Snippet 提示(OpenCode/OpenClaw 不显示)
---
## 变更
### 代理接管恢复流程
代理接管的热切换和供应商同步逻辑经过重构,确保通用配置在整个接管生命周期中得到保护。
- 接管活跃时,供应商同步更新恢复备份而非直接写入 live 配置文件
- 保存恢复快照前先应用通用配置,使回滚能还原真实的用户配置
- 遗留供应商中推断使用了通用配置的条目自动标记 `commonConfigEnabled=true`
### Codex TOML 编辑引擎
将 Codex `config.toml` 的更新逻辑重构到共享的 Section 感知 TOML 辅助函数上。
- Rust 端新增 `codex_config.rs` 模块,包含 `update_codex_toml_field``remove_codex_toml_base_url_if`
- 前端新增 `getTomlSectionRange` / `getCodexProviderSectionName` 等 Section 感知工具函数
- `proxy.rs` 中散落的 TOML 内联编辑逻辑统一委托给新模块
### 通用配置初始化生命周期
启动流程重新排序,通用配置 Snippet 的提取和迁移逻辑更加健壮。
- 启动时先从干净的 live 文件自动提取通用配置 Snippet,再恢复代理接管状态
- 引入 Snippet `cleared` 标志,追踪用户是否主动清除了某个 Snippet
- 持久化一次性遗留迁移标志,避免重复执行旧版 `commonConfigEnabled` 回填
---
## Bug 修复
### 通用配置丢失
- 修复代理接管期间通用配置可能被丢弃的多种场景:同步覆盖 live 文件、热切换产生不完整的恢复快照、供应商切换丢失配置变更
### Codex 恢复快照保护
- 修复 Codex 接管恢复备份在供应商热切换时丢弃已有 `mcp_servers` 配置块的问题;将 MCP 备份保留策略从整表替换改为按 server id 合并,供应商/通用配置的 MCP 定义在冲突时优先,备份中独有的服务器仍被保留
### 已清除 Snippet 复活
- 修复启动时自动提取机制重新创建用户已主动清除的通用配置 Snippet 的问题
### Codex `base_url` 位置错误
- 修复 Codex `base_url` 提取和编辑未定位到正确的 `[model_providers.<name>]` Section,导致追加到文件末尾或误将 `mcp_servers.*.base_url` 识别为供应商端点的问题
---
## 下载与安装
访问 [Releases](https://github.com/farion1231/cc-switch/releases/latest) 下载对应版本。
### 系统要求
| 系统 | 最低版本 | 架构 |
| ------- | ----------------------------- | ----------------------------------- |
| Windows | Windows 10 及以上 | x64 |
| macOS | macOS 10.15 (Catalina) 及以上 | Intel (x64) / Apple Silicon (arm64) |
| Linux | 见下表 | x64 |
### Windows
| 文件 | 说明 |
| ------------------------------------------ | ----------------------------------- |
| `CC-Switch-v3.12.2-Windows.msi` | **推荐** - MSI 安装包,支持自动更新 |
| `CC-Switch-v3.12.2-Windows-Portable.zip` | 便携版,解压即用,不写入注册表 |
### macOS
| 文件 | 说明 |
| ---------------------------------- | --------------------------------------------------------- |
| `CC-Switch-v3.12.2-macOS.zip` | **推荐** - 解压后拖入 Applications 即可,Universal Binary |
| `CC-Switch-v3.12.2-macOS.tar.gz` | 用于 Homebrew 安装和自动更新 |
> **注意**:由于作者没有苹果开发者账号,首次打开可能出现"未知开发者"警告,请先关闭,然后前往"系统设置" → "隐私与安全性" → 点击"仍要打开",之后便可以正常打开
### HomebrewmacOS
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
| 发行版 | 推荐格式 | 安装方式 |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| 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` |
+313
View File
@@ -0,0 +1,313 @@
# CC Switch v3.12.3
> GitHub Copilot Reverse Proxy, macOS Code Signing & Notarization, Reasoning Effort Mapping, OpenCode SQLite Backend
**[中文版 →](v3.12.3-zh.md) | [日本語版 →](v3.12.3-ja.md)**
---
## Overview
CC Switch v3.12.3 is a major feature release that adds GitHub Copilot reverse proxy support with a dedicated Auth Center, introduces macOS code signing and Apple notarization for a seamless install experience, maps reasoning effort levels across providers, migrates OpenCode to a SQLite backend, enables Tool Search via the native `ENABLE_TOOL_SEARCH` environment variable toggle, and delivers a full skill backup/restore lifecycle. Additional improvements include proxy gzip compression, o-series model compatibility, Skills import rework, Ghostty terminal fix, Skills cache strategy optimization, Claude 4.6 context window update, and multiple bug fixes.
**Release Date**: 2026-03-24
**Update Scale**: 36 commits | 107 files changed | +9,124 / -802 lines
---
## Highlights
- **GitHub Copilot reverse proxy**: Full Copilot proxy support with OAuth device flow authentication, token refresh, and request fingerprint emulation ([⚠️ Risk Notice](#-risk-notice))
- **Copilot Auth Center**: Dedicated authentication management UI for GitHub Copilot OAuth flow with token status display and one-click refresh
- **macOS code signing & notarization**: macOS builds are now code-signed and notarized by Apple, eliminating the "unidentified developer" warning entirely
- **Reasoning Effort mapping**: Proxy-layer auto-mapping — explicit `output_config.effort` takes priority, falling back to `budget_tokens` thresholds (<4 000→low, 4 00016 000→medium, ≥16 000→high) for o-series and GPT-5+ models
- **OpenCode SQLite backend**: Added SQLite session storage for OpenCode alongside existing JSON backend; dual-backend scan with SQLite priority on ID conflicts
- **Codex 1M context window toggle**: One-click checkbox to set `model_context_window = 1000000` with auto-populated `model_auto_compact_token_limit`
- **Disable Auto-Upgrade toggle**: Added `DISABLE_AUTOUPDATER` env var checkbox in the Claude Common Config editor to prevent Claude Code from auto-upgrading
- **Tool Search env var toggle**: Tool Search enabled via Claude 2.1.76+ native `ENABLE_TOOL_SEARCH` environment variable in the Common Config editor — no binary patching required
- **Skill backup/restore lifecycle**: Skills are automatically backed up before uninstall; backup list with restore and delete management added
- **Proxy gzip compression**: Non-streaming proxy requests now auto-negotiate gzip compression, reducing bandwidth usage
- **o-series model compatibility**: Chat Completions proxy correctly uses `max_completion_tokens` for o1/o3/o4-mini models; Responses API kept on the correct `max_output_tokens` field
- **Skills import rework**: Replaced implicit filesystem-based app inference with explicit `ImportSkillSelection` to prevent incorrect multi-app activation
- **Ghostty terminal support**: Fixed Claude session restore in Ghostty terminal
---
## New Features
### GitHub Copilot Reverse Proxy
Added full reverse proxy support for GitHub Copilot, enabling Copilot-authenticated requests to be forwarded through CC Switch.
- Implements OAuth device flow authentication for GitHub Copilot
- Automatic token refresh and session management
- Request fingerprint emulation for seamless compatibility
- Integrated into the existing proxy infrastructure alongside Claude, Codex, and Gemini handlers
### Copilot Auth Center
A dedicated authentication management UI for GitHub Copilot.
- OAuth device flow with code display and browser-based authorization
- Token status display showing expiration and validity
- One-click token refresh without re-authentication
- Integrated into the settings panel for easy access
### Reasoning Effort Mapping
Proxy-layer auto-mapping of reasoning effort for OpenAI o-series and GPT-5+ models.
- Two-tier resolution: explicit `output_config.effort` takes priority, falling back to thinking `budget_tokens` thresholds (<4 000→low, 4 00016 000→medium, ≥16 000→high)
- Covers both Chat Completions and Responses API paths with 17 unit tests
### OpenCode SQLite Backend
Added SQLite session storage support for OpenCode alongside the existing JSON backend.
- Dual-backend scan with SQLite priority on ID conflicts
- Atomic session deletion and path validation
- JSON backend remains functional for backwards compatibility
### Codex 1M Context Window Toggle
Added a one-click toggle for Codex 1M context window in the config editor.
- Checkbox sets `model_context_window = 1000000` in `config.toml`
- Auto-populates `model_auto_compact_token_limit = 900000` when enabled
- Unchecking removes both fields cleanly
### Disable Auto-Upgrade Toggle
Added a checkbox in the Claude Common Config editor to disable Claude Code auto-upgrades.
- Sets `DISABLE_AUTOUPDATER=1` in the environment configuration when enabled
- Displayed alongside Teammates mode, Tool Search, and High Effort toggles
### Tool Search Environment Variable Toggle
Tool Search is now enabled via the native `ENABLE_TOOL_SEARCH` environment variable introduced in Claude 2.1.76+.
- Toggle available in the Common Config editor under environment variables
- Sets `ENABLE_TOOL_SEARCH=1` in the Claude environment configuration
- No binary patching required — uses Claude's built-in support
### macOS Code Signing & Notarization
macOS builds are now code-signed and notarized by Apple.
- Application signed with a valid Apple Developer certificate
- Notarized through Apple's notarization service for Gatekeeper approval
- DMG installer also signed and notarized
- Eliminates the "unidentified developer" warning on first launch
### Skill Auto-Backup on Uninstall
Skill files are now automatically backed up before uninstall to prevent accidental data loss.
- Backups stored in `~/.cc-switch/skill-backups/` with all skill files and a `meta.json` containing original metadata
- Old backups are automatically pruned to keep at most 20
- Backup path is returned to the frontend and shown in the success toast
### Skill Backup Restore & Delete
Added management commands for skill backups created during uninstall.
- List all available skill backups with metadata
- Restore copies files back to SSOT, saves the DB record, and syncs to the current app with rollback on failure
- Delete removes the backup directory after a confirmation dialog
- ConfirmDialog gains a configurable zIndex prop to support nested dialog stacking
---
## Changes
### Skills Cache Strategy Optimization
Optimized the Skills cache invalidation strategy for better performance.
- Reduced unnecessary cache refreshes during skill operations
- Improved cache coherence between skill install/uninstall and list queries
### Claude 4.6 Context Window Update
Updated Claude 4.6 model preset with the latest context window size.
- Reflects the expanded context window for Claude 4.6 models
- Updated in provider presets for accurate model information display
### MiniMax M2.7 Upgrade
- Updated MiniMax provider preset to M2.7 model variant
### Xiaomi MiMo Upgrade
- Updated Xiaomi MiMo provider preset to the latest model version
### AddProviderDialog Simplification
- Removed redundant OAuth tab, reducing dialog from 3 tabs to 2 (app-specific + universal)
### Provider Form Advanced Options Collapse
- Model mapping, API format, and other advanced fields in the Claude provider form now auto-collapse when empty
- Auto-expands when any value is set or when a preset fills them in; does not auto-collapse when manually cleared
### Proxy Gzip Compression
Non-streaming proxy requests now support gzip compression for reduced bandwidth usage.
- Non-streaming requests let reqwest auto-negotiate gzip and transparently decompress responses
- Streaming requests conservatively keep `Accept-Encoding: identity` to avoid decompression errors on interrupted SSE streams
### o1/o3 Model Compatibility
Proxy forwarding now handles OpenAI o-series model token parameters correctly.
- Chat Completions path uses `max_completion_tokens` instead of `max_tokens` for o1/o3/o4-mini models (#1451, thanks @Hemilt0n)
- Responses API path kept on the correct `max_output_tokens` field instead of incorrectly injecting `max_completion_tokens`
### OpenCode Model Variants
- Placed OpenCode model variants at top level instead of inside options for better discoverability (#1317)
### Skills Import Flow
The Skills import flow has been reworked for correctness and cleanup.
- Replaced implicit filesystem-based app inference with explicit `ImportSkillSelection` to prevent incorrect multi-app activation when the same skill directory exists under multiple app paths
- Added reconciliation to `sync_to_app` to remove disabled/orphaned symlinks
- MCP `sync_all_enabled` now removes disabled servers from live config
- Schema migration preserves a snapshot of legacy app mappings to avoid lossy reconstruction
---
## Bug Fixes
### WebDAV Password Clearing
- Fixed an issue where the WebDAV password was silently cleared when saving unrelated settings
### Tool Message Parsing
- Fixed incorrect parsing of tool-use messages in certain proxy response formats
### Dark Mode Styling
- Fixed dark mode rendering inconsistencies in UI components
### Copilot Request Fingerprint
- Fixed request fingerprint generation for Copilot proxy to match expected format
### Provider Form Double Submit
- Prevented duplicate submissions on rapid button clicks in provider add/edit forms (#1352, thanks @Hexi1997)
### Ghostty Session Restore
- Fixed Claude session restore in Ghostty terminal (#1506, thanks @canyonsehun)
### Skill ZIP Import Extension
- Added `.skill` file extension support in ZIP import dialog (#1240, #1455, thanks @yovinchen)
### Skill ZIP Install Target App
- ZIP skill installs now use the currently active app instead of always defaulting to Claude
### OpenClaw Active Card Highlight
- Fixed active OpenClaw provider card not being highlighted (#1419, thanks @funnytime75)
### Responsive Layout with TOC
- Improved responsive design when TOC title exists (#1491, thanks @West-Pavilion)
### Import Skills Dialog White Screen
- Added missing TooltipProvider in ImportSkillsDialog to prevent runtime crash when opening the dialog
### Panel Bottom Blank Area
- Replaced hardcoded `h-[calc(100vh-8rem)]` with `flex-1 min-h-0` across all content panels to eliminate bottom gap caused by mismatched offset values on different platforms
---
## Documentation
### Pricing Model ID Normalization
- Added documentation section explaining model ID normalization rules (prefix stripping, suffix trimming, `@``-` replacement) in EN/ZH/JA user manuals (#1591, thanks @makoMakoGo)
### macOS Signed Build Messaging
- Removed all `xattr` workaround instructions and "unidentified developer" warnings from README, README_ZH, installation guides (EN/ZH/JA), and FAQ pages (EN/ZH/JA); replaced with "signed and notarized by Apple" messaging
---
## ⚠️ Risk Notice
**GitHub Copilot Reverse Proxy Disclaimer**
The Copilot reverse proxy feature introduced in this release accesses GitHub Copilot services through reverse-engineered, unofficial APIs. Please be aware of the following risks before enabling this feature:
1. **Terms of Service**: This feature may violate [GitHub's Acceptable Use Policies](https://docs.github.com/en/site-policy/acceptable-use-policies/github-acceptable-use-policies) and [Terms for Additional Products and Features](https://docs.github.com/en/site-policy/github-terms/github-terms-for-additional-products-and-features), which prohibit excessive automated bulk activity, unauthorized service reproduction, and placing undue burden on servers through automated means.
2. **Account Risk**: There are documented cases of GitHub issuing warning emails to users of similar tools, citing "scripted interactions or otherwise deliberately unusual or strenuous" usage patterns. Continued use after a warning may result in temporary or permanent suspension of Copilot access.
3. **No Guarantee**: GitHub may update its detection mechanisms at any time, and usage patterns that work today may be flagged in the future.
Users enable this feature **at their own risk**. CC Switch is not responsible for any account restrictions, warnings, or service suspensions resulting from the use of this feature.
---
## Download & Installation
Visit [Releases](https://github.com/farion1231/cc-switch/releases/latest) to download the appropriate version.
### System Requirements
| System | 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 |
### Windows
| File | Description |
| ------------------------------------------ | ---------------------------------------------------- |
| `CC-Switch-v3.12.3-Windows.msi` | **Recommended** - MSI installer with auto-update |
| `CC-Switch-v3.12.3-Windows-Portable.zip` | Portable version, extract and run, no registry write |
### macOS
| File | Description |
| ---------------------------------- | -------------------------------------------------------------------- |
| `CC-Switch-v3.12.3-macOS.dmg` | **Recommended** - DMG installer, drag to Applications, Universal Binary |
| `CC-Switch-v3.12.3-macOS.zip` | ZIP archive, extract and drag to Applications, Universal Binary |
| `CC-Switch-v3.12.3-macOS.tar.gz` | For Homebrew installation and auto-update |
> macOS builds are code-signed and notarized by Apple for a seamless install experience.
### Homebrew (macOS)
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
Update:
```bash
brew upgrade --cask cc-switch
```
### Linux
| Distribution | Recommended Format | Installation Method |
| --------------------------------------- | ------------------ | ---------------------------------------------------------------------- |
| 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 directly, or use AUR |
| Other distributions / Unsure | `.AppImage` | `chmod +x CC-Switch-*.AppImage && ./CC-Switch-*.AppImage` |
+313
View File
@@ -0,0 +1,313 @@
# CC Switch v3.12.3
> GitHub Copilot リバースプロキシ、macOS コード署名と公証、Reasoning Effort マッピング、Tool Search 環境変数トグル、Skill バックアップ/リストア、OpenCode SQLite バックエンド
**[中文版 →](v3.12.3-zh.md) | [English →](v3.12.3-en.md)**
---
## 概要
CC Switch v3.12.3 は、GitHub Copilot リバースプロキシと Copilot Auth Center を追加し、Copilot トークンを使用した Claude/OpenAI API へのアクセスを実現しました。macOS ビルドに Apple コード署名と公証を導入し、「開発元を確認できません」の警告を解消しました。Reasoning Effort マッピングにより、Claude の thinking budget を OpenAI 互換の reasoning_effort パラメータに自動変換します。Tool Search は従来のバイナリパッチ方式から Claude 2.1.76+ ネイティブの `ENABLE_TOOL_SEARCH` 環境変数トグルに移行し、共通設定エディタから切り替え可能になりました。OpenCode バックエンドを JSON から SQLite に移行し、Skill バックアップ/リストアライフサイクル、プロキシ gzip 圧縮、o シリーズモデル互換性の改善も含まれます。
**リリース日**: 2026-03-24
**更新規模**: 36 commits | 107 files changed | +9,124 / -802 lines
---
## ハイライト
- **GitHub Copilot リバースプロキシ**: Copilot トークンを使用して Claude/OpenAI API にアクセスするリバースプロキシを追加。Copilot Auth Center でトークンの取得と管理が可能([⚠️ リスクに関する注意事項](#-リスクに関する注意事項)
- **macOS コード署名と公証**: macOS ビルドが Apple のコード署名と公証に対応し、初回起動時の警告なしでインストール可能に。DMG インストーラーを新たに提供
- **Reasoning Effort マッピング**: プロキシ層での自動マッピング — 明示的な `output_config.effort` を優先し、`budget_tokens` 閾値(<4000→low, 400016000→medium, ≥16000→high)にフォールバック。o シリーズおよび GPT-5+ モデルに対応
- **Tool Search 環境変数トグル**: バイナリパッチ方式を廃止し、Claude 2.1.76+ ネイティブの `ENABLE_TOOL_SEARCH` 環境変数による切り替えに移行。共通設定エディタから設定可能
- **Skill バックアップ/リストアライフサイクル**: アンインストール前に Skill ファイルを自動バックアップ。バックアップリスト、リストア、削除の管理機能を追加
- **OpenCode SQLite バックエンド**: OpenCode に SQLite セッションストレージを追加(既存の JSON バックエンドと併存)。ID 競合時は SQLite を優先するデュアルバックエンドスキャン
- **Codex 1M コンテキストウィンドウトグル**: 設定エディタでワンクリックで `model_context_window = 1000000` を設定可能。`model_auto_compact_token_limit` も自動設定
- **自動アップグレード無効化トグル**: Claude 共通設定エディタに `DISABLE_AUTOUPDATER` 環境変数のチェックボックスを追加し、Claude Code の自動アップグレードを防止
- **プロキシ Gzip 圧縮**: 非ストリーミングプロキシリクエストが gzip 圧縮を自動ネゴシエーションし、帯域幅消費を削減
- **o シリーズモデル互換性**: Chat Completions プロキシが o1/o3/o4-mini モデルに `max_completion_tokens` を正しく使用。Responses API は正しい `max_output_tokens` フィールドを維持
- **Skills インポートの刷新**: ファイルシステムベースの暗黙的なアプリ推論を明示的な `ImportSkillSelection` に置き換え、複数アプリの誤った有効化を防止
- **Ghostty ターミナルサポート**: Ghostty ターミナルでの Claude セッション復元を修正
---
## 新機能
### GitHub Copilot リバースプロキシ
GitHub Copilot トークンを使用して Claude API および OpenAI API にアクセスするリバースプロキシ機能を追加しました。
- Copilot のアクセストークンを利用し、Claude Code や Codex などのクライアントからプロキシ経由で API リクエストを転送
- Copilot 固有のリクエストフィンガープリントとヘッダー処理に対応
- プロバイダープリセットに Copilot 用テンプレートを追加
### Copilot Auth Center
Copilot トークンの取得と管理を行う認証センターを追加しました。
- GitHub デバイスフローによるトークン取得をサポート
- トークンの有効期限管理と自動リフレッシュ
- フロントエンドから直接トークンステータスの確認と再認証が可能
### Reasoning Effort マッピング
OpenAI o シリーズおよび GPT-5+ モデル向けのプロキシ層自動マッピング機能を追加しました。
- 二段階の解決ロジック:明示的な `output_config.effort` を優先し、thinking `budget_tokens` 閾値(<4000→low, 400016000→medium, ≥16000→high)にフォールバック
- Chat Completions と Responses API の両パスをカバー、17 個のユニットテスト付き
### Tool Search 環境変数トグル
Claude CLI Tool Search の有効化/無効化を環境変数で制御する設定を追加しました。
- Claude 2.1.76+ で導入されたネイティブの `ENABLE_TOOL_SEARCH` 環境変数を使用
- 共通設定(Common Config)エディタから直接トグル可能
- 従来のバイナリパッチ方式は不要になり、CLI アップデート時の再適用も不要
### Skill アンインストール時の自動バックアップ
アンインストール前に Skill ファイルを自動バックアップし、意図しないデータ損失を防止します。
- バックアップは `~/.cc-switch/skill-backups/` に保存され、すべての skill ファイルと元のメタデータを含む `meta.json` が含まれます
- 古いバックアップは自動的にプルーニングされ、最大 20 個を保持
- バックアップパスはフロントエンドに返され、成功トーストに表示
### Skill バックアップのリストアと削除
アンインストール時に作成された Skill バックアップの管理コマンドを追加しました。
- すべての利用可能な skill バックアップをメタデータ付きで一覧表示
- リストアはファイルを SSOT にコピーし、DB レコードを保存し、現在のアプリに同期。失敗時は自動ロールバック
- 削除は確認ダイアログの後にバックアップディレクトリを削除
- ConfirmDialog にネストされたダイアログスタッキングをサポートする設定可能な zIndex プロパティを追加
### OpenCode SQLite バックエンド
OpenCode に SQLite セッションストレージサポートを追加しました(既存の JSON バックエンドと併存)。
- デュアルバックエンドスキャン、ID 競合時は SQLite を優先
- アトミックなセッション削除とパス検証
- JSON バックエンドは後方互換性のため引き続き機能
### Codex 1M コンテキストウィンドウトグル
設定エディタに Codex 1M コンテキストウィンドウのワンクリックトグルを追加しました。
- チェックボックスで `config.toml``model_context_window = 1000000` を設定
- 有効化時に `model_auto_compact_token_limit = 900000` を自動設定
- 無効化時は両フィールドをクリーンに削除
### 自動アップグレード無効化トグル
Claude 共通設定エディタに自動アップグレードを無効化するチェックボックスを追加しました。
- 有効化時に `DISABLE_AUTOUPDATER=1` 環境変数を設定し、Claude Code の自動アップグレードを防止
- Teammates モード、Tool Search、高強度思考トグルと同じ行に表示
### macOS コード署名と公証
macOS ビルドに Apple のコード署名と公証を導入しました。
- Apple Developer ID による署名と Apple 公証サービスによる公証を実施
- 初回起動時の「開発元を確認できません」警告が不要に
- DMG インストーラーを新たに提供し、ドラッグ&ドロップでのインストールに対応
- CI/CD パイプラインに署名・公証ステップを統合
---
## 変更
### Skills キャッシュ戦略の最適化
Skills のキャッシュ戦略を最適化し、パフォーマンスと信頼性を向上しました。
- キャッシュの有効期限管理とインバリデーション戦略を改善
- 不要なキャッシュ再構築を削減し、起動時間を短縮
### Claude 4.6 コンテキストウィンドウ更新
Claude 4.6 モデルのコンテキストウィンドウサイズを更新しました。
- Claude 4.6 の最新コンテキストウィンドウサイズをプリセットに反映
### MiniMax M2.7 アップグレード
MiniMax モデルプリセットを M2.7 にアップグレードしました。
- MiniMax プロバイダープリセットのモデル ID とパラメータを M2.7 に更新
### Xiaomi MiMo アップグレード
Xiaomi MiMo モデルプリセットをアップグレードしました。
- MiMo プロバイダープリセットのモデル ID とパラメータを最新版に更新
### AddProviderDialog の簡素化
- 冗長な OAuth タブを削除し、ダイアログを 3 タブから 2 タブ(アプリ固有 + ユニバーサル)に簡素化
### プロバイダーフォームの高度なオプション折りたたみ
- Claude プロバイダーフォームのモデルマッピング、API フォーマットなどの高度なフィールドが未入力時にデフォルトで折りたたまれるように変更
- プリセットが値を入力すると自動展開。手動クリア時は自動折りたたみしない
### プロキシ Gzip 圧縮
非ストリーミングプロキシリクエストが gzip 圧縮をサポートし、帯域幅消費を削減しました。
- 非ストリーミングリクエストは reqwest が gzip を自動ネゴシエーションし、レスポンスを透過的に解凍
- ストリーミングリクエストは中断された SSE ストリームの解凍エラーを避けるため、保守的に `Accept-Encoding: identity` を維持
### o1/o3 モデル互換性
プロキシ転送が OpenAI o シリーズモデルのトークンパラメータを正しく処理するようになりました。
- Chat Completions パスが o1/o3/o4-mini モデルに `max_tokens` の代わりに `max_completion_tokens` を使用 (#1451@Hemilt0n に感謝)
- Responses API パスが正しい `max_output_tokens` フィールドを維持し、`max_completion_tokens` の誤った注入を防止
### OpenCode モデルバリアント
- OpenCode のモデルバリアントを options 内部ではなくプリセットのトップレベルに配置し、発見しやすさを向上 (#1317)
### Skills インポートフロー
Skills インポートフローが正確性とクリーンアップのためにリワークされました。
- ファイルシステムベースの暗黙的なアプリ推論を明示的な `ImportSkillSelection` に置き換え、同じ skill ディレクトリが複数アプリパスに存在する場合の複数アプリ誤有効化を防止
- `sync_to_app` に調整ロジックを追加し、無効化/孤立したシンボリックリンクを削除
- MCP `sync_all_enabled` がライブ設定から無効化されたサーバーを削除するように改善
- スキーママイグレーションがレガシーアプリマッピングのスナップショットを保持し、損失のある再構築を回避
---
## バグ修正
### WebDAV パスワードの消失
- 無関係な設定保存時に WebDAV パスワードがサイレントにクリアされる問題を修正
### ツールメッセージのパース
- プロキシのツールメッセージパース処理の不具合を修正し、特定のツール呼び出しパターンでのエラーを解消
### ダークモードの表示
- ダークモードでの一部 UI コンポーネントの表示不具合を修正
### Copilot リクエストフィンガープリント
- Copilot リバースプロキシのリクエストフィンガープリント生成の不具合を修正し、認証エラーを解消
### プロバイダーフォームの二重送信
- プロバイダー追加/編集フォームでの高速連続クリックによる重複送信を防止 (#1352@Hexi1997 に感謝)
### Ghostty ターミナルセッション復元
- Ghostty ターミナルでの Claude セッション復元の失敗を修正 (#1506@canyonsehun に感謝)
### Skill ZIP インポート拡張子
- ZIP インポートダイアログが `.skill` ファイル拡張子をサポートするように修正 (#1240, #1455@yovinchen に感謝)
### Skill ZIP インストール対象アプリ
- ZIP 方式でインストールされた skill が常に Claude をデフォルトにするのではなく、現在アクティブなアプリを使用するように修正
### OpenClaw アクティブカードのハイライト
- OpenClaw の現在アクティブなプロバイダーカードがハイライト表示されない問題を修正 (#1419@funnytime75 に感謝)
### TOC 付きレスポンシブレイアウト
- TOC タイトルが存在する場合のレスポンシブデザインを改善 (#1491@West-Pavilion に感謝)
### Skills インポートダイアログの白い画面
- ImportSkillsDialog に不足していた TooltipProvider を追加し、ダイアログを開く際のランタイムクラッシュを防止
### パネル下部の空白エリア
- すべてのコンテンツパネルのハードコードされた `h-[calc(100vh-8rem)]``flex-1 min-h-0` に置き換え、異なるプラットフォーム間のオフセット値の不一致による下部のギャップを解消
---
## ドキュメント
### 料金モデル ID の正規化
- 中英日三言語のユーザーマニュアルにモデル ID 正規化ルール(プレフィックス除去、サフィックストリミング、`@``-` 置換)の説明セクションを追加 (#1591@makoMakoGo に感謝)
### macOS 署名済みメッセージの更新
- README、README_ZH、インストールガイド(EN/ZH/JA)、FAQ ページ(EN/ZH/JA)からすべての `xattr` 回避策と「開発元を確認できません」警告を削除し、「Apple のコード署名と公証済み」メッセージに置換
---
## ⚠️ リスクに関する注意事項
**GitHub Copilot リバースプロキシに関する免責事項**
本リリースで追加された Copilot リバースプロキシ機能は、リバースエンジニアリングによる非公式 API を通じて GitHub Copilot サービスにアクセスします。この機能を有効にする前に、以下のリスクをご確認ください:
1. **利用規約違反の可能性**:この機能は [GitHub 利用規約](https://docs.github.com/en/site-policy/acceptable-use-policies/github-acceptable-use-policies)および[追加製品の利用条件](https://docs.github.com/en/site-policy/github-terms/github-terms-for-additional-products-and-features)に違反する可能性があります。これらの規約では、過度な自動一括操作、サービスの無断複製、自動化手段によるサーバーへの過度な負荷が禁止されています。
2. **アカウントリスク**:類似ツールの利用者が GitHub から「スクリプト化されたインタラクション、または意図的に異常もしくは過度な使用」を指摘する警告メールを受け取った事例が報告されています。警告後も使用を継続した場合、Copilot へのアクセスが一時的または永久的に停止される可能性があります。
3. **将来の利用保証なし**:GitHub は検出メカニズムをいつでも更新する可能性があり、現在利用可能な使用パターンが将来的にフラグ付けされる可能性があります。
この機能を有効にすることで、ユーザーは**すべてのリスクを自己責任で負う**ものとします。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 |
### Windows
| ファイル | 説明 |
| ------------------------------------------ | ---------------------------------------------------- |
| `CC-Switch-v3.12.3-Windows.msi` | **推奨** - MSI インストーラー、自動更新対応 |
| `CC-Switch-v3.12.3-Windows-Portable.zip` | ポータブル版、解凍して実行、レジストリ書き込みなし |
### macOS
| ファイル | 説明 |
| ---------------------------------- | ----------------------------------------------------------------- |
| `CC-Switch-v3.12.3-macOS.dmg` | **推奨** - DMG インストーラー、ドラッグ&ドロップでインストール |
| `CC-Switch-v3.12.3-macOS.zip` | 解凍して Applications にドラッグ、Universal Binary |
| `CC-Switch-v3.12.3-macOS.tar.gz` | Homebrew インストールと自動更新用 |
> macOS 版は Apple のコード署名と公証済みで、そのままインストールしてご利用いただけます。
### Homebrew (macOS)
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
| ディストリビューション | 推奨形式 | インストール方法 |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| 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` |
+296
View File
@@ -0,0 +1,296 @@
# CC Switch v3.12.3
> GitHub Copilot 反向代理、macOS 代码签名与公证、Reasoning Effort 映射、Tool Search 环境变量开关、Skill 备份/恢复生命周期
**[English →](v3.12.3-en.md) | [日本語版 →](v3.12.3-ja.md)**
---
## 概览
CC Switch v3.12.3 新增了 **GitHub Copilot 反向代理** 支持和 **Copilot Auth Center** 认证管理,引入了 **Reasoning Effort 映射** 实现跨供应商推理强度控制,通过 Claude 2.1.76+ 原生 `ENABLE_TOOL_SEARCH` 环境变量实现了 **Tool Search 开关**,新增了 **OpenCode SQLite 后端** 支持,并完成了 **macOS 代码签名与 Apple 公证**。同时引入了完整的 Skill 备份/恢复生命周期,改进了代理对 OpenAI o 系列模型的兼容性和 gzip 压缩支持,优化了 Skills 缓存策略,更新了 Claude 4.6 上下文窗口、MiniMax M2.7 和小米 MiMo 模型预设,并修复了 WebDAV 密码、工具消息解析、暗色模式和 Copilot 请求指纹等方面的问题。
**发布日期**2026-03-24
**更新规模**36 commits | 107 files changed | +9,124 / -802 lines
---
## 重点内容
- **GitHub Copilot 反向代理**:新增 Copilot 反向代理支持,通过 Copilot Auth Center 管理 GitHub Token 认证,实现 Copilot 模型在 Claude Code 中的无缝使用([⚠️ 风险提示](#-风险提示)
- **macOS 代码签名与公证**macOS 版本已通过 Apple 代码签名和公证,新增 DMG 安装格式,无需再手动绕过"未知开发者"警告
- **Reasoning Effort 映射**:代理层自动映射 — 显式 `output_config.effort` 优先,回退到 `budget_tokens` 阈值(<4000→low, 400016000→medium, ≥16000→high),支持 o 系列和 GPT-5+ 模型
- **Tool Search 环境变量开关**:利用 Claude 2.1.76+ 原生 `ENABLE_TOOL_SEARCH` 环境变量,在通用配置编辑器中一键启用 Tool Search
- **Skill 备份/恢复生命周期**:卸载前自动备份 Skill 文件;新增备份列表、恢复和删除管理
- **OpenCode SQLite 后端**:为 OpenCode 新增 SQLite 会话存储(与现有 JSON 后端并存),ID 冲突时 SQLite 优先的双后端扫描
- **Codex 1M 上下文窗口开关**:配置编辑器中一键设置 `model_context_window = 1000000`,自动填充 `model_auto_compact_token_limit`
- **禁用自动升级开关**:通用配置编辑器中新增 `DISABLE_AUTOUPDATER` 环境变量复选框,防止 Claude Code 自动升级
- **代理 Gzip 压缩**:非流式代理请求自动协商 gzip 压缩,减少带宽消耗
- **o 系列模型兼容性**Chat Completions 代理正确使用 `max_completion_tokens` 处理 o1/o3/o4-mini 模型
- **Skills 导入重构**:将基于文件系统的隐式应用推断替换为显式的 `ImportSkillSelection`,防止多应用错误激活
---
## 新功能
### GitHub Copilot 反向代理
新增完整的 GitHub Copilot 集成,作为 Claude Code 供应商使用。
- 通过 OAuth Device Code 流程进行 GitHub 认证
- 支持多账号管理和自动 Token 刷新
- Anthropic ↔ OpenAI 格式自动转换
- 实时获取可用模型列表和用量统计 (#930,感谢 @Mason-mengze)
### Copilot Auth Center
在设置中新增认证中心面板,全局管理 GitHub 账号。
- 支持按供应商绑定账号(通过 `meta.authBinding`
- 统一的 Token 管理和刷新机制
### Tool Search 开关
利用 Claude 2.1.76+ 原生 `ENABLE_TOOL_SEARCH` 环境变量控制 Tool Search 功能。
- 在供应商通用配置编辑器中以复选框形式暴露
- 替代了之前的二进制补丁方案,更简洁可靠 (#930,感谢 @Mason-mengze)
### Reasoning Effort 映射
新增代理层自动推理强度映射,支持 OpenAI o 系列和 GPT-5+ 模型。
- 两级解析:显式 `output_config.effort` 优先,回退到 `budget_tokens` 阈值(<4000→low, 400016000→medium, ≥16000→high
- 覆盖 Chat Completions 和 Responses API 两条路径,含 17 个单元测试
### OpenCode SQLite 后端
为 OpenCode 新增 SQLite 会话存储支持(与现有 JSON 后端并存)。
- 双后端扫描,ID 冲突时 SQLite 优先
- 原子会话删除和路径校验
- JSON 后端保持向后兼容
### Codex 1M 上下文窗口开关
在配置编辑器中新增 Codex 1M 上下文窗口一键开关。
- 复选框设置 `config.toml` 中的 `model_context_window = 1000000`
- 启用时自动填充 `model_auto_compact_token_limit = 900000`
- 关闭时干净移除两个字段
### 禁用自动升级开关
在 Claude 通用配置编辑器中新增禁用自动升级的复选框。
- 勾选后设置 `DISABLE_AUTOUPDATER=1` 环境变量,阻止 Claude Code 自动升级
- 与 Teammates 模式、Tool Search、高强度思考等开关同一排显示
### Skill 卸载自动备份
卸载 Skill 前自动备份文件,防止数据意外丢失。
- 备份存储在 `~/.cc-switch/skill-backups/`,包含所有 skill 文件和记录原始元数据的 `meta.json`
- 旧备份自动清理,最多保留 20 个
- 备份路径返回前端并在成功提示中显示
### Skill 备份恢复与删除
新增卸载时创建的 Skill 备份的管理功能。
- 列出所有可用的 skill 备份及元数据
- 恢复操作将文件拷回 SSOT,保存数据库记录,并同步到当前应用,失败时自动回滚
- 删除操作在确认对话框后移除备份目录
### macOS 代码签名与 Apple 公证
CI 流程新增完整的 macOS 代码签名和 Apple 公证支持。
- 导入 Apple Developer ID 证书,签名 Universal Binary
- 提交 Apple 公证并将票据装订到 `.app``.dmg`
- 硬性验证步骤(`codesign --verify` + `spctl -a` + `stapler validate`)把关发布
---
## 变更
### Skills 缓存策略优化
-`invalidateQueries` 替换为直接 `setQueryData` 更新,用于 skill 安装/卸载/导入操作
- 新增 `staleTime: Infinity``keepPreviousData`,消除加载闪烁 (#1573,感谢 @TangZhiZzz)
### 代理 Gzip 压缩
- 非流式请求允许 reqwest 自动协商 gzip 并透明解压响应
- 流式请求保守地保持 `Accept-Encoding: identity`,避免中断的 SSE 流解压出错
### o1/o3 模型兼容性
- Chat Completions 路径对 o1/o3/o4-mini 模型使用 `max_completion_tokens` 替代 `max_tokens` (#1451,感谢 @Hemilt0n)
- Responses API 路径保持使用正确的 `max_output_tokens` 字段
### OpenCode 模型变体
- 将 OpenCode 的模型变体放在预设顶层而非嵌套在 options 内部,提升可发现性 (#1317)
### Skills 导入流程
- 将基于文件系统的隐式应用推断替换为显式的 `ImportSkillSelection`,防止同一 skill 目录存在于多个应用路径下时错误激活多个应用
-`sync_to_app` 增加协调逻辑,移除已禁用/孤立的符号链接
- MCP `sync_all_enabled` 现在会从 live 配置中移除已禁用的服务器
### Claude 4.6 上下文窗口
- Claude Opus 4.6 和 Sonnet 4.6 上下文窗口从 200K 更新至 1M(GA 发布)
### MiniMax 模型升级
- MiniMax 预设从 M2.5 升级至 M2.7,更新三语合作伙伴描述
### 小米 MiMo 模型升级
- MiMo 预设从 mimo-v2-flash 升级至 mimo-v2-pro
### 添加供应商对话框简化
- 移除冗余的 OAuth 标签页,对话框从 3 个标签页减少到 2 个(应用专属 + 通用)
### 供应商表单高级选项折叠
- Claude 供应商表单中的模型映射、API 格式等高级字段在未填写时默认折叠
- 预设填充值后自动展开,手动清空不会自动折叠
---
## Bug 修复
### WebDAV 密码被静默清除
- 修复 ProviderList 或 UsageScriptModal 保存设置时 WebDAV 密码被静默清除的问题
- 前端 payload 中剥离 `webdavSync`,后端 `merge_settings_for_save()` 增加回填逻辑保护现有密码
### 工具消息解析
- 修复 Claudetool_result content blocks)、Codexfunction_call/function_call_output payloads)和 Geminiarray content + toolCalls extraction)的 tool_use/tool_result 消息分类 (#1401,感谢 @BlueOcean223)
### 暗色模式选择器
- 将 Tailwind `darkMode``["selector", "class"]` 改为 `["selector", ".dark"]`,确保暗色模式正确激活 (#1596,感谢 @qinxiandiqi)
### Copilot 请求指纹
- 统一所有 Copilot API 调用点的请求指纹头,防止 User-Agent 泄漏和 Stream Check 不匹配
### 供应商表单防重复提交
- 修复快速连续点击按钮时供应商添加/编辑表单重复提交的问题 (#1352,感谢 @Hexi1997)
### Ghostty 终端会话恢复
- 修复在 Ghostty 终端中恢复 Claude 会话失败的问题 (#1506,感谢 @canyonsehun)
### Skill ZIP 导入扩展名
- ZIP 导入对话框现在支持 `.skill` 文件扩展名 (#1240, #1455,感谢 @yovinchen)
### Skill ZIP 安装目标应用
- ZIP 方式安装的 skill 现在使用当前活跃应用,而非始终默认为 Claude
### OpenClaw 活跃供应商高亮
- 修复 OpenClaw 当前激活的供应商卡片未高亮显示的问题 (#1419,感谢 @funnytime75)
### 响应式布局与 TOC
- 改善存在 TOC 标题时的响应式布局 (#1491,感谢 @West-Pavilion)
### Skills 导入对话框白屏
- 在 ImportSkillsDialog 中补充缺失的 TooltipProvider,修复打开对话框时的运行时崩溃
### 面板底部空白区域
- 将所有内容面板的硬编码 `h-[calc(100vh-8rem)]` 替换为 `flex-1 min-h-0`,消除因不同平台偏移量不匹配导致的底部空白
---
## 文档
### 定价模型 ID 归一化
- 在中英日三语用户手册中新增模型 ID 归一化规则说明(前缀剥离、后缀修剪、`@``-` 替换)(#1591,感谢 @makoMakoGo)
### macOS 签名与公证说明
- 移除 README、安装指南和 FAQ 中所有 `xattr` 变通方案和"未知开发者"警告
- 替换为"已通过 Apple 代码签名和公证"的说明
---
## ⚠️ 风险提示
**GitHub Copilot 反向代理免责声明**
本版本新增的 Copilot 反向代理功能通过逆向工程的非官方 API 访问 GitHub Copilot 服务。启用此功能前,请注意以下风险:
1. **违反服务条款**:此功能可能违反 [GitHub 可接受使用政策](https://docs.github.com/en/site-policy/acceptable-use-policies/github-acceptable-use-policies)和[附加产品条款](https://docs.github.com/en/site-policy/github-terms/github-terms-for-additional-products-and-features),其中禁止过度自动化批量活动、未经授权的服务复制以及通过自动化手段对服务器施加不当负担。
2. **账号风险**:已有类似工具的用户收到 GitHub 官方警告邮件,指出其存在"脚本化交互或其他刻意的异常或高强度使用"行为。收到警告后继续使用可能导致 Copilot 访问权限被暂停甚至永久封禁。
3. **无法保证长期可用**:GitHub 可能随时更新其检测机制,当前可用的使用方式未来可能被标记。
用户启用此功能即表示**自行承担所有风险**。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 |
### Windows
| 文件 | 说明 |
| ------------------------------------------ | ----------------------------------- |
| `CC-Switch-v3.12.3-Windows.msi` | **推荐** - MSI 安装包,支持自动更新 |
| `CC-Switch-v3.12.3-Windows-Portable.zip` | 便携版,解压即用,不写入注册表 |
### macOS
| 文件 | 说明 |
| ---------------------------------- | --------------------------------------------------------- |
| `CC-Switch-v3.12.3-macOS.dmg` | **推荐** - DMG 安装包,拖入 Applications 即可 |
| `CC-Switch-v3.12.3-macOS.zip` | 解压后拖入 ApplicationsUniversal Binary |
| `CC-Switch-v3.12.3-macOS.tar.gz` | 用于 Homebrew 安装和自动更新 |
> macOS 版本已通过 Apple 代码签名和公证,可直接安装使用。
### HomebrewmacOS
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
| 发行版 | 推荐格式 | 安装方式 |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| 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.13.0
> Lightweight Mode, Quota & Balance Visibility, Provider Model Auto-Fetch, Codex OAuth Reverse Proxy, and Tray Per-App Submenus
**[中文版 →](v3.13.0-zh.md) | [日本語版 →](v3.13.0-ja.md)**
---
## Overview
CC Switch v3.13.0 is a major feature release centered on observability, provider workflow ergonomics, and proxy compatibility. It adds inline **quota and balance displays** across official Claude / Codex / Gemini providers plus Token Plan, Copilot, and third-party balance APIs; introduces a **Lightweight Mode** that keeps CC Switch running from the system tray without a main window; delivers **automatic model discovery** via OpenAI-compatible `/v1/models` across all five supported applications; ships a **Codex OAuth reverse proxy** for ChatGPT subscribers; reorganizes the tray menu into **per-app submenus**; rebuilds the proxy forwarding stack on a **Hyper-based client**; and overhauls the **Skills workflow** with discovery, batch updates, storage-location toggling, and built-in skills.sh search and install. Additional improvements include full URL endpoint mode, enhanced token usage tracking, the Copilot interaction optimizer, a UTF-8 streaming chunk boundary fix for multi-byte output, a Linux startup UI responsiveness fix, and a friendlier new-user onboarding experience.
**Release Date**: 2026-04-10
**Update Scale**: 139 commits | 280 files changed | +31,627 / -3,042 lines
---
## Highlights
- **Lightweight Mode**: Tray-only operating mode that destroys the main window on exit to tray and recreates it on demand, reducing CC Switch's desktop footprint to near zero when idle
- **Quota & Balance Visibility**: Inline quota or balance readout across provider cards — official Claude / Codex / Gemini subscriptions, GitHub Copilot premium interactions, Codex OAuth, Token Plan providers (Kimi / Zhipu GLM / MiniMax), plus official balance queries for DeepSeek, StepFun, SiliconFlow, OpenRouter, and Novita AI
- **Provider Model Auto-Fetch**: OpenAI-compatible `/v1/models` discovery across Claude, Codex, Gemini, OpenCode, and OpenClaw provider forms, with grouped dropdown selection and failure-specific error messages
- **Codex OAuth Reverse Proxy**: ChatGPT Codex reverse proxy exposed as a new Claude provider card type, allowing users to use their ChatGPT subscription in Claude Code. Includes managed OAuth login and inline subscription quota display ([⚠️ Risk Notice](#-risk-notice))
- **Tray Per-App Submenus**: Reworked the tray menu into per-application submenus so it never overflows the screen and background provider switching scales to dozens of providers per app
- **Skills Discovery & Batch Updates**: SHA-256-based skill update detection, per-skill and "Update All" batch actions, `skills.sh` search integration, and a storage-location toggle between CC Switch storage and `~/.agents/skills`
- **Session Workflow Upgrades**: Batch session deletion, a directory picker before launching Claude terminal restore, usage import from Claude / Codex / Gemini session logs without proxy interception, precise Codex JSONL parsing, and per-app usage filtering
- **OpenCode / OpenClaw Stream Check Coverage**: OpenCode detection via npm package mapping, OpenClaw `openai-completions` support, and the remaining OpenClaw protocol variants — with custom-header passthrough and auth-header detection fixes
- **Full URL Endpoint Mode**: Provider option that treats `base_url` as a complete upstream endpoint, unblocking vendors that require nonstandard URL layouts
- **Hyper-based Proxy Forwarding Stack**: Refactored proxy forwarding onto a Hyper-based client with transparent header forwarding, improved endpoint rewriting, and better support for dynamic upstream endpoints
- **Copilot Interaction Optimizer**: Request classification and routing logic that reduces unnecessary GitHub Copilot premium interaction consumption
- **UTF-8 Stream Chunk Boundary Fix**: All four SSE streaming paths now preserve incomplete multi-byte UTF-8 sequences across TCP chunks, eliminating intermittent U+FFFD garbled output via the Copilot reverse proxy
- **Linux Startup UI Fix**: Fixed the long-standing issue where the window UI couldn't receive clicks on Linux until the user manually maximized and restored the window
- **First-Run Onboarding**: One-time welcome dialog on fresh installs, automatic seeding of Claude / OpenAI / Google official presets, and auto-import of OpenCode / OpenClaw live configurations on startup
- **Claude Session Titles & Search Highlighting**: Meaningful title extraction for Claude sessions using a priority chain (custom-title metadata → first user message → directory basename), plus keyword highlighting in Session Manager search results
- **URL-Based Provider Icons**: Dual rendering mode supporting Vite URL imports for large SVGs and raster images (PNG, JPG, WebP), keeping small SVGs inlined
- **New Provider Presets**: TheRouter, DDSHub, LionCCAPI, Shengsuanyun (胜算云), PIPELLM, and E-FlowCode across supported applications
---
## New Features
### Lightweight Mode
A tray-only operating mode that dramatically reduces CC Switch's desktop footprint when idle.
- Destroys the main window on exit-to-tray instead of hiding it, freeing UI resources and memory
- Recreates the window on demand when the user reopens CC Switch from the tray, a deeplink, or single-instance activation
- Integrated into every window-re-show path: normal startup, deeplink, single_instance, tray `show_main`, and the lightweight-exit round-trip
### Quota & Balance Visibility
Added inline quota and balance readouts to provider cards so users can see remaining capacity without leaving the card.
- **Official subscriptions**: Inline quota display for Claude, Codex, and Gemini official providers
- **GitHub Copilot**: Premium interactions quota display on the Copilot provider card
- **Codex OAuth**: ChatGPT subscription quota inline with the Codex OAuth provider card
- **Token Plan providers**: Kimi, Zhipu GLM, and MiniMax usage progression display (requires manual activation to avoid confusion)
- **Third-party balances**: Official balance queries for DeepSeek, StepFun, SiliconFlow, OpenRouter, and Novita AI (requires manual activation to avoid confusion)
- Health-check and usage-config buttons are hidden for official providers to keep the card clean
### Provider Model Auto-Fetch
Added OpenAI-compatible model discovery to every provider form, removing the manual copy-paste loop for model IDs.
- Queries the configured provider endpoint's `/v1/models`
- Groups models in the dropdown by category for easier selection
- Failure-specific error messages distinguish network / authentication / endpoint issues
- Supported across all five applications: Claude, Codex, Gemini, OpenCode, and OpenClaw
### Codex OAuth Reverse Proxy
Added a reverse proxy path for ChatGPT subscribers who want to use their ChatGPT subscription in Claude Code.
- Managed OAuth login flow with ChatGPT authentication
- Surfaces as a new Claude provider card type alongside API-key providers
- Inline subscription quota display
- Integrated into the Auth Center for unified token management
- See the [⚠️ Risk Notice](#-risk-notice) below before enabling
### Tray Per-App Submenus
Reorganized the tray menu so providers are grouped under each application instead of living in a flat list.
- Per-application submenus for Claude, Codex, Gemini, OpenCode, and OpenClaw
- Prevents the tray menu from overflowing the screen when users have many providers
- Background provider switching scales cleanly to long provider lists
### Skills Discovery & Batch Updates
Upgraded the Skills management panel into a complete discovery plus maintenance workflow.
- **SHA-256 update detection**: Skills are content-hashed so the UI knows exactly which ones have upstream changes
- **Per-skill and batch updates**: Individual "Update" buttons plus an animated "Update All" batch action
- **Storage-location toggle**: Switch between CC Switch storage and `~/.agents/skills` without losing skill state
- **Public registry search**: `skills.sh` search integrated directly into the dialog for discovering community skills
### Session Workflow Upgrades
Multiple session management improvements that reduce friction when working with Claude / Codex / Gemini sessions.
- **Batch session deletion**: Select and delete multiple sessions at once from Session Manager (#1693, thanks @Alexlangl)
- **Directory picker before restore**: Claude terminal restore now prompts for the working directory up front (#1752, thanks @yovinchen)
- **Usage from session logs without proxy**: Usage data imported directly from Claude / Codex / Gemini session logs — no proxy interception required
- **Precise Codex JSONL parsing**: Replaced estimated Codex usage with precise JSONL session-log parsing plus Codex model name normalization for consistent pricing lookup
- **Gemini CLI session log integration**: Gemini usage now syncs accurately from Gemini CLI session logs
- **Per-app usage filtering**: Filter the usage dashboard by Claude, Codex, or Gemini independently
### OpenCode / OpenClaw Stream Check Coverage
Extended the Stream Check panel to cover the full OpenCode and OpenClaw surface area.
- OpenCode detection via npm package mapping
- Support for the OpenClaw `openai-completions` protocol
- Support for the remaining three OpenClaw protocol variants
- Edge-case handling for custom-header passthrough, OpenClaw custom auth-header detection, Bedrock error messaging, and OpenCode default `baseURL` fallback
### Full URL Endpoint Mode
Added a provider option that treats `base_url` as a complete upstream endpoint instead of a base URL with path appending (#1561, thanks @yovinchen).
- Proxy forwarding and Stream Check both honor the full-URL mode
- Unblocks vendors that require nonstandard URL layouts
- Configurable per-provider on the provider form
### OpenCode StepFun Step Plan Preset
- Added a StepFun Step Plan provider preset for OpenCode with sensible defaults (#1668, thanks @sky-wang-salvation)
### Copilot Interaction Optimizer
Added request classification and routing logic that reduces unnecessary GitHub Copilot premium interaction consumption.
- Classifies incoming requests by intent and weight
- Routes low-value requests away from premium interaction consumption paths
- Designed to extend the usable lifetime of a Copilot subscription
- Note: Even with optimized consumption, using the Copilot API outside of Copilot still consumes more than using it within Copilot.
### First-Run Welcome Dialog
Added a one-time welcome dialog on fresh installs to guide new users through the CC Switch workflow.
- Explains how existing live configuration is preserved as a default provider
- Introduces the bundled official preset that enables one-click revert to official endpoints
- Upgrade users are automatically excluded via empty provider check
### Official Provider Seeding
- Added automatic seeding of Claude Official, OpenAI Official, and Google Official provider entries on startup, giving every user a one-click path back to the official endpoint
### OpenCode / OpenClaw Auto-Import
- Added automatic startup import of live OpenCode and OpenClaw provider configurations, matching the auto-import behavior already present for Claude, Codex, and Gemini
### Common Config Editor Guidance
- Added an informational guide and empty-state prompt to the Common Config snippet editor modal for Claude, Codex, and Gemini
- Added a one-time informational dialog explaining Common Config Snippets when users first open the provider add/edit form
### Claude Session Titles & Search Highlighting
- Added meaningful title extraction for Claude sessions using a priority chain: custom-title metadata, first real user message, then directory basename fallback
- Added keyword highlighting in session titles and messages during Session Manager search
### URL-Based Provider Icons
- Added a dual rendering mode to the icon system: small SVGs are inlined as React components, while large SVGs and raster images (PNG, JPG, WebP) are loaded via Vite URL imports as `<img>` tags
### Kaku Terminal Support
- Added Kaku as a selectable terminal for session launch on macOS, reusing the WezTerm-compatible launch path (#1983, thanks @yovinchen)
### OMO Slim Council Support
- Restored first-class council support as a built-in oh-my-opencode-slim agent with updated metadata and UI copy (#1982, thanks @yovinchen)
### New Provider Presets
- **TheRouter**: Added across Claude, Codex, Gemini, OpenCode, and OpenClaw (#1891, #1892, thanks @cmzz)
- **DDSHub**: Added as a third-party partner provider for Claude with icon and partner promotion text
- **LionCCAPI**: Added across all five apps with anthropic-messages protocol for OpenCode and OpenClaw
- **Shengsuanyun (胜算云)**: Added as an aggregator partner provider across all five apps with URL-based icon and localized display name
- **PIPELLM**: Added across Claude, Codex, OpenCode, and OpenClaw with full model definitions and icon
- **E-FlowCode**: Added across all five apps with per-app protocol configuration
---
## Changes
### Tray Menu Organization
- Reworked the tray menu into per-application submenus (Claude / Codex / Gemini / OpenCode / OpenClaw)
- Prevents overflow and scales to long provider lists
### Proxy Forwarding Stack
Rebuilt the proxy forwarding layer on a Hyper-based HTTP client (#1714, thanks @yovinchen).
- Transparent header forwarding: headers are forwarded without aggressive filtering
- Improved endpoint rewriting logic
- Better support for dynamic upstream endpoints
- Paired with the new Full URL Endpoint Mode to unblock vendors with nonstandard URL layouts
### OAuth Auth Center UI Polish
- Tightened the Auth Center copy, layout, and icon presentation so the Codex OAuth login flow feels cleaner and less cluttered
### Provider Key Lifecycle & Live Sync
Reworked the additive provider create / rename / duplicate flows so live config writes, cleanup, and rollback stay consistent across OpenCode / OpenClaw and takeover scenarios (#1724, thanks @yovinchen).
- Additive-mode highlight behavior made persistent across refreshes (#1747, thanks @yovinchen)
- Consistent live config writes across OpenCode / OpenClaw
- Rollback behavior preserved when operations fail
### Codex OAuth Defaults
- Updated the Codex OAuth preset to the GPT-5.4 model family
---
## Bug Fixes
### Copilot Authentication & Proxy Compatibility
- Fixed GitHub Copilot authentication regressions (#1854, thanks @Mason-mengze)
- Corrected enterprise and dynamic endpoint handling
- Repaired clipboard verification-code copying on macOS and Linux
- Fixed Responses routing when Copilot-backed Claude providers target OpenAI models (#1735, thanks @Mason-mengze)
### UTF-8 Stream Chunk Boundaries
Fixed intermittent garbled output (U+FFFD replacement characters) in Claude Code when multi-byte UTF-8 sequences such as Chinese characters and emoji were split across TCP stream chunks via the Copilot reverse proxy (#1923, thanks @Cod1ng).
- Replaced `String::from_utf8_lossy` with a new `append_utf8_safe` helper across all four SSE streaming paths
- Preserves incomplete trailing bytes in a remainder buffer and merges them with the next chunk before decoding
- Not reproducible with direct Copilot connections that pass through raw bytes without format conversion
### Fragmented System Prompt Normalization
Fixed strict OpenAI-compatible chat backends (Nvidia, Qwen-style) rejecting requests when converted Claude payloads contained multiple system messages (#1942, thanks @yovinchen).
- Normalized system content into a single leading system message during the Anthropic → OpenAI chat transformation
- Leaves the rest of the message stream unchanged
### Streaming Parser Compatibility
- Fixed SSE parsing to accept fields with optional spaces, improving compatibility with non-strict streaming implementations (#1664, thanks @Alexlangl)
### Provider Switch State Corruption
- Serialized per-app provider switches to prevent concurrent failover or hot-switch operations from leaving `is_current`, settings state, and live backup state out of sync
### Claude Takeover Live Config Drift
- Fixed provider edits while Claude takeover is active so live settings remain aligned with the latest provider state without breaking takeover restore behavior (#1828, thanks @geekdada)
### WebDAV Password Retention & Validation
- Fixed the WebDAV password field so saved credentials remain visible after refresh
- Treated `MKCOL 405` responses correctly during connection validation (#1685, thanks @Alexlangl)
### Provider Card Action States
- Fixed additive-mode highlight behavior (#1747, thanks @yovinchen)
- Aligned usage display layout across provider cards by always rendering action buttons
- Replaced hard proxy-switch blocking with a warning path
- Disabled unsupported test and usage actions for Copilot and Codex OAuth cards
- Hid usage-config and health-check buttons for official providers
- Removed the hover-push animation from provider cards
### Usage Accuracy & Pricing
- Fixed MiniMax quota math and 0% → 100% progression
- Corrected CNY → USD pricing plus missing model definitions
- Improved Gemini session-log syncing accuracy
- Resolved session-based usage entries being shown as unknown providers
### Usage Editor & Skills UI Regressions
- Fixed usage query fields being reset while editing extractor code (#1771, thanks @if-nil)
- Corrected broken `skills.sh` links and empty descriptions
- Fixed auto-query default interval (5 min) and number-input clearing in usage configuration
### Chinese Skills Terminology
- Unified Skills-related labels across settings panels in the `zh` locale so storage and sync options use consistent wording
### Environment & Preset Compatibility
- Added Bun global bin detection in CLI scan (#1742, thanks @makoMakoGo)
- Adapted to the oh-my-openagent rename with backward compatibility (#1746, thanks @yovinchen)
- Corrected the OpenCode `kimi-for-coding` preset (#1738, thanks @makoMakoGo)
- Gated Gemini keychain parsing to macOS only
- Fixed an OpenClaw serializer panic on empty collections (#1724, thanks @yovinchen)
### Linux UI Unresponsive on Startup
Fixed a long-standing Linux bug where the window UI (including native title bar buttons) couldn't receive clicks until the user manually maximized and restored the window.
- **Root causes**: (1) Tauri webview did not acquire keyboard focus after `show()` on Linux, so the first click was consumed by X11/Wayland click-to-activate (Tauri #10746, wry #637); (2) GTK surface's input region failed to renegotiate on the `visible:false → show()` path under some WebKitGTK/compositor combinations, leaving the entire window unresponsive
- **Mitigations**: Set `WEBKIT_DISABLE_COMPOSITING_MODE=1` at startup, and added a new `linux_fix::nudge_main_window` helper that performs `set_focus` + a ±1px no-op resize ~200ms after show, equivalent to a visually invisible "maximize-and-restore"
- **Coverage**: Wired into all window-re-show paths — normal startup, deeplink, single_instance, tray `show_main`, and lightweight-mode exit
### Linux Drag Region on Header
- Removed `data-tauri-drag-region` from the top header bar on Linux to avoid triggering `gtk_window_begin_move_drag` paths affected by Tauri #13440 under Wayland
- macOS drag behavior is preserved
### OpenCode / OpenClaw Stream Check Edge Cases
- Fixed custom-header passthrough
- OpenClaw custom auth-header detection
- Bedrock error messaging
- OpenCode default `baseURL` fallback handling
### Duplicate Toast on Provider Switch
- Fixed double toast notifications (proxy-required warning followed by switch-success) when switching to Copilot, ChatGPT, or OpenAI-format providers with the proxy not running
### Session Search Accuracy & Chinese Support
- Fixed session search result truncation across providers
- Switched FlexSearch tokenizer to full mode for proper Chinese substring matching
### Adaptive Thinking Reasoning Effort
- Fixed `resolve_reasoning_effort()` mapping adaptive thinking to `xhigh` instead of incorrectly using `high` in OpenAI format conversions
### Thinking Model Fallback Display
- Fixed the Claude provider form showing an empty Thinking model field after saving only a main model by applying read-only fallback to ANTHROPIC_MODEL (#1984, thanks @yovinchen)
### Auth Tab Localization
- Fixed missing i18n translation keys for the settings auth tab label across all locale bundles (#1985, thanks @yovinchen)
### Schema Migration Guard
- Fixed database migrations failing when skills or model_pricing tables did not exist by adding table-existence checks before ALTER and UPDATE operations
---
## Documentation
### User Manual Refresh
- Updated the EN / ZH / JA user manuals to cover tray submenus, lightweight mode, provider model fetching, session management, workspace files, WebDAV v2 behavior, OpenCode / OpenClaw activation, and other provider workflow improvements
### Community & Contribution Docs
- Added `CONTRIBUTING.md`, `SECURITY.md`, and `CODE_OF_CONDUCT.md`
- Added bilingual GitHub issue and PR templates
- Added Dependabot configuration (#1829, thanks @bengbengbalabalabeng) and a stale-bot workflow for inactive issues
- Added a PR / push quality-checks CI workflow
### Release Notes Risk Notice Backport
- Added a Copilot reverse proxy risk notice and anchored highlight links in the v3.12.3 release notes across all three languages
### Sponsor Partners
- Added Shengsuanyun, LionCC, and DDS as sponsor partners in README across all languages
---
## ⚠️ Risk Notice
**Codex OAuth Reverse Proxy Disclaimer**
The Codex OAuth reverse proxy introduced in this release accesses ChatGPT Codex services through reverse-engineered OAuth flows. Please be aware of the following risks before enabling this feature:
1. **Terms of Service**: Using reverse-engineered OAuth flows to access OpenAI services may violate OpenAI's terms of service, which prohibit unauthorized automated access, service reproduction, and circumventing intended access paths.
2. **Account Risk**: OpenAI may flag unusual usage patterns as suspicious automated activity, potentially resulting in temporary or permanent restrictions on ChatGPT access.
3. **No Guarantee**: OpenAI may update its authentication and detection mechanisms at any time, and usage patterns that work today may be flagged in the future.
The **GitHub Copilot reverse proxy** introduced in v3.12.3 also remains subject to its existing risk notice — see the [v3.12.3 release notes](v3.12.3-en.md#-risk-notice) for the full disclosure.
Users enable these features **at their own risk**. CC Switch is not responsible for any account restrictions, warnings, or service suspensions resulting from the use of these features.
---
## Download & Installation
Visit [Releases](https://github.com/farion1231/cc-switch/releases/latest) to download the appropriate version.
### System Requirements
| System | 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 |
### Windows
| File | Description |
| ------------------------------------------ | ---------------------------------------------------- |
| `CC-Switch-v3.13.0-Windows.msi` | **Recommended** - MSI installer with auto-update |
| `CC-Switch-v3.13.0-Windows-Portable.zip` | Portable version, extract and run, no registry write |
### macOS
| File | Description |
| ---------------------------------- | -------------------------------------------------------------------- |
| `CC-Switch-v3.13.0-macOS.dmg` | **Recommended** - DMG installer, drag to Applications, Universal Binary |
| `CC-Switch-v3.13.0-macOS.zip` | ZIP archive, extract and drag to Applications, Universal Binary |
| `CC-Switch-v3.13.0-macOS.tar.gz` | For Homebrew installation and auto-update |
> macOS builds are code-signed and notarized by Apple for a seamless install experience.
### Homebrew (macOS)
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
Update:
```bash
brew upgrade --cask cc-switch
```
### Linux
| Distribution | Recommended Format | Installation Method |
| --------------------------------------- | ------------------ | ---------------------------------------------------------------------- |
| 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 directly, or use AUR |
| Other distributions / Unsure | `.AppImage` | `chmod +x CC-Switch-*.AppImage && ./CC-Switch-*.AppImage` |
+433
View File
@@ -0,0 +1,433 @@
# CC Switch v3.13.0
> 軽量モード、クォータ・残高の可視化、プロバイダーモデル自動取得、Codex OAuth リバースプロキシ、トレイのアプリ別サブメニュー
**[中文版 →](v3.13.0-zh.md) | [English →](v3.13.0-en.md)**
---
## 概要
CC Switch v3.13.0 は、可観測性、プロバイダーワークフローの使いやすさ、プロキシ互換性を中心とした大型機能リリースです。Claude / Codex / Gemini の公式プロバイダー、Token Plan、Copilot、サードパーティ残高 API にわたる**クォータと残高のインライン表示**を追加し、メインウィンドウなしでシステムトレイから CC Switch を動作させる**軽量モード**を導入しました。OpenAI 互換の `/v1/models` による**自動モデル発見**を 5 つのサポート対象アプリケーションすべてに提供し、ChatGPT サブスクライバー向けの **Codex OAuth リバースプロキシ**を同梱しています。トレイメニューを**アプリ別サブメニュー**に再編成し、プロキシ転送スタックを **Hyper ベースのクライアント**に再構築し、**Skills ワークフロー**を発見、バッチ更新、ストレージ位置切り替え、および組み込みの skills.sh 検索・インストールで刷新しました。さらに、フル URL エンドポイントモード、強化されたトークン用量追跡、Copilot インタラクション最適化、マルチバイト UTF-8 ストリームチャンク境界修正、Linux 起動時の UI 応答性修正、およびよりフレンドリーな新規ユーザーオンボーディングなども含まれます。
**リリース日**: 2026-04-10
**更新規模**: 139 commits | 280 files changed | +31,627 / -3,042 lines
---
## ハイライト
- **軽量モード**: トレイ専用の動作モード。トレイへの終了時にメインウィンドウを破棄し、必要時に再作成することで、アイドル時の CC Switch のデスクトップフットプリントを最小化
- **クォータと残高の可視化**: プロバイダーカードでのインラインクォータ/残高表示 — Claude / Codex / Gemini 公式サブスクリプション、GitHub Copilot premium interactions、Codex OAuth、Token Plan プロバイダー(Kimi / Zhipu GLM / MiniMax)、および DeepSeek / StepFun / SiliconFlow / OpenRouter / Novita AI の公式残高クエリをカバー
- **プロバイダーモデル自動取得**: Claude / Codex / Gemini / OpenCode / OpenClaw のプロバイダーフォームに OpenAI 互換の `/v1/models` 発見機能を追加。グループ化ドロップダウンと失敗時の具体的なエラーメッセージ付き
- **Codex OAuth リバースプロキシ**: ChatGPT の Codex リバースプロキシを新しい Claude プロバイダーカードタイプとして追加。ユーザーは ChatGPT サブスクリプションを Claude Code で利用可能に。マネージド OAuth ログインとサブスクリプションクォータのインライン表示を提供([⚠️ リスクに関する注意事項](#-リスクに関する注意事項)
- **トレイのアプリ別サブメニュー**: トレイメニューをアプリ別サブメニューに再編成し、プロバイダー数が多くてもメニューがオーバーフローせず、バックグラウンドのプロバイダー切り替えが長いリストでもスケール
- **Skills 発見とバッチ更新**: SHA-256 ベースの skill 更新検出、各 skill および「すべて更新」のバッチ更新、`skills.sh` 検索統合、CC Switch ストレージと `~/.agents/skills` の間のストレージ位置切り替え
- **セッションワークフローの改善**: Session Manager でのバッチ削除、Claude ターミナル復元前のディレクトリピッカー、プロキシ傍受なしでの Claude / Codex / Gemini セッションログからの用量インポート、正確な Codex JSONL 解析、アプリ別の用量フィルタリング
- **OpenCode / OpenClaw Stream Check カバレッジ**: OpenCode の npm パッケージマッピング検出、OpenClaw `openai-completions` サポート、および残りの OpenClaw プロトコルバリアント
- **フル URL エンドポイントモード**: `base_url` を完全な上流エンドポイントとして扱うプロバイダーオプションを追加し、非標準 URL レイアウトを要求するベンダーに対応
- **Hyper ベースのプロキシ転送スタック**: プロキシ転送層を Hyper ベースのクライアントに再構築し、透過的なヘッダー転送、改善されたエンドポイントリライト、および動的上流エンドポイントのサポートを強化
- **Copilot インタラクション最適化**: GitHub Copilot premium interaction の不要な消費を削減するリクエスト分類とルーティングロジックを追加
- **UTF-8 ストリームチャンク境界修正**: マルチバイト UTF-8 シーケンスが TCP チャンクを跨いで分割された際の Copilot リバースプロキシ経由での文字化け(U+FFFD 置換文字)を解消するため、すべての 4 つの SSE ストリーミングパスを修正
- **Linux 起動時 UI 修正**: ユーザーが手動でウィンドウを最大化・復元するまでウィンドウ UI がクリックを受け付けない長年の問題を修正
- **初回起動オンボーディング**: 新規インストール時のワンタイムウェルカムダイアログ、Claude / OpenAI / Google 公式プリセットの自動シード、起動時の OpenCode / OpenClaw ライブ設定の自動インポート
- **Claude セッションタイトルと検索ハイライト**: カスタムタイトルメタデータ → 最初のユーザーメッセージ → ディレクトリベースネームの優先チェーンによる Claude セッションの意味のあるタイトル抽出、Session Manager 検索でのキーワードハイライト
- **URL ベースのプロバイダーアイコン**: 大きな SVG とラスター画像(PNG / JPG / WebP)を Vite URL import でロードし、小さな SVG はインライン保持するデュアルレンダリングモード
- **新プロバイダープリセット**: TheRouter、DDSHub、LionCCAPI、Shengsuanyun(胜算云)、PIPELLM、E-FlowCode を対応アプリケーションに追加
---
## 新機能
### 軽量モード
CC Switch のアイドル時のデスクトップフットプリントを大幅に削減するトレイ専用動作モード。
- トレイへの終了時にメインウィンドウを隠すのではなく破棄し、UI リソースとメモリを解放
- トレイ、ディープリンク、またはシングルインスタンスアクティベーションからユーザーが CC Switch を再オープンしたときにウィンドウを再作成
- 通常起動、ディープリンク、シングルインスタンス、トレイ `show_main`、軽量モード終了など、すべてのウィンドウ再表示パスに統合
### クォータと残高の可視化
プロバイダーカードにクォータと残高の表示を追加し、カードから離れずに残容量を確認できるようにしました。
- **公式サブスクリプション**: Claude / Codex / Gemini 公式プロバイダーのサブスクリプションクォータ表示
- **GitHub Copilot**: Copilot プロバイダーカードに premium interactions 残量を表示
- **Codex OAuth**: Codex OAuth カードに ChatGPT サブスクリプションクォータをインライン表示
- **Token Plan プロバイダー**: Kimi、Zhipu GLM、MiniMax の使用量進行表示(混乱を避けるため手動で有効化が必要)
- **サードパーティ残高**: DeepSeek、StepFun、SiliconFlow、OpenRouter、Novita AI に公式残高クエリを追加(混乱を避けるため手動で有効化が必要)
- 公式プロバイダーではヘルスチェックと用量設定ボタンを非表示にし、カードをクリーンに保つ
### プロバイダーモデル自動取得
すべてのプロバイダーフォームに OpenAI 互換のモデル発見機能を追加し、モデル ID の手動コピー&ペーストを不要に。
- 設定された API キーを使ってプロバイダーの `/v1/models` エンドポイントをクエリ
- ドロップダウンでモデルをカテゴリ別にグループ化
- ネットワーク / 認証 / エンドポイント未検出 / パース失敗を区別する具体的なエラーメッセージを提供
- 5 つのアプリケーション(Claude / Codex / Gemini / OpenCode / OpenClaw)すべてをサポート
### Codex OAuth リバースプロキシ
ChatGPT サブスクライバーが ChatGPT サブスクリプションを Claude Code で利用できるリバースプロキシパスを追加。
- ChatGPT 認証を使ったマネージド OAuth ログインフロー
- API キー型プロバイダーと並ぶ新しい Claude プロバイダーカードタイプとして表示
- サブスクリプションクォータのインライン表示
- Auth Center との統合によるトークンの一元管理
- 有効化前に下記の [⚠️ リスクに関する注意事項](#-リスクに関する注意事項) をご確認ください
### トレイのアプリ別サブメニュー
トレイメニューを、フラットリストの代わりにアプリケーション別にプロバイダーをグループ化する構造に再編成しました。
- Claude / Codex / Gemini / OpenCode / OpenClaw のアプリ別サブメニュー
- プロバイダーが多い場合にトレイメニューが画面からはみ出すことを防止
- バックグラウンドのプロバイダー切り替えが長いリストでもクリーンにスケール
### Skills 発見とバッチ更新
Skills 管理パネルを、発見と保守を備えた完全なワークフローにアップグレード。
- **SHA-256 更新検出**: Skill をコンテンツハッシュ化することで、どれが上流で変更されたかを UI が正確に把握
- **各 skill およびバッチ更新**: 個別の「更新」ボタンと、スライドインアニメーション付きの「すべて更新」バッチアクション
- **ストレージ位置切り替え**: CC Switch ストレージと `~/.agents/skills` の間を skill 状態を失わずに切り替え
- **公開レジストリ検索**: `skills.sh` 検索をダイアログに直接統合し、コミュニティ skill を発見しやすく
### セッションワークフローの改善
Claude / Codex / Gemini セッションでの作業を効率化する複数のセッション管理改善。
- **セッションのバッチ削除**: Session Manager で複数のセッションを選択し、1 つのアクションで削除 (#1693, @Alexlangl に感謝)
- **復元前のディレクトリピッカー**: Claude ターミナルの復元時、事前に作業ディレクトリを選択 (#1752, @yovinchen に感謝)
- **プロキシなしのセッションログ用量**: Claude / Codex / Gemini セッションログから直接用量データをインポート — プロキシ傍受は不要
- **正確な Codex JSONL 解析**: Codex の推定用量を、JSONL セッションログの正確な解析に置き換え。Codex モデル名の正規化により料金ルックアップが一貫
- **Gemini CLI セッションログ統合**: Gemini 用量が Gemini CLI セッションログから正確に同期
- **アプリ別の用量フィルタリング**: 用量ダッシュボードを Claude / Codex / Gemini ごとに独立してフィルタリング可能
### OpenCode / OpenClaw Stream Check カバレッジ
Stream Check パネルのカバレッジを OpenCode と OpenClaw のサーフェス全体に拡張。
- npm パッケージマッピングによる OpenCode 検出
- OpenClaw `openai-completions` プロトコルのサポート
- 残りの 3 つの OpenClaw プロトコルバリアントのサポート
- カスタムヘッダー透過、OpenClaw カスタム auth-header 検出、Bedrock エラーメッセージ、OpenCode デフォルト `baseURL` フォールバックのエッジケース処理
### フル URL エンドポイントモード
`base_url` をパス付加を伴わない完全な上流エンドポイントとして扱うプロバイダーオプションを追加 (#1561, @yovinchen に感謝)。
- プロキシ転送と Stream Check の両方がフル URL モードに対応
- 非標準 URL レイアウトを要求するベンダーをアンブロック
- プロバイダーフォームでプロバイダー単位で設定可能
### OpenCode StepFun Step Plan プリセット
- OpenCode 向けに StepFun Step Plan プロバイダープリセットと適切なデフォルト値を追加 (#1668, @sky-wang-salvation に感謝)
### Copilot インタラクション最適化
GitHub Copilot premium interaction の不要な消費を削減するリクエスト分類とルーティングロジックを追加。
- 受信リクエストを意図と重要度で分類
- 価値の低いリクエストを premium interaction 消費パスから迂回
- Copilot サブスクリプションの使用可能期間を延長することを目的
- 注意: 消費を最適化しても、Copilot 外で Copilot API を使用する場合、Copilot 内で使用するよりも消費量は多くなります。
### 初回起動ウェルカムダイアログ
新規インストールのユーザーに CC Switch のワークフローを案内するワンタイムウェルカムダイアログを追加。
- 既存のライブ設定がデフォルトプロバイダーとして保持される仕組みを説明
- 内蔵の公式プリセットによるワンクリックでの公式エンドポイント復帰を紹介
- アップグレードユーザーは空プロバイダーチェックにより自動的にスキップ
### 公式プロバイダーの自動シード
- 起動時に Claude Official / OpenAI Official / Google Official プロバイダーエントリを自動シードし、すべてのユーザーにワンクリックで公式エンドポイントに戻るパスを提供
### OpenCode / OpenClaw 自動インポート
- 起動時に OpenCode と OpenClaw のライブプロバイダー設定を自動インポート。Claude / Codex / Gemini で既にある自動インポート動作と同等に
### Common Config エディタガイダンス
- Claude / Codex / Gemini の Common Config スニペットエディタモーダルに情報ガイドと空状態プロンプトを追加
- ユーザーがプロバイダー追加/編集フォームを初めて開く際、Common Config Snippets を説明するワンタイムダイアログを追加
### Claude セッションタイトルと検索ハイライト
- Claude セッションの意味のあるタイトル抽出を追加。優先チェーン: カスタムタイトルメタデータ → 最初の実ユーザーメッセージ → ディレクトリベースネームフォールバック
- Session Manager 検索時にセッションタイトルとメッセージ内のキーワードをハイライト
### URL ベースのプロバイダーアイコン
- アイコンシステムにデュアルレンダリングモードを追加: 小さな SVG は React コンポーネントとしてインライン、大きな SVG とラスター画像(PNG / JPG / WebP)は Vite URL import で `<img>` タグとしてロード
### Kaku ターミナルサポート
- macOS でセッション起動用の選択可能なターミナルとして Kaku を追加。WezTerm 互換の起動パスを再利用 (#1983, @yovinchen に感謝)
### OMO Slim Council サポート
- 内蔵 oh-my-opencode-slim エージェントとしての council のファーストクラスサポートを復元。メタデータと UI コピーを更新 (#1982, @yovinchen に感謝)
### 新プロバイダープリセット
- **TheRouter**: Claude / Codex / Gemini / OpenCode / OpenClaw の 5 アプリに追加 (#1891, #1892, @cmzz に感謝)
- **DDSHub**: Claude のサードパーティパートナープロバイダーとして追加。アイコンとパートナープロモーションテキスト付き
- **LionCCAPI**: 5 アプリすべてに追加。OpenCode / OpenClaw は anthropic-messages プロトコルを使用
- **Shengsuanyun(胜算云)**: アグリゲーターパートナープロバイダーとして 5 アプリすべてに追加。URL ベースのアイコンとローカライズ名をサポート
- **PIPELLM**: Claude / Codex / OpenCode / OpenClaw に追加。完全なモデル定義とアイコン付き
- **E-FlowCode**: 5 アプリすべてに追加。アプリごとに異なるプロトコル設定
---
## 変更
### トレイメニュー構成
- トレイメニューをアプリ別サブメニュー(Claude / Codex / Gemini / OpenCode / OpenClaw)に再編成
- オーバーフローを防ぎ、長いプロバイダーリストでもスケール
### プロキシ転送スタック
プロキシ転送層を Hyper ベースの HTTP クライアント上に再構築 (#1714, @yovinchen に感謝)。
- 透過的なヘッダー転送: ヘッダーをアグレッシブにフィルタせずに転送
- 改善されたエンドポイントリライトロジック
- 動的上流エンドポイントへのより良いサポート
- 新しいフル URL エンドポイントモードと組み合わせ、非標準 URL レイアウトのベンダーをアンブロック
### OAuth Auth Center UI 調整
- Auth Center のコピー、レイアウト、アイコンの表現を調整し、Codex OAuth ログインフローをよりクリーンに
### プロバイダーキーライフサイクルと Live 同期
アディティブプロバイダーの作成/名前変更/複製フローを再構築し、OpenCode / OpenClaw およびテイクオーバーシナリオで Live 設定の書き込み、クリーンアップ、ロールバックが一貫するように (#1724, @yovinchen に感謝)。
- アディティブモードのハイライト動作がリフレッシュ後も保持 (#1747, @yovinchen に感謝)
- OpenCode / OpenClaw 全体で Live 設定の書き込みが一貫
- 操作失敗時のロールバック動作を保持
### Codex OAuth デフォルト
- Codex OAuth プリセットを GPT-5.4 モデルファミリーに更新
---
## バグ修正
### Copilot 認証とプロキシ互換性
- GitHub Copilot 認証の回帰を修正 (#1854, @Mason-mengze に感謝)
- エンタープライズおよび動的エンドポイントの処理を修正
- macOS と Linux でのクリップボード検証コードコピーを修復
- Copilot バックの Claude プロバイダーが OpenAI モデルをターゲットとする場合の Responses ルーティングを修正 (#1735, @Mason-mengze に感謝)
### UTF-8 ストリームチャンク境界
Claude Code で Copilot リバースプロキシ経由時、中国語文字や絵文字などのマルチバイト UTF-8 シーケンスが TCP ストリームチャンクを跨いで分割される際の文字化け(U+FFFD 置換文字)を修正 (#1923, @Cod1ng に感謝)。
- すべての 4 つの SSE ストリーミングパスで `String::from_utf8_lossy` を新しい `append_utf8_safe` ヘルパーに置き換え
- 不完全な末尾バイトを残余バッファで保持し、次のチャンクとマージしてからデコード
- 直接の Copilot 接続では再現しない(フォーマット変換なしで生バイトを通すため)
### フラグメント System Prompt の正規化
厳格な OpenAI 互換 chat バックエンド(Nvidia、Qwen 系)が変換後の Claude ペイロードに複数の system メッセージを含む場合にリクエストを拒否する問題を修正 (#1942, @yovinchen に感謝)。
- Anthropic → OpenAI chat 変換時に、system コンテンツを単一の先頭 system メッセージに正規化
- メッセージストリームの残りは変更なし
### ストリーミングパーサー互換性
- オプションのスペースを含むフィールドを受け入れるよう SSE パースを修正し、非厳格なストリーミング実装との互換性を向上 (#1664, @Alexlangl に感謝)
### プロバイダー切り替え状態の破損
- アプリごとのプロバイダー切り替えを直列化し、並行フェイルオーバーやホットスイッチ操作が `is_current`、設定状態、Live バックアップ状態を不整合状態のままにすることを防止
### Claude テイクオーバー Live 設定のドリフト
- Claude テイクオーバーが有効な間のプロバイダー編集で、Live 設定が最新のプロバイダー状態と整合を保つようにし、テイクオーバー復元動作を壊さない (#1828, @geekdada に感謝)
### WebDAV パスワード保持と検証
- 保存済みの WebDAV パスワードがリフレッシュ後も表示されるように修正
- 接続検証時に `MKCOL 405` レスポンスを正しく処理 (#1685, @Alexlangl に感謝)
### プロバイダーカードのアクション状態
- アディティブモードのハイライト動作を修正 (#1747, @yovinchen に感謝)
- アクションボタンを常にレンダリングすることでプロバイダーカード全体の用量表示レイアウトを整列
- ハードなプロキシ切り替えブロッキングを警告パスに置き換え
- Copilot および Codex OAuth カードでサポートされていないテスト/用量アクションを無効化
- 公式プロバイダーでは用量設定とヘルスチェックのボタンを非表示
- プロバイダーカードのホバープッシュアニメーションを削除
### 用量精度と料金
- MiniMax クォータの計算と 0% → 100% 進行を修正
- CNY → USD の料金を修正し、不足モデルを追加
- Gemini セッションログ同期の精度を改善
- セッションベースの用量エントリが「不明なプロバイダー」として表示される問題を解決
### 用量エディタと Skills UI の回帰
- エクストラクタコード編集時に用量クエリフィールドがリセットされる問題を修正 (#1771, @if-nil に感謝)
- 壊れた `skills.sh` リンクと空の説明を修正
- 用量設定の auto-query デフォルト間隔(5 分)と数値入力のクリア問題を修正
### 中国語 Skills 用語
- zh ロケールの設定パネルで Skills 関連ラベルを統一し、ストレージと同期オプションで一貫した表現を使用
### 環境とプリセット互換性
- CLI スキャンで Bun グローバル bin 検出を追加 (#1742, @makoMakoGo に感謝)
- oh-my-openagent のリネームに後方互換性を持って対応 (#1746, @yovinchen に感謝)
- OpenCode `kimi-for-coding` プリセットを修正 (#1738, @makoMakoGo に感謝)
- Gemini キーチェーン解析を macOS のみに制限
- 空コレクションで発生する OpenClaw シリアライザのパニックを修正 (#1724, @yovinchen に感謝)
### Linux 起動時の UI 応答性
ユーザーが手動でウィンドウを最大化・復元するまで、ウィンドウ UI(ネイティブタイトルバーボタンを含む)がクリックを受け付けないという長年の Linux 固有のバグを修正。
- **根本原因**: (1) Tauri webview が Linux の `show()` 後にキーボードフォーカスを取得せず、最初のクリックが X11/Wayland の click-to-activate によって消費される(Tauri #10746、wry #637; (2) GTK surface の入力領域が、一部の WebKitGTK/コンポジター組み合わせで `visible:false → show()` パスの再交渉に失敗し、ウィンドウ全体が応答しなくなる
- **緩和策**: 起動時に `WEBKIT_DISABLE_COMPOSITING_MODE=1` を設定し、新しい `linux_fix::nudge_main_window` ヘルパーを追加。show から ~200ms 後に `set_focus` + ±1px のノーオペレーションリサイズを実行し、視覚的に見えない「最大化と復元」と同等の動作を実現
- **カバレッジ**: すべてのウィンドウ再表示パス(通常起動、ディープリンク、シングルインスタンス、トレイ `show_main`、軽量モード終了)に統合
### Linux ヘッダーのドラッグ領域
- Wayland 下で Tauri #13440 の影響を受ける `gtk_window_begin_move_drag` パスのトリガーを回避するため、Linux ではトップヘッダーバーから `data-tauri-drag-region` を削除
- macOS のドラッグ動作は保持
### OpenCode / OpenClaw Stream Check のエッジケース
- カスタムヘッダー透過を修正
- OpenClaw カスタム auth-header 検出を修正
- Bedrock エラーメッセージを修正
- OpenCode デフォルト `baseURL` のフォールバック処理を修正
### プロバイダー切り替え時の重複 Toast
- プロキシ未実行時に Copilot / ChatGPT / OpenAI フォーマットプロバイダーに切り替えた際の二重 toast 通知(プロキシ必要警告 + 切り替え成功)を修正
### セッション検索精度と中国語サポート
- プロバイダーをまたぐセッション検索結果の切り詰めを修正
- FlexSearch トークナイザーを full モードに切り替え、中国語サブストリングマッチングを正しく動作させる
### 適応的思考の推論エフォート
- `resolve_reasoning_effort()` が適応的思考を `high` ではなく正しく `xhigh` にマッピングするよう修正(OpenAI フォーマット変換時)
### Thinking モデルフォールバック表示
- Claude プロバイダーフォームでメインモデルのみ保存後に Thinking モデルフィールドが空で表示される問題を修正。ANTHROPIC_MODEL への読み取り専用フォールバックを適用 (#1984, @yovinchen に感謝)
### Auth タブのローカライゼーション
- 設定の auth タブラベルに不足していた i18n 翻訳キーをすべてのロケールバンドルで修正 (#1985, @yovinchen に感謝)
### スキーマ移行ガード
- skills または model_pricing テーブルが存在しない場合にデータベース移行が失敗する問題を修正。ALTER および UPDATE 操作の前にテーブル存在チェックを追加
---
## ドキュメント
### ユーザーマニュアルの刷新
- EN / ZH / JA ユーザーマニュアルで、トレイサブメニュー、軽量モード、プロバイダーモデル取得、セッション管理、ワークスペースファイル、WebDAV v2 の動作、OpenCode / OpenClaw の有効化、その他のプロバイダーワークフロー改善を更新
### コミュニティと貢献ドキュメント
- `CONTRIBUTING.md``SECURITY.md``CODE_OF_CONDUCT.md` を追加
- バイリンガル GitHub issue および PR テンプレートを追加
- Dependabot 設定 (#1829, @bengbengbalabalabeng に感謝) と、非アクティブな issue を自動クローズする stale-bot ワークフローを追加
- PR / push 品質チェック CI ワークフローを追加
### Release Notes のリスク通知バックポート
- v3.12.3 の release notes に Copilot リバースプロキシのリスク通知とハイライトリンクのアンカーを 3 言語すべてに追加
### スポンサーパートナー
- README の 3 言語すべてに Shengsuanyun、LionCC、DDS をスポンサーパートナーとして追加
---
## ⚠️ リスクに関する注意事項
**Codex OAuth リバースプロキシに関する免責事項**
本リリースで追加された Codex OAuth リバースプロキシ機能は、リバースエンジニアリングによる OAuth フローを通じて ChatGPT の Codex サービスにアクセスします。この機能を有効にする前に、以下のリスクをご確認ください:
1. **利用規約違反の可能性**: リバースエンジニアリングされた OAuth フローを使用して OpenAI サービスにアクセスすることは、OpenAI の利用規約に違反する可能性があります。これらの規約では、未承認の自動アクセス、サービス複製、および意図されたアクセスパスの回避が禁止されています。
2. **アカウントリスク**: OpenAI は異常な使用パターンを疑わしい自動化活動としてフラグ付けし、ChatGPT へのアクセスに一時的または永久的な制限を科す可能性があります。
3. **将来の利用保証なし**: OpenAI は認証および検出メカニズムをいつでも更新する可能性があり、現在動作する使用パターンが将来的にフラグ付けされる可能性があります。
v3.12.3 で導入された **GitHub Copilot リバースプロキシ**も、既存のリスク通知の対象となります — 詳細は [v3.12.3 リリースノート](v3.12.3-ja.md#-リスクに関する注意事項) を参照してください。
これらの機能を有効にすることで、ユーザーは**すべてのリスクを自己責任で負う**ものとします。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 |
### Windows
| ファイル | 説明 |
| ------------------------------------------ | ---------------------------------------------------- |
| `CC-Switch-v3.13.0-Windows.msi` | **推奨** - MSI インストーラー、自動更新対応 |
| `CC-Switch-v3.13.0-Windows-Portable.zip` | ポータブル版、解凍して実行、レジストリ書き込みなし |
### macOS
| ファイル | 説明 |
| ---------------------------------- | ----------------------------------------------------------------- |
| `CC-Switch-v3.13.0-macOS.dmg` | **推奨** - DMG インストーラー、ドラッグ&ドロップでインストール |
| `CC-Switch-v3.13.0-macOS.zip` | 解凍して Applications にドラッグ、Universal Binary |
| `CC-Switch-v3.13.0-macOS.tar.gz` | Homebrew インストールと自動更新用 |
> macOS 版は Apple のコード署名と公証済みで、そのままインストールしてご利用いただけます。
### Homebrew (macOS)
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
| ディストリビューション | 推奨形式 | インストール方法 |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| 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` |
+434
View File
@@ -0,0 +1,434 @@
# CC Switch v3.13.0
> 轻量模式、配额与余额展示、供应商模型自动获取、Codex OAuth 反向代理、托盘按应用分级菜单
**[English →](v3.13.0-en.md) | [日本語版 →](v3.13.0-ja.md)**
---
## 概览
CC Switch v3.13.0 是一次重要的功能版本,聚焦于可观测性、供应商工作流与代理兼容性。本版本在各主要供应商卡片上新增了**配额与余额展示**,覆盖 Claude / Codex / Gemini 官方订阅、Token PlanKimi / Zhipu GLM / MiniMax)、Copilot premium interactions 以及 DeepSeek / StepFun / SiliconFlow / OpenRouter / Novita AI 等第三方余额查询;引入了**轻量模式**,让 CC Switch 可以仅驻留在系统托盘中运行;通过 OpenAI 兼容的 `/v1/models` 端点在 Claude / Codex / Gemini / OpenCode / OpenClaw 五个应用的供应商表单中实现了**模型自动发现**;为 ChatGPT 订阅者提供了 **Codex OAuth 反向代理**;将托盘菜单重构为**按应用分级的子菜单**;将代理转发层重建在 **Hyper 客户端**之上;并完成了 **Skills 工作流**的发现、批量更新和存储位置切换改造,内置了 skills.sh 搜索安装。其他改进还包括完整 URL 端点模式、更完善的 token 用量追踪、Copilot 调用优化器、多字节 UTF-8 流式分片边界修复以及 Linux 启动时 UI 无响应修复,以及更友善的新用户引导等。
**发布日期**2026-04-10
**更新规模**139 commits | 280 files changed | +31,627 / -3,042 lines
---
## 重点内容
- **轻量模式**:新增仅托盘运行模式,退出到托盘时销毁主窗口、按需重建,空闲时资源占用接近零
- **配额与余额展示**:供应商卡片上直接展示配额或余额 —— 覆盖 Claude / Codex / Gemini 官方订阅、GitHub Copilot premium interactions、Codex OAuth、Token PlanKimi / Zhipu GLM / MiniMax),以及 DeepSeek / StepFun / SiliconFlow / OpenRouter / Novita AI 的官方余额查询
- **供应商模型自动获取**:为 Claude / Codex / Gemini / OpenCode / OpenClaw 的供应商表单新增 OpenAI 兼容的 `/v1/models` 发现能力,按分组下拉展示并提供针对性错误提示
- **Codex OAuth 反向代理**:新增 ChatGPT 的 Codex 反向代理,作为新的 Claude 供应商卡片类型,让用户在可以在 Claude Code 里面使用 ChatGPT 订阅。包含受管 OAuth 登录流程和订阅配额展示([⚠️ 风险提示](#-风险提示)
- **托盘按应用分级菜单**:将托盘菜单重构为按应用分组的子菜单,防止供应商多时菜单溢出,让后台切换供应商在大量供应商场景下仍可用
- **Skills 发现与批量更新**:基于 SHA-256 内容哈希的更新检测、单项和"全部更新"批量操作、`skills.sh` 表搜索集成,以及 CC Switch 与 `~/.agents/skills` 的存储位置切换
- **会话工作流升级**:会话管理器批量删除、Claude 终端恢复前的目录选择器、无需代理拦截即可导入 Claude / Codex / Gemini 会话日志用量、精确的 Codex JSONL 解析、按应用筛选用量面板
- **OpenCode / OpenClaw 流式检测覆盖**:新增 OpenCode 的 npm 包映射检测、OpenClaw `openai-completions` 支持,以及其余所有 OpenClaw 协议变体
- **完整 URL 端点模式**:新增将 `base_url` 视作完整上游端点的供应商选项,支持非标准 URL 布局的厂商
- **Hyper 代理转发栈**:将代理转发层重构到 Hyper 客户端之上,实现透明头部转发、改进的端点重写以及对动态上游端点的更好支持
- **Copilot 调用优化器**:新增请求分类和路由逻辑,降低 GitHub Copilot premium interaction 的不必要消耗
- **UTF-8 流式分片边界修复**:所有 4 条 SSE 流式路径改为跨分片保留残留多字节序列,消除 Copilot 反代下中文/emoji 乱码
- **Linux 启动 UI 修复**:修复长期存在的 Linux 窗口初次无法响应点击、需用户手动最大化再还原才能操作的问题
- **首次运行引导**:新安装时弹出一次性欢迎对话框、自动种入 Claude / OpenAI / Google 官方预设、启动时自动导入 OpenCode / OpenClaw 的 live 配置
- **Claude 会话标题与搜索高亮**:从 Claude 会话中提取有意义的标题(自定义标题 → 首条用户消息 → 目录名),在会话管理器搜索时高亮匹配关键词
- **URL 图标支持**:图标系统新增双渲染模式,大 SVG 和光栅图片(PNG / JPG / WebP)通过 Vite URL import 加载,小 SVG 保持内联
- **新供应商预设**:新增 TheRouter、DDSHub、LionCCAPI、胜算云、PIPELLM、E-FlowCode 预设
---
## 新功能
### 轻量模式
新增仅托盘运行模式,显著降低 CC Switch 空闲时的桌面占用。
- 退出到托盘时销毁主窗口而非隐藏,释放 UI 资源和内存
- 用户从托盘、深链接或单例激活时按需重建窗口
- 覆盖所有窗口重新显示路径:正常启动、深链接、单例、托盘 `show_main` 以及轻量模式退出返程
### 配额与余额展示
在供应商卡片上新增配额和余额读数,用户无需离开卡片即可查看剩余容量。
- **官方订阅**Claude / Codex / Gemini 官方供应商的订阅配额展示
- **GitHub Copilot**:在 Copilot 供应商卡片上显示 premium interactions 剩余量
- **Codex OAuth**:在 Codex OAuth 卡片上内联展示 ChatGPT 订阅配额
- **Token Plan 供应商**Kimi、Zhipu GLM、MiniMax 用量进度显示(为避免混淆,需要手动开启)
- **第三方余额**:为 DeepSeek、StepFun、SiliconFlow、OpenRouter、Novita AI 提供官方余额查询(为避免混淆,需要手动开启)
- 官方供应商的健康检查和用量配置按钮自动隐藏,保持卡片简洁
### 供应商模型自动获取
为所有供应商表单新增 OpenAI 兼容的模型发现能力,消除手动复制粘贴模型 ID 的繁琐流程。
- 使用配置的 API key 向供应商的 `/v1/models` 端点发起请求
- 在下拉菜单中按类别分组展示模型
- 对网络 / 认证 / 端点不存在 / 解析失败等场景提供具体错误消息
- 支持全部五个应用(Claude / Codex / Gemini / OpenCode / OpenClaw
### Codex OAuth 反向代理
新增 ChatGPT 订阅者的 Codex OAuth 反向代理路径,让 ChatGPT 订阅者可以在 Claude Code 中使用自己的订阅。
- 受管 OAuth 登录流程,通过 ChatGPT 认证
- 作为新的 Claude 供应商卡片类型出现在列表中,与 API-key 型供应商并列
- 订阅配额内联展示
- 与 Auth Center UI 紧密集成,统一管理 Token
- 启用前请参见下文的 [⚠️ 风险提示](#-风险提示)
### 托盘按应用分级菜单
将托盘菜单重构为按应用分组的子菜单,取代原来的扁平列表。
- 为 Claude / Codex / Gemini / OpenCode / OpenClaw 分别建立独立的子菜单
- 防止用户有大量供应商时托盘菜单溢出屏幕
- 后台切换供应商的可扩展性更好
### Skills 发现与批量更新
将 Skills 管理面板升级为完整的发现 + 维护工作流。
- **SHA-256 更新检测**:通过内容哈希判断哪些 skill 在远端有更新
- **单项与批量更新**:单项"更新"按钮 + 带滑入动画的"全部更新"批量操作
- **存储位置切换**:在 CC Switch 存储和 `~/.agents/skills` 之间切换而不丢失 skill 状态
- **公共注册表搜索**:将 `skills.sh` 搜索直接集成到对话框中,方便发现社区 skill
### 会话工作流升级
多项会话管理改进,降低使用 Claude / Codex / Gemini 会话时的摩擦。
- **批量删除会话**:在会话管理器中选择并一次删除多个会话 (#1693, 感谢 @Alexlangl)
- **恢复前目录选择器**:Claude 终端恢复前先选择工作目录 (#1752, 感谢 @yovinchen)
- **无需代理的会话日志用量**:直接从 Claude / Codex / Gemini 会话日志导入用量数据,无需代理拦截
- **精确的 Codex JSONL 解析**:替换 Codex 的估算用量为基于 JSONL 会话日志的精确解析,同时对模型名称做归一化以保证定价查询一致性
- **Gemini CLI 会话日志集成**Gemini 用量现在从 Gemini CLI 会话日志精确同步
- **按应用筛选用量**:用量面板可按 Claude / Codex / Gemini 独立筛选
### OpenCode / OpenClaw 流式检测覆盖
将 Stream Check 面板的覆盖范围扩展到 OpenCode 和所有 OpenClaw 协议变体。
- 通过 npm 包映射检测 OpenCode 供应商
- 支持 OpenClaw `openai-completions` 协议
- 支持剩余的三个 OpenClaw 协议变体
- 针对自定义头透传、OpenClaw 自定义 auth-header 检测、Bedrock 错误消息、OpenCode 默认 `baseURL` 回退等边界情况进行了处理
### 完整 URL 端点模式
新增将 `base_url` 视作完整上游端点的供应商选项,取代原有的 base-URL 加路径拼接模式 (#1561, 感谢 @yovinchen)。
- 代理转发和 Stream Check 都会遵循完整 URL 模式
- 解锁需要非标准 URL 布局的厂商
- 可在供应商表单中按供应商配置
### OpenCode StepFun Step Plan 预设
- 为 OpenCode 新增 StepFun Step Plan 供应商预设及合理默认值 (#1668, 感谢 @sky-wang-salvation)
### Copilot 调用优化器
新增请求分类和路由逻辑,降低 GitHub Copilot premium interaction 的不必要消耗。
- 根据请求意图和权重进行分类
- 将低价值请求路由到非 premium 通道
- 旨在延长 Copilot 订阅的可用时长
- 注意,即使优化过消耗以后,在 Copilot 外使用 Copilot 的 API 消耗仍然会高于在 Copilot 内使用。
### 首次运行欢迎对话框
新安装用户首次打开时显示一次性欢迎对话框,引导了解 CC Switch 工作流程。
- 说明已有 live 配置如何被保留为默认供应商
- 介绍内置官方预设如何实现一键回滚到官方端点
- 升级用户通过空供应商检查自动跳过
### 官方供应商自动种入
- 启动时自动种入 Claude Official / OpenAI Official / Google Official 供应商条目,为每位用户提供一键回滚到官方端点的路径
### OpenCode / OpenClaw 自动导入
- 启动时自动导入 OpenCode 和 OpenClaw 的 live 供应商配置,与 Claude / Codex / Gemini 已有的自动导入行为对齐
### Common Config 编辑器引导
- 在 Claude / Codex / Gemini 的 Common Config 代码片段编辑器弹窗中添加引导信息和空状态提示
- 用户首次打开供应商添加/编辑表单时弹出一次性对话框说明 Common Config Snippets
### Claude 会话标题与搜索高亮
- 为 Claude 会话新增有意义的标题提取,优先链:自定义标题元数据 → 首条真实用户消息 → 目录名回退
- 在会话管理器搜索时高亮匹配关键词
### URL 图标支持
- 图标系统新增双渲染模式:小 SVG 以 React 组件内联,大 SVG 和光栅图片(PNG / JPG / WebP)通过 Vite URL import 以 `<img>` 标签加载
### Kaku 终端支持
- macOS 上新增 Kaku 作为可选终端用于启动会话,复用 WezTerm 兼容的启动路径 (#1983, 感谢 @yovinchen)
### OMO Slim Council 支持
- 恢复 council 作为内置 oh-my-opencode-slim agent 的一等支持,更新元数据和 UI 文案 (#1982, 感谢 @yovinchen)
### 新供应商预设
- **TheRouter**:覆盖 Claude / Codex / Gemini / OpenCode / OpenClaw 五个应用 (#1891, #1892, 感谢 @cmzz)
- **DDSHub**:作为 Claude 的第三方合作伙伴供应商,含图标和推广文案
- **LionCCAPI**:覆盖全部五个应用,OpenCode / OpenClaw 使用 anthropic-messages 协议
- **胜算云 (Shengsuanyun)**:作为聚合类合作伙伴供应商覆盖全部五个应用,支持 URL 图标和本地化名称
- **PIPELLM**:覆盖 Claude / Codex / OpenCode / OpenClaw,含完整模型定义和图标
- **E-FlowCode**:覆盖全部五个应用,按应用配置不同协议
---
## 变更
### 托盘菜单组织
- 将托盘菜单重构为按应用分级的子菜单(Claude / Codex / Gemini / OpenCode / OpenClaw
- 防止菜单溢出,支持大量供应商的场景
### 代理转发栈
将代理转发层重建在 Hyper HTTP 客户端之上 (#1714, 感谢 @yovinchen)。
- 透明头部转发:头部透传,不做激进过滤
- 改进的端点重写逻辑
- 更好地支持动态上游端点
- 与新的"完整 URL 端点模式"配合,解锁非标准 URL 布局的厂商
### OAuth Auth Center UI 精修
- 精修 Auth Center 的文案、布局和图标呈现,让 Codex OAuth 登录流程更清爽
### 供应商键生命周期与 Live 同步
重做了新增模式供应商的创建/重命名/复制流程,让 Live 配置写入、清理和回滚在 OpenCode / OpenClaw 与接管场景下保持一致 (#1724, 感谢 @yovinchen)。
- 新增模式高亮行为在刷新后依旧保持 (#1747, 感谢 @yovinchen)
- OpenCode / OpenClaw 的 Live 配置写入保持一致
- 失败时正确回滚,避免半提交状态
### Codex OAuth 默认值
- Codex OAuth 预设升级到 GPT-5.4 系列
---
## Bug 修复
### Copilot 认证与代理兼容性
- 修复 GitHub Copilot 认证回归问题 (#1854, 感谢 @Mason-mengze)
- 修正企业版和动态端点处理
- 修复 macOS 和 Linux 上的剪贴板验证码复制问题
- 修复 Copilot 作为 Claude 供应商时 OpenAI 模型的 Responses 分流 (#1735, 感谢 @Mason-mengze)
### UTF-8 流式分片边界
修复 Claude Code 在 Copilot 反代下,当中文字符或 emoji 等多字节 UTF-8 序列跨 TCP 分片传输时出现的间歇性乱码(U+FFFD 替换字符)问题 (#1923, 感谢 @Cod1ng)。
- 将所有 4 条 SSE 流式路径中的 `String::from_utf8_lossy` 替换为新的 `append_utf8_safe` 辅助函数
- 通过残留缓冲区保留不完整的尾部字节,并在下一个分片合并后再解码
- 直连 Copilot 的场景不可复现,因为直连模式透传原始字节而不做格式转换
### 碎片 System Prompt 规范化
修复严格的 OpenAI 兼容 chat 后端(Nvidia、Qwen 风格)在转换后 Claude 负载包含多条 system 消息时拒绝请求的问题 (#1942, 感谢 @yovinchen)。
- 在 Anthropic → OpenAI chat 转换时将 system 内容合并为单条前置 system 消息
- 其余消息流保持不变
### 流式解析兼容性
- 修复 SSE 解析以接受包含可选空格的字段,提升对非严格流式实现的兼容性 (#1664, 感谢 @Alexlangl)
### 供应商切换状态损坏
- 将按应用的供应商切换串行化,防止并发故障转移或热切换操作导致 `is_current`、设置状态和 Live 备份状态不一致
### Claude 接管 Live 配置漂移
- 修复 Claude 接管启用时供应商编辑导致 Live 设置与供应商状态失步,同时保持接管恢复行为不被破坏 (#1828, 感谢 @geekdada)
### WebDAV 密码保留与校验
- 修复 WebDAV 密码字段在刷新后不可见的问题
- 连接校验时正确处理 `MKCOL 405` 响应 (#1685, 感谢 @Alexlangl)
### 供应商卡片动作状态
- 修复新增模式高亮行为 (#1747, 感谢 @yovinchen)
- 始终渲染动作按钮,对齐各卡片的用量显示布局
- 用警告路径替换硬阻塞的代理切换
- 禁用 Copilot 和 Codex OAuth 卡片上不受支持的测试/用量动作
- 隐藏官方供应商的用量配置和健康检查按钮
- 移除供应商卡片上的 hover 推送动画
### 用量精确性与定价
- 修复 MiniMax 配额数学和 0% → 100% 进度
- 修正 CNY → USD 定价并补齐缺失模型
- 改进 Gemini 会话日志同步的精度
- 修复基于会话的用量条目显示为"未知供应商"的问题
### 用量编辑器与 Skills UI 回归
- 修复编辑提取器代码时用量查询字段被重置的问题 (#1771, 感谢 @if-nil)
- 修正 `skills.sh` 链接失效和空描述问题
- 修复用量配置中的 auto-query 默认间隔(5 分钟)和 number-input 清空问题
### 中文 Skills 术语
- 统一 zh locale 下设置面板中的 Skills 相关标签,保持存储与同步选项用词一致
### 环境与预设兼容性
- 在 CLI 扫描中新增 Bun 全局 bin 检测 (#1742, 感谢 @makoMakoGo)
- 适配 oh-my-openagent 重命名并保持向后兼容 (#1746, 感谢 @yovinchen)
- 修正 OpenCode `kimi-for-coding` 预设 (#1738, 感谢 @makoMakoGo)
- 将 Gemini keychain 解析限制为仅 macOS
- 修复空集合时 OpenClaw 序列化器 panic (#1724, 感谢 @yovinchen)
### Linux 启动时 UI 无响应
修复长期存在的 Linux 专属 bug:窗口 UI(包括原生标题栏按钮)在用户手动最大化再还原之前无法接收点击。
- **根因 1**Tauri webview 在 Linux 上 `show()` 之后未获得键盘焦点,首次点击被 X11 / Wayland 的 click-to-activate 消费掉(Tauri #10746、wry #637
- **根因 2**:在某些 WebKitGTK / 合成器组合下,GTK surface 的输入区域在 `visible:false → show()` 路径上未能重协商,导致整个窗口无响应
- **缓解措施**:启动时设置 `WEBKIT_DISABLE_COMPOSITING_MODE=1`,并新增 `linux_fix::nudge_main_window` 辅助函数,在 show 之后 ~200ms 执行 `set_focus` + ±1px 无操作尺寸调整,等效于一次视觉上不可见的"最大化再还原"
- **覆盖范围**:接入所有窗口重新显示路径 —— 正常启动、深链接、单例、托盘 `show_main` 以及轻量模式退出返程
### Linux 标题栏拖动区域
- 在 Linux 上从顶部标题栏移除 `data-tauri-drag-region`,避免触发 Wayland 下受 Tauri #13440 影响的 `gtk_window_begin_move_drag` 路径
- macOS 拖动行为保持不变
### OpenCode / OpenClaw 流式检测边界情况
- 修复自定义头透传
- 修复 OpenClaw 自定义 auth-header 检测
- 修复 Bedrock 错误消息
- 修复 OpenCode 默认 `baseURL` 回退处理
### 供应商切换时重复 Toast
- 修复代理未运行时切换到 Copilot / ChatGPT / OpenAI 格式供应商时出现双重 toast 通知(代理必需警告 + 切换成功)
### 会话搜索精度与中文支持
- 修复会话搜索结果在跨供应商时被截断的问题
- 将 FlexSearch 分词器切换为 full 模式以支持中文子串匹配
### 自适应思维推理力度
- 修复 `resolve_reasoning_effort()` 将自适应思维错误映射为 `high`,应为 `xhigh`OpenAI 格式转换场景)
### Thinking 模型回退显示
- 修复 Claude 供应商表单仅填写主模型后 Thinking 模型字段显示为空,改为只读回退到 ANTHROPIC_MODEL (#1984, 感谢 @yovinchen)
### Auth Tab 本地化
- 修复设置面板 auth tab 标签在所有语言包中缺失 i18n 翻译 key (#1985, 感谢 @yovinchen)
### 数据库迁移守卫
- 修复 skills 或 model_pricing 表不存在时数据库迁移失败,在 ALTER 和 UPDATE 操作前添加表存在性检查
---
## 文档
### 用户手册刷新
- 在 EN / ZH / JA 用户手册中覆盖托盘子菜单、轻量模式、供应商模型获取、会话管理、工作区文件、WebDAV v2 行为、OpenCode / OpenClaw 启用等供应商工作流改进
### 社区与贡献文档
- 新增 `CONTRIBUTING.md``SECURITY.md``CODE_OF_CONDUCT.md`
- 新增双语 GitHub issue 和 PR 模板
- 新增 Dependabot 配置 (#1829, 感谢 @bengbengbalabalabeng) 和 stale-bot 工作流以自动关闭不活跃的 issue
- 新增 PR / push 质量检查 CI 工作流
### Release Notes 风险提示回填
- 在三语 v3.12.3 release notes 中新增 Copilot 反代风险提示,并为重点内容添加锚点链接
### 赞助商合作伙伴
- 在三语 README 中新增胜算云、LionCC、DDS 作为赞助商合作伙伴
---
## ⚠️ 风险提示
**Codex OAuth 反向代理免责声明**
本版本新增的 Codex OAuth 反向代理功能通过逆向工程的 OAuth 流程访问 ChatGPT 的 Codex 服务。启用此功能前,请注意以下风险:
1. **违反服务条款**:使用逆向 OAuth 流程访问 OpenAI 服务可能违反 OpenAI 的服务条款,其中禁止未经授权的自动化访问、服务复制以及绕过既定的访问路径。
2. **账号风险**:OpenAI 可能将异常使用模式标记为可疑的自动化行为,从而对 ChatGPT 访问施加临时或永久限制。
3. **无法保证长期可用**:OpenAI 可能随时更新其认证和检测机制,当前可用的使用方式未来可能被标记。
v3.12.3 引入的 **GitHub Copilot 反向代理**同样适用原有风险提示 —— 详见 [v3.12.3 release notes](v3.12.3-zh.md#-风险提示)。
用户启用上述功能即表示**自行承担所有风险**。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 |
### Windows
| 文件 | 说明 |
| ---------------------------------------- | ----------------------------------- |
| `CC-Switch-v3.13.0-Windows.msi` | **推荐** - MSI 安装包,支持自动更新 |
| `CC-Switch-v3.13.0-Windows-Portable.zip` | 便携版,解压即用,不写入注册表 |
### macOS
| 文件 | 说明 |
| -------------------------------- | --------------------------------------------- |
| `CC-Switch-v3.13.0-macOS.dmg` | **推荐** - DMG 安装包,拖入 Applications 即可 |
| `CC-Switch-v3.13.0-macOS.zip` | 解压后拖入 ApplicationsUniversal Binary |
| `CC-Switch-v3.13.0-macOS.tar.gz` | 用于 Homebrew 安装和自动更新 |
> macOS 版本已通过 Apple 代码签名和公证,可直接安装使用。
### HomebrewmacOS
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
| 发行版 | 推荐格式 | 安装方式 |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| 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` |
+469
View File
@@ -0,0 +1,469 @@
# CC Switch v3.14.0
> Hermes Agent becomes the 6th managed app, Claude Opus 4.7 rolls out across the preset matrix, Gemini Native API proxy, "Local Routing" rename, and application-level window controls
**[中文版 →](v3.14.0-zh.md) | [日本語版 →](v3.14.0-ja.md)**
---
## Overview
CC Switch v3.14.0 is a major release centered on onboarding **Hermes Agent as the 6th first-class managed app** and rolling out **Claude Opus 4.7** across the full aggregator and Bedrock preset matrix. Hermes support covers a database v9 → v10 migration, a complete Rust command surface, YAML-backed `~/.hermes/config.yaml` read/write with atomic backups, MCP sync, Skills sync, SQLite + JSONL session management, and dedicated frontend panels including a Memory editor. All four API protocols aligned with Hermes Agent 0.10.0 (`chat_completions`, `anthropic_messages`, `codex_responses`, `bedrock_converse`) are selectable. Providers owned by the user-authored `providers:` dict are rendered as read-only cards, and deep YAML configuration is delegated directly to the Hermes Web UI.
Beyond Hermes, this release adds a **Gemini Native API proxy** (`api_format = "gemini_native"`) so the proxy can forward directly to Google's `generateContent` endpoint with full streaming, schema conversion, and shadow request support; renames the legacy "Local Proxy Takeover" to **Local Routing** across UI copy, README, and docs in all three locales; introduces **application-level window controls**, an opt-in setting that materially improves the experience on Linux Wayland where compositor-drawn buttons can become inert; and bundles late additions for launching `hermes dashboard` from the toolbar, a LemonData preset across all six apps, a DDSHub Codex endpoint, plus several Hermes health-check and Usage modal fixes.
On the session side, the message list is **virtualized** via `@tanstack/react-virtual` so conversations with thousands of records scroll smoothly and long messages collapse by default; the Usage dashboard adds a **date range picker** (Today / 1d / 7d / 14d / 30d + custom date-time calendar) and a page-jump input; **Stream Check error classification** now surfaces color-coded toasts with refreshed default probe models and an explicit "model not found" branch; and switching to official providers is **blocked while Local Routing is active** to avoid account-suspension risk. The pricing database is reseeded from v8 → v9 with ~50 new model entries (Claude 4.7, Opus 4.7 Adaptive Thinking, Grok 4, Qwen 3.5/3.6, MiniMax M2.5/M2.7, Doubao Seed 2.0 series, GLM-5/5.1 and others) and corrected stale prices.
**Release Date**: 2026-04-21
**Update Scale**: 100 commits | 219 files changed | +20,548 / -3,569 lines
---
## Highlights
- **Hermes Agent Support (6th Managed App)**: Database v9 → v10 migration, full Rust command surface, YAML read/write with atomic backups, MCP sync, Skills sync, SQLite + JSONL session management, dedicated frontend panels, and four API protocols (`chat_completions` / `anthropic_messages` / `codex_responses` / `bedrock_converse`)
- **Claude Opus 4.7 Rollout**: Adaptive thinking whitelisting, per-million pricing seed, Bedrock SKU (`anthropic.claude-opus-4-7` / `global.anthropic.claude-opus-4-7`, dropping the legacy `-v1` suffix); all aggregator and Bedrock presets migrated to Opus 4.7 as the default Opus model
- **Claude `max` Effort Tier**: Effort dropdown upgraded from `high` to `max`
- **Gemini Native API Proxy**: New `api_format = "gemini_native"` forwards directly to Google's `generateContent` with full streaming / schema conversion / shadow request support
- **GitHub Copilot Enterprise Server**: GHES authentication and endpoint configuration for Copilot-backed Claude providers
- **Copilot Premium Consumption Deep Optimization**: Proactive thinking-block stripping before forwarding, `tool_result` classification fix, subagent detection, `x-interaction-id` billing merge, orphan `tool_result` sanitization, and default warmup downgrade — a systematic reduction in premium interaction consumption
- **Session List Virtualization**: Long conversations scroll smoothly and long messages collapse by default to reduce text layout cost
- **Codex / OpenClaw Session Title Extraction**: Meaningful title extraction with 2-line display; strips OpenClaw `message_id` suffix noise
- **Usage Date Range Picker**: Today / 1d / 7d / 14d / 30d preset tabs + custom date-time calendar; page-jump input on paginated lists
- **Stream Check Error Classification**: Color-coded error toasts; refreshed default probe models; explicit "model not found" detection
- **Block Official Provider Switching During Local Routing**: Routing official API traffic through the local proxy carries account-suspension risk — switches are blocked with a warning toast
- **Pricing Database Refresh (v8 → v9)**: ~50 new model entries and corrected stale prices
- **Application-Level Window Controls**: Opt-in setting to render CC Switch's own min/max/close buttons, materially improving Linux Wayland experience
- **Hermes in Unified Skills Management**: Skill install, enable, and filter now cover Hermes
- **Hermes / OpenClaw Config Directory Override**: Point CC Switch at a custom `~/.hermes/config.yaml` or `openclaw.json` location
- **Launch Hermes Dashboard from Toolbar**: When the Hermes Web UI probe fails, the toolbar entry offers to run `hermes dashboard` in the user's preferred terminal
- **New Partner Presets**: LemonData across all six apps; DDSHub Codex endpoint; StepFun Step Plan
---
## Added
### Hermes Agent Support (6th Managed App)
CC Switch now treats Hermes Agent as a first-class managed app alongside Claude / Codex / Gemini / OpenCode / OpenClaw.
- **Database Migration v9 → v10**: Adds `enabled_hermes` columns to `mcp_servers` and `skills` tables (`DEFAULT 0`, auto-migrated, no data loss)
- **YAML Configuration Read/Write**: `~/.hermes/config.yaml` read/write with atomic backups; `tests/hermes_roundtrip.rs` guards against dropped OAuth MCP `auth` blocks or pollution of unrelated YAML keys
- **Four API Protocols**: Aligned with Hermes Agent 0.10.0 — `chat_completions` / `anthropic_messages` / `codex_responses` / `bedrock_converse`; new deeplinks default to `chat_completions`
- **User `providers:` Dict Read-Only Rendering**: User-authored providers in the YAML appear as read-only cards in CC Switch; deep configuration delegates to the Hermes Web UI
- **Additive Switching**: Unlike Claude / Codex's "override" style, all Hermes providers coexist in the same YAML
### Hermes Memory Panel
- New Memory panel for editing `MEMORY.md` / `USER.md` directly, with an enable switch, character-count limits, and a live save flow
- Replaces the Prompts entry for Hermes
### Hermes Provider Presets (~50)
- Covers Nous Research, Shengsuanyun, OpenRouter, DeepSeek, Together AI, StepFun, Zhipu GLM, Bailian, Kimi, MiniMax, DouBao, BaiLing, ModelScope, KAT-Coder, PackyCode, Cubence, AIGoCode, RightCode, AICodeMirror, AICoding, CrazyRouter, SSSAiCode, Micu, CTok.ai, DDSHub, E-FlowCode, LionCCAPI, PIPELLM, Compshare, SiliconFlow, AiHubMix, DMXAPI, TheRouter, Novita, Nvidia, and Xiaomi MiMo
### Launch Hermes Dashboard from Toolbar
- When the Hermes Web UI probe fails, the toolbar entry opens a confirm dialog offering to run `hermes dashboard` in the user's preferred terminal
- Spawned via a temp bash / batch script; `hermes dashboard` opens the browser itself once ready, so no polling is required
- The Memory panel and Health banner keep the existing toast behavior
- Also corrects the stale `hermes web` hint in the offline toast (the real command is `hermes dashboard`)
- Linux terminal detection reordered to try `which` before stat'ing `/usr/bin`, `/bin`, `/usr/local/bin`
### Claude Opus 4.7 Support
- New Claude Opus 4.7 with adaptive thinking whitelisting, per-million pricing seed, and Bedrock SKU (`anthropic.claude-opus-4-7` / `global.anthropic.claude-opus-4-7`, dropping the legacy `-v1` suffix)
- All aggregator and Bedrock presets migrated to Opus 4.7 as the default Opus model
### Claude `max` Effort Tier
- Claude effort dropdown upgraded from `high` to `max` for extended reasoning capacity
### Gemini Native API Proxy
- New `api_format = "gemini_native"` so the proxy can forward directly to Google's `generateContent` API (#1918, thanks @yovinchen)
- Full streaming, schema conversion, and shadow request support
- Adds `gemini_url.rs`, `gemini_schema.rs`, `gemini_shadow.rs`, `streaming_gemini.rs`, and `transform_gemini.rs` under the proxy providers module
### GitHub Copilot Enterprise Server (GHES)
- GHES authentication and endpoint configuration for Copilot-backed Claude providers (#2175, thanks @hotelbe)
### Session List Virtualization
- Virtualized the session list via `@tanstack/react-virtual` so long conversations (thousands of records) scroll smoothly
- Long session messages are collapsed by default to reduce text layout cost
### Codex / OpenClaw Session Title Extraction
- Meaningful title auto-extraction for Codex and OpenClaw sessions with 2-line display
- Strips OpenClaw `message_id` suffix noise
### Usage Date Range Picker
- New date range selector on the usage dashboard with preset tabs (Today / 1d / 7d / 14d / 30d) + custom date + time calendar (#2002, thanks @yovinchen)
- Page-jump input added on paginated lists
### Model Mapping Quick-Set
- New quick-set button next to model mapping fields in provider forms for faster edits (#2179, thanks @lispking)
### Stream Check Error Classification
- Stream Check errors are classified and surfaced as color-coded toasts
- Refreshed default probe models to match each vendor's current lineup
- Explicit detection for "model not found" responses
### Block Official Provider Switching During Local Routing
- Switching to official providers is blocked while Local Routing is active, with a warning toast
- Reason: routing official API traffic through the local proxy carries account-suspension risk
### Pricing Database Refresh (v8 → v9)
- Reseed-on-migration pricing table
- ~50 new model pricing entries including Claude 4.7, Opus 4.7 Adaptive Thinking, Grok 4, Qwen 3.5/3.6, MiniMax M2.5/M2.7, Doubao Seed 2.0 series, GLM-5/5.1
- Corrected stale prices for DeepSeek, Kimi K2.5, and others
### Application-Level Window Controls
- Opt-in setting to render CC Switch's own minimize / toggle-maximize / close buttons instead of system decorations (#1119, thanks @git1677967754)
- Materially improves the experience on Linux Wayland where compositor-drawn buttons can become inert
### Hermes in Unified Skills Management
- Hermes is added to the unified Skills surface
- Skill install, enable, and filter now cover the Hermes app alongside Claude / Codex / Gemini / OpenCode / OpenClaw
### OpenClaw Config Directory Override
- New settings option to point CC Switch at a custom `openclaw.json` location (#1518, thanks @mrFranklin)
### Hermes Config Directory Override
- New settings option to point CC Switch at a custom `~/.hermes/config.yaml` location, backed by data-driven dispatch
### StepFun Step Plan Preset
- StepFun Step Plan (EN / ZH) provider presets (#2155, thanks @hengm3467)
### New API Usage Script Template
- Added a User-Agent header to the New API usage script template for better upstream compatibility
### LemonData Provider Preset (All Six Apps)
- LemonData registered as a third-party partner preset across Claude, Codex, Gemini, OpenCode, OpenClaw, and Hermes
- Icon assets and zh / en / ja partner-promotion copy
- Claude preset uses `ANTHROPIC_API_KEY` auth; OpenAI-compatible apps target `gpt-5.4`
### DDSHub Codex Preset
- Added a Codex-compatible endpoint for DDSHub at the same host as its Claude service
- Base URL omits the `/v1` suffix because the gateway auto-routes OpenAI SDK paths
---
## Changed
### "Local Proxy Takeover" → "Local Routing"
- Unified the terminology across UI copy, README, and docs in all three locales
- Functional behavior is unchanged
### Hermes `Auto` api_mode Removed
- Users must pick an explicit protocol; new deeplinks default to `chat_completions`
- Eliminates URL-based heuristic surprises
### Hermes Provider Form
- Added an API mode dropdown and per-provider model editor
- Binds per-provider models to the top-level `model:` when switching active providers
### Hermes Deep Config Delegation
- Deep YAML knobs are no longer duplicated in the CC Switch form — they are delegated to the Hermes Web UI via a direct launch action
### Hermes Toolbar Layout
- Swapped the Hermes Web UI button from `ExternalLink` to `LayoutDashboard` (clicking may spawn `hermes dashboard` rather than just opening a URL)
- Moved MCP to the final toolbar slot so Hermes matches the Claude / Codex / Gemini / OpenCode layout
### `ANTHROPIC_REASONING_MODEL` Removed from Claude Quick-Set
- Decoupled the reasoning capability from model selection; the legacy field is no longer surfaced in the quick-set form
### Per-Provider Proxy Config Removed
- Consolidated into global Local Routing
- Provider-level proxy toggle and associated storage are gone
### Unified Toolbar Icon Button Width
- Normalized icon-button widths across Claude / Codex / Gemini / OpenCode / OpenClaw / Hermes panels for a consistent header look
### Rust Toolchain Pinned to 1.95
- Adopted clippy 1.95 suggestions across the workspace and pinned the toolchain to prevent nightly drift
### Tray Menu ID Constant
- The tray identifier moved from the hardcoded string `"main"` to a `TRAY_ID` constant (`"cc-switch"`) across all call sites (#1978, thanks @lidaxian121)
### Copilot Premium Consumption Deep Optimization
A systematic overhaul to reduce Copilot reverse-proxy premium interaction consumption across multiple dimensions:
- **Proactive Thinking Block Stripping Before Forwarding**: Anthropic's `thinking` / `redacted_thinking` blocks are rejected by OpenAI-compatible endpoints. Previously, the request failed upstream, burning one premium interaction before the `thinking_rectifier` could retry. A new proactive strip step (Copilot optimization pipeline step 3.5, after `tool_result` merging) eliminates that wasted interaction
- **Request Classification Fix**: Messages containing `tool_result` are now classified as agent continuation instead of user-initiated, preventing every tool call from being falsely counted as a premium interaction
- **Subagent Detection**: Identifies subagents via `__SUBAGENT_MARKER__` with `metadata._agent_` fallback, setting `x-interaction-type=conversation-subagent`
- **Deterministic `x-interaction-id` Billing Merge**: Derives `x-interaction-id` from the session ID so multiple requests within the same session collapse into a single billing interaction
- **Orphan `tool_result` Sanitization**: Cleans up orphan `tool_result` entries to prevent upstream errors that would trigger retries and duplicate billing
- **Warmup Downgrade Enabled by Default**: Uses `gpt-5-mini` as the default downgrade model
- **Optimization Pipeline Reorder**: classify → sanitize → merge → warmup, so classification sees raw `tool_result` semantics
- Fixed a `CopilotOptimizerConfig` default-value inconsistency (unified to `gpt-5-mini`)
### Usage Script Intranet Support
- Removed private-IP / suspicious-hostname blocking from usage scripts, unblocking enterprise intranet, Docker, and self-hosted API endpoints
- Built-in templates still enforce HTTPS (except localhost) and same-origin checks; custom templates remain user-controlled with those request-URL checks skipped
### Failover Queue Notes
- Provider notes now appear in failover queue selectors and queue rows for easier identification across multi-provider queues (#2138, thanks @Coconut-Fish)
---
## Fixed
### Header Auto-Compact Latching After Maximize
- The toolbar no longer stays compacted after maximize/restore; compaction now reevaluates on size changes
### Hermes YAML Pollution & OAuth MCP `auth` Drop
- Round-tripping through CC Switch no longer drops OAuth MCP `auth` blocks or pollutes unrelated YAML keys
- Guard tests added via `tests/hermes_roundtrip.rs`
### Hermes Active Provider Display
- Hermes UI now correctly surfaces the active provider and wires add / enable / remove actions
### Hermes Provider Persistence
- Providers persist under `custom_providers:` so `api_mode` and `model` survive restarts and config reloads
### Hermes Health Check Borrowing OpenClaw Schema
- Hermes providers were routed through `check_additive_app_stream` (the OpenClaw dispatcher), which reads camelCase `baseUrl` / `apiKey` / `api` and surfaced "OpenClaw provider is missing baseUrl" even when every Hermes field was filled
- Introduced `check_hermes_stream` with Hermes-specific extractors that map `api_mode` (`chat_completions` / `anthropic_messages` / `codex_responses`) to the matching `check_claude_stream` `api_format`; `bedrock_converse` returns as unsupported
- `api_mode` is now resolved before URL / API key extraction, so `bedrock_converse` users see the real cause rather than a misleading "missing base_url"
### Usage Query Modal for Hermes & OpenClaw
- `getProviderCredentials` now reads flat `settingsConfig` fields for Hermes (snake_case `base_url` / `api_key`) and OpenClaw (camelCase `baseUrl` / `apiKey`), so the "official balance" template auto-selects for matching providers like SiliconFlow
- Refactored the BALANCE and TOKEN_PLAN test paths to reuse the precomputed `providerCredentials` instead of re-reading `env.ANTHROPIC_*` directly, fixing the "empty key" error for non-Claude apps even when the key was configured
### Codex `cache_control` Preservation
- Preserve `cache_control` when merging system prompts during Codex format conversion (#1946, thanks @yovinchen)
### Claude Prompt Cache Key Leak
- Stopped sending prompt cache keys during Claude chat conversions (#2003, thanks @yovinchen)
### Proxy Hop-by-Hop Header Stripping
- Strip hop-by-hop response headers (Connection, Keep-Alive, Transfer-Encoding, etc.) per RFC 7230 (#2060, thanks @yovinchen)
### Permissive Proxy CORS Removed
- Removed the permissive CORS layer from the proxy (#1915, thanks @zerone0x)
### Backend Error Details in Proxy Toast
- Surface backend error payload details in proxy-related toast messages instead of a generic failure string
### Usage Log Deduplication
- Deduplicated proxy and session-log usage records so the same request is no longer double-counted
- Synced the request log time range with the dashboard's 1d / 7d / 30d selector
### Common Config Checkbox Persistence
- Checkbox state for Claude / Codex / Gemini common-config toggles now persists correctly across reopens (#2191, thanks @zxZeng)
### Claude Plugin `settings.json` Sync
- Editing the current provider now syncs back to `settings.json` for the Claude plugin path (#1905, thanks @chengww5217)
### Google Official Gemini Env Preservation
- Saving the Google Official Gemini provider no longer clobbers the `env` block
### OpenCode JSON5 Parser for Trailing Commas
- OpenCode config reads now tolerate trailing commas via a JSON5 parser (#2023, thanks @wwminger)
### Preset Refreshes
- Refreshed stale context windows for DeepSeek and Claude 1M
- Refreshed stale model IDs; backfilled Hermes model lists
- Fixed the Nous endpoint and replaced the Hermes placeholder icon with Nous brand artwork
- Pruned unused official Hermes presets
### Auto-Expand Collapsed Messages on Search Hit
- Collapsed messages now auto-expand when a search match lands inside hidden content
### Unknown Subscription Quota Tiers Hidden
- Provider cards no longer render unknown subscription quota tiers
### Weekly Limit Label Unified
- Aligned the `weekly_limit` tier label with the official 7-day naming across locales
### Root-Level Skill Repo Install
- Fixed skill installation when the repository root itself is a skill
### Session ID Parsing Clippy
- Removed a redundant closure in session ID parsing (clippy warning)
### Stream Check Default Models Refresh
- Updated stream-check default probe models to match each vendor's current lineup
### Skills Import Sync
- Imported Skills are now immediately synced into enabled app directories instead of only being recorded in the database (#2101, thanks @yaoguohh)
- The UI no longer shows "installed" while the target app directory is missing the skill
### Ghostty Session Restore
- Fixed Ghostty session restore launch by using shell execution with `--working-directory` (#1976, thanks @Suda202)
- Avoids `cwd` escaping issues when the path contains spaces or special characters
---
## Docs
### README Sponsor Updates
- Updated SiliconFlow signup bonus to ¥16
- Trimmed the SSSAiCode sponsor blurb
- Updated partner logos
- Added LemonData as a new sponsor
### Global Proxy Hint Clarified
- Clarified the global proxy hint about local routing across all three locales
### Takeover → Routing Rename
- Renamed takeover docs to routing and updated anchors across all languages
### PIPELLM Website URL
- Updated the PIPELLM sponsor website URL to `code.pipellm.ai`
---
## ⚠️ Breaking Changes
### Hermes requires explicit `api_mode`
- The `Auto` mode is gone; imported or deeplinked providers default to `chat_completions`
- Users with prior `Auto` configs will be prompted to pick a protocol
### `ANTHROPIC_REASONING_MODEL` removed from Claude quick-set
- The legacy field is no longer exposed; existing settings are cleaned up automatically
### Per-provider proxy configuration removed
- Migrate to the global Local Routing setting
- Existing per-provider proxy values are ignored
### Database schema v9 → v10
- Adds `enabled_hermes` columns to `mcp_servers` and `skills`
- Auto-migrated with `DEFAULT 0`; no data loss
### Pricing table reseeded (v8 → v9)
- The `model_pricing` table is cleared and reseeded on first launch to pick up new models and corrected prices
### XCodeAPI preset removed
- Users of the XCodeAPI preset should switch to another provider
---
## ⚠️ 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 [v3.12.3 release notes](v3.12.3-en.md#-risk-notice).
**Codex OAuth Reverse Proxy**: Using the Codex OAuth reverse proxy with a ChatGPT subscription may violate OpenAI's terms of service. See [v3.13.0 release notes](v3.13.0-en.md#-risk-notice).
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 |
### Windows
| File | Description |
| ---------------------------------------- | ----------------------------------------------- |
| `CC-Switch-v3.14.0-Windows.msi` | **Recommended** - MSI installer, supports auto-update |
| `CC-Switch-v3.14.0-Windows-Portable.zip` | Portable, extract and run, no registry writes |
### macOS
| File | Description |
| -------------------------------- | -------------------------------------------------------- |
| `CC-Switch-v3.14.0-macOS.dmg` | **Recommended** - DMG installer, drag into Applications |
| `CC-Switch-v3.14.0-macOS.zip` | Extract and drag into Applications, Universal Binary |
| `CC-Switch-v3.14.0-macOS.tar.gz` | For Homebrew installation and auto-update |
> macOS builds are Apple code-signed and notarized — install directly.
### Homebrew (macOS)
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
Update:
```bash
brew upgrade --cask cc-switch
```
### Linux
| 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` |
+469
View File
@@ -0,0 +1,469 @@
# CC Switch v3.14.0
> Hermes Agent が 6 番目の管理対象アプリに、Claude Opus 4.7 をプリセットマトリクス全体へ展開、Gemini Native API プロキシ、「Local Routing」への名称統一、アプリケーションレベルのウィンドウコントロール
**[中文版 →](v3.14.0-zh.md) | [English →](v3.14.0-en.md)**
---
## 概要
CC Switch v3.14.0 は、**Hermes Agent を 6 番目の一等管理対象アプリケーション**として CC Switch に取り込み、**Claude Opus 4.7** をアグリゲーターおよび Bedrock プリセットのマトリクス全体に展開することを中心に据えた大型リリースです。Hermes サポートは、データベース v9 → v10 マイグレーション、完全な Rust コマンド面、アトミックバックアップ付きの YAML ベースな `~/.hermes/config.yaml` 読み書き、MCP 同期、Skills 同期、SQLite + JSONL セッション管理、および Memory エディターを含む専用のフロントエンドパネルをカバーします。Hermes Agent 0.10.0 スキーマに整合する 4 つの API プロトコル(`chat_completions``anthropic_messages``codex_responses``bedrock_converse`)すべてを選択可能です。ユーザーが直接記述した `providers:` dict のエントリは読み取り専用カードとして表示され、深い YAML 設定は Hermes Web UI に委譲されます。
Hermes に加えて、本リリースでは **Gemini Native API プロキシ**`api_format = "gemini_native"`)を追加し、プロキシがリクエストを Google の `generateContent` エンドポイントに直接転送できるようにしました(完全なストリーミング、スキーマ変換、シャドウリクエストをサポート)。また、旧「Local Proxy Takeover」を三言語の UI / README / ドキュメント全体で **Local Routing** に統一リネームし、コンポジターが描画するボタンが無反応になり得る Linux Wayland などのシーンで、CC Switch が自前で最小化 / 最大化 / 閉じるボタンを描画できるオプション「**アプリケーションレベルのウィンドウコントロール**」を導入しました。さらにリリース直前に、ツールバーからの `hermes dashboard` 直接起動、LemonData の全アプリプリセット、DDSHub の Codex エンドポイント、および複数の Hermes ヘルスチェックと Usage モーダルの修正が追加されました。
セッション側では、`@tanstack/react-virtual` によるセッションリストの**仮想化**で数千件のレコードを持つ長い会話も滑らかにスクロールでき、長いメッセージはデフォルトで折り畳まれます。Usage ダッシュボードには**日付範囲ピッカー**(今日 / 1d / 7d / 14d / 30d + カスタム日時カレンダー)とページジャンプ入力が追加され、**Stream Check エラー分類**は色分けされたトーストで提示され、デフォルトの探索モデルが更新され、「モデルが見つからない」レスポンスを個別に識別するようになりました。また、Local Routing が有効な間に公式プロバイダーへの切り替えを**強制的にブロック**する保護を追加し、公式 API トラフィックがローカルプロキシを経由することによるアカウント停止リスクを防ぎます。Pricing データベースは v8 → v9 で再シードされ、約 50 件の新しいモデルエントリ(Claude 4.7、Opus 4.7 Adaptive Thinking、Grok 4、Qwen 3.5/3.6、MiniMax M2.5/M2.7、Doubao Seed 2.0 系列、GLM-5/5.1 など)を追加し、いくつかの古い価格を修正しました。
**リリース日**: 2026-04-21
**更新規模**: 100 commits | 219 files changed | +20,548 / -3,569 lines
---
## ハイライト
- **Hermes Agent サポート(6 番目の管理対象アプリ)**: データベース v9 → v10 マイグレーション、完全な Rust コマンド面、アトミックバックアップ付き YAML 読み書き、MCP 同期、Skills 同期、SQLite + JSONL セッション管理、専用フロントエンドパネル、4 つの API プロトコル(`chat_completions` / `anthropic_messages` / `codex_responses` / `bedrock_converse`
- **Claude Opus 4.7 の全面展開**: 適応的思考のホワイトリスト、百万トークン単位の価格シード、Bedrock SKU(`anthropic.claude-opus-4-7` / `global.anthropic.claude-opus-4-7`、旧 `-v1` サフィックスを廃止)、全アグリゲーター / Bedrock プリセットを Opus 4.7 をデフォルト Opus モデルに移行
- **Claude `max` エフォートティア**: エフォートのドロップダウンを `high` から `max` に引き上げ
- **Gemini Native API プロキシ**: 新しい `api_format = "gemini_native"` により、プロキシが Google の `generateContent` に直接転送可能に(完全なストリーミング / スキーマ変換 / シャドウリクエスト対応)
- **GitHub Copilot Enterprise Server**: Copilot ベースの Claude プロバイダーに GHES 認証とエンドポイント設定を追加
- **Copilot 交互消費の大幅最適化**: 転送前の thinking ブロック主動削除、`tool_result` メッセージ分類修正、subagent 検出、`x-interaction-id` 課金マージ、孤立 `tool_result` のサニタイズ、Warmup ダウングレードのデフォルト有効化など、premium 交互消費を系統的に削減
- **セッションリスト仮想化**: 長い会話が滑らかにスクロール。長いメッセージはデフォルトで折り畳まれ、テキストレイアウトコストを削減
- **Codex / OpenClaw セッションタイトル抽出**: 意味のあるタイトルを自動抽出(2 行表示)、OpenClaw の `message_id` 末尾ノイズを除去
- **Usage 日付範囲ピッカー**: Today / 1d / 7d / 14d / 30d プリセットタブ + カスタム日時カレンダー。ページネーションリストにページジャンプ入力
- **Stream Check エラー分類**: エラーを分類し色分けトーストで提示。デフォルト探索モデル更新。「モデルが見つからない」レスポンスを明示的に検出
- **Local Routing 有効時の公式プロバイダー切り替えブロック**: 公式 API トラフィックをローカルプロキシ経由で流すとアカウント停止のリスクがあるため、切り替えを強制ブロックして警告トーストを表示
- **Pricing データベース刷新(v8 → v9)**: 約 50 件の新しいモデルエントリを追加し、古い価格を修正
- **アプリケーションレベルのウィンドウコントロール**: CC Switch が自前で最小化 / 最大化トグル / 閉じるボタンを描画するオプション設定。Linux Wayland での体験を大きく改善
- **統一 Skills 管理への Hermes 追加**: Skill のインストール / 有効化 / フィルターが Hermes をカバー
- **Hermes / OpenClaw 設定ディレクトリのカスタマイズ**: 設定で `~/.hermes/config.yaml``openclaw.json` のカスタム位置を指定可能
- **ツールバーからの Hermes Dashboard 起動**: Hermes Web UI のプローブに失敗した際、ツールバーエントリからユーザーの優先ターミナルで `hermes dashboard` を実行可能
- **新パートナープリセット**: LemonData を全 6 アプリにわたって追加、DDSHub の Codex エンドポイント、StepFun Step Plan
---
## 新機能
### Hermes Agent サポート(6 番目の管理対象アプリ)
CC Switch は Hermes Agent を Claude / Codex / Gemini / OpenCode / OpenClaw と並ぶ一等の管理対象アプリとして初めてサポートします。
- **データベースマイグレーション v9 → v10**: `mcp_servers``skills` テーブルに `enabled_hermes` カラムを追加(`DEFAULT 0`、自動マイグレーション、データ損失なし)
- **YAML 設定の読み書き**: `~/.hermes/config.yaml` をアトミックバックアップ付きで読み書き。`tests/hermes_roundtrip.rs` が OAuth MCP `auth` ブロックの消失や無関係なキーの汚染を防止
- **4 つの API プロトコル**: Hermes Agent 0.10.0 と整合する `chat_completions` / `anthropic_messages` / `codex_responses` / `bedrock_converse`。新しいディープリンクはデフォルトで `chat_completions`
- **ユーザー `providers:` dict の読み取り専用表示**: YAML に手書きされたプロバイダーエントリは CC Switch で読み取り専用カードとして表示され、深い設定は Hermes Web UI に委譲
- **加算的な切り替え**: Claude / Codex の「上書き」型切り替えと異なり、Hermes ではすべてのプロバイダーが同じ YAML に共存
### Hermes Memory パネル
- `MEMORY.md` / `USER.md` を直接編集できる Memory パネルを追加(有効化スイッチ、文字数制限、ライブ保存フロー付き)
- Hermes の Prompts エントリを置き換え
### Hermes プロバイダープリセット(約 50 個)
- Nous Research、Shengsuanyun(胜算云)、OpenRouter、DeepSeek、Together AI、StepFun、Zhipu GLM、Bailian(百炼)、Kimi、MiniMax、DouBao(豆包)、BaiLing(百灵)、ModelScope(魔搭)、KAT-Coder、PackyCode、Cubence、AIGoCode、RightCode、AICodeMirror、AICoding、CrazyRouter、SSSAiCode、Micu、CTok.ai、DDSHub、E-FlowCode、LionCCAPI、PIPELLM、Compshare、SiliconFlow、AiHubMix、DMXAPI、TheRouter、Novita、Nvidia、Xiaomi MiMo をカバー
### ツールバーからの Hermes Dashboard 起動
- Hermes Web UI のプローブに失敗した際、ツールバーエントリがユーザーの優先ターミナルで `hermes dashboard` を実行する確認ダイアログを表示
- 一時 bash / batch スクリプト経由で起動。`hermes dashboard` 自身が準備完了後にブラウザを開くため、ポーリングは不要
- Memory パネルと Health バナーは既存のトースト動作を維持
- オフラインのトーストにあった古い `hermes web` のヒントも修正(正しいコマンドは `hermes dashboard`
- Linux ターミナル検出の順序を変更し、`/usr/bin``/bin``/usr/local/bin` を stat する前に `which` を試すように
### Claude Opus 4.7 サポート
- Claude Opus 4.7 を追加。適応的思考のホワイトリスト、百万トークン単位の価格シード、Bedrock SKU(`anthropic.claude-opus-4-7` / `global.anthropic.claude-opus-4-7`、旧 `-v1` サフィックスを廃止)
- 全アグリゲーター / Bedrock プリセットをデフォルト Opus モデルとして Opus 4.7 に移行
### Claude `max` エフォートティア
- Claude エフォートドロップダウンを `high` から `max` に引き上げ、より強力な推論容量を解放
### Gemini Native API プロキシ
- 新しい `api_format = "gemini_native"` により、プロキシが Google の `generateContent` API に直接転送可能 (#1918, 感謝 @yovinchen)
- 完全なストリーミング、スキーマ変換、シャドウリクエストに対応
- proxy providers モジュール下に `gemini_url.rs``gemini_schema.rs``gemini_shadow.rs``streaming_gemini.rs``transform_gemini.rs` を追加
### GitHub Copilot Enterprise ServerGHES
- Copilot ベースの Claude プロバイダーに GHES 認証とエンドポイント設定を追加 (#2175, 感謝 @hotelbe)
### セッションリスト仮想化
- `@tanstack/react-virtual` によりセッションリストを仮想化。数千件のレコードを持つ長い会話も滑らかにスクロール
- 長いセッションメッセージはデフォルトで折り畳まれ、テキストレイアウトコストを削減
### Codex / OpenClaw セッションタイトル抽出
- Codex と OpenClaw セッションから意味のあるタイトルを自動抽出し、2 行表示
- OpenClaw の `message_id` 末尾ノイズを除去
### Usage 日付範囲ピッカー
- Usage ダッシュボードに日付範囲セレクターを追加。プリセットタブ(Today / 1d / 7d / 14d / 30d+ カスタム日時カレンダー (#2002, 感謝 @yovinchen)
- ページネーションリストにページジャンプ入力を追加
### モデルマッピングのクイック入力
- プロバイダーフォームのモデルマッピングフィールドの横にクイック入力ボタンを追加し、編集を高速化 (#2179, 感謝 @lispking)
### Stream Check エラー分類
- Stream Check エラーを分類し、色分けトーストとして提示
- デフォルトの探索モデルを各ベンダーの現行ラインナップに合わせて更新
- 「モデルが見つからない」レスポンスを明示的に検出
### Local Routing 有効時の公式プロバイダー切り替えブロック
- Local Routing が有効な状態で公式プロバイダーに切り替えようとすると、強制的にブロックされ警告トーストが表示される
- 理由: 公式 API トラフィックをローカルプロキシ経由で流すとアカウント停止のリスクがあるため
### Pricing データベース刷新(v8 → v9)
- マイグレーション時に定価テーブルを再シード
- Claude 4.7、Opus 4.7 Adaptive Thinking、Grok 4、Qwen 3.5/3.6、MiniMax M2.5/M2.7、Doubao Seed 2.0 系列、GLM-5/5.1 などを含む約 50 件の新しいモデルエントリを追加
- DeepSeek、Kimi K2.5 などの古い価格を修正
### アプリケーションレベルのウィンドウコントロール
- CC Switch が自前で最小化 / 最大化トグル / 閉じるボタンを描画するオプション設定を追加。システム装飾の代わりに使用 (#1119, 感謝 @git1677967754)
- コンポジター描画ボタンが無反応になり得る Linux Wayland での体験を大きく改善
### 統一 Skills 管理への Hermes 追加
- 統一 Skills サーフェスに Hermes を追加
- Skill のインストール / 有効化 / フィルターが、Claude / Codex / Gemini / OpenCode / OpenClaw と並んで Hermes アプリをカバー
### OpenClaw 設定ディレクトリのカスタマイズ
- CC Switch が参照する `openclaw.json` のカスタム位置を設定できるオプションを追加 (#1518, 感謝 @mrFranklin)
### Hermes 設定ディレクトリのカスタマイズ
- CC Switch が参照する `~/.hermes/config.yaml` のカスタム位置を設定できるオプションを追加。データ駆動 dispatch でサポート
### StepFun Step Plan プリセット
- StepFun Step PlanEN / ZH)プロバイダープリセットを追加 (#2155, 感謝 @hengm3467)
### New API 用量スクリプトテンプレート
- New API の用量スクリプトテンプレートに User-Agent ヘッダーを追加し、上流互換性を向上
### LemonData プロバイダープリセット(全 6 アプリ)
- LemonData をサードパーティパートナープリセットとして Claude、Codex、Gemini、OpenCode、OpenClaw、Hermes の全 6 アプリに登録
- アイコンアセットと zh / en / ja 三言語のパートナー推奨文面を追加
- Claude プリセットは `ANTHROPIC_API_KEY` 認証を使用。OpenAI 互換アプリは `gpt-5.4` をターゲット
### DDSHub Codex プリセット
- DDSHub の Codex 互換エンドポイントを追加(Claude サービスと同じホスト)
- ベース URL は `/v1` サフィックスを省略(ゲートウェイが OpenAI SDK パスを自動ルーティング)
---
## 変更
### 「Local Proxy Takeover」→「Local Routing」
- 三言語の UI 文言、README、ドキュメント全体で用語を統一リネーム
- 機能的な動作は変更なし
### Hermes `Auto` api_mode の削除
- ユーザーは明示的にプロトコルを選択する必要あり。新しいディープリンクはデフォルトで `chat_completions`
- URL ベースのヒューリスティックによる意外な挙動を排除
### Hermes プロバイダーフォーム
- API モードドロップダウンとプロバイダー単位のモデルエディターを追加
- アクティブなプロバイダーを切り替える際、プロバイダー単位のモデルをトップレベルの `model:` にバインド
### Hermes 深い設定の委譲
- 深い YAML 設定は CC Switch フォームで重複させず、「Hermes Web UI を起動」ボタン経由で Web UI に直接委譲
### Hermes ツールバーレイアウト
- Hermes Web UI ボタンのアイコンを `ExternalLink` から `LayoutDashboard` に変更(クリック時に単に URL を開くのではなく `hermes dashboard` を起動する場合があるため、パネル型アイコンのほうが意味的に正確)
- MCP をツールバーの末尾に移動し、Hermes のレイアウトを Claude / Codex / Gemini / OpenCode と揃える
### Claude Quick-Set から `ANTHROPIC_REASONING_MODEL` を削除
- 推論能力とモデル選択を分離。レガシーフィールドは Quick-Set フォームから除外
### プロバイダー単位のプロキシ設定を削除
- グローバルな Local Routing に統合
- プロバイダー単位のプロキシトグルと関連ストレージは削除済み
### ツールバーアイコンボタン幅の統一
- Claude / Codex / Gemini / OpenCode / OpenClaw / Hermes パネルの間でアイコンボタン幅を正規化し、ヘッダーの見た目を統一
### Rust Toolchain を 1.95 にピン留め
- ワークスペース全体で clippy 1.95 の提案を採用し、nightly ドリフトを防ぐためツールチェーンをピン留め
### トレイメニュー ID 定数
- トレイ識別子をハードコーディング文字列 `"main"` から `TRAY_ID` 定数(`"cc-switch"`)に移行。すべての呼び出し箇所で同期 (#1978, 感謝 @lidaxian121)
### Copilot 交互消費の大幅最適化
Copilot リバースプロキシの premium 交互消費を削減するための系統的な最適化。以下の複数の改善をカバー:
- **転送前に thinking ブロックを主動削除**: Anthropic の `thinking` / `redacted_thinking` ブロックは OpenAI 互換エンドポイントに拒否される。従来は上流でリクエストが失敗して premium 交互を 1 回消費した後、`thinking_rectifier` によってリトライされていた。新しい主動削除ステップ(Copilot 最適化パイプラインの 3.5 ステップ目、`tool_result` マージ後)により、この無駄な premium 消費を直接解消
- **リクエスト分類の修正**: `tool_result` を含むメッセージをユーザー発起の新規リクエストではなく、エージェント継続として分類。ツール呼び出しが毎回 premium 交互としてカウントされる問題を防止
- **subagent 検出**: `__SUBAGENT_MARKER__``metadata._agent_` フォールバックで subagent を識別し、`x-interaction-type=conversation-subagent` を設定
- **決定論的 `x-interaction-id` による課金マージ**: セッション ID から `x-interaction-id` を導出し、同一セッション内の複数リクエストを 1 回の課金交互に統合
- **孤立 `tool_result` のサニタイズ**: 孤立した `tool_result` を整理し、上流エラーによるリトライおよび重複課金を防止
- **Warmup ダウングレードをデフォルトで有効化**: `gpt-5-mini` をデフォルトのダウングレードモデルとして使用
- **最適化パイプラインの並び替え**: classify → sanitize → merge → warmup の順序で、分類が生の `tool_result` セマンティクスを参照可能に
- `CopilotOptimizerConfig` のデフォルト値の不一致を修正(`gpt-5-mini` に統一)
### 用量スクリプトのイントラネットサポート
- 用量スクリプトからプライベート IP / 不審なホスト名のブロッキングを削除し、エンタープライズイントラネット、Docker、自己ホスト API エンドポイントを解放
- ビルトインテンプレートは引き続き HTTPS(localhost を除く)と同一オリジンチェックを強制。カスタムテンプレートはユーザー制御のまま、リクエスト URL のチェックをスキップ
### Failover キューの備考表示
- プロバイダーの備考が failover キューセレクターとキュー行に表示され、マルチプロバイダーキューでの識別が容易に (#2138, 感謝 @Coconut-Fish)
---
## バグ修正
### 最大化後のツールバー自動折り畳みラッチ
- ウィンドウの最大化 / 復元後、ツールバーが折り畳まれたままになる問題を修正。折り畳み判定はサイズ変更時に再評価される
### Hermes YAML 汚染と OAuth MCP `auth` 消失
- CC Switch 経由でラウンドトリップしても OAuth MCP `auth` ブロックが消失したり、無関係な YAML キーが汚染されたりしなくなった
- `tests/hermes_roundtrip.rs` をガードテストとして追加
### Hermes アクティブプロバイダー表示
- Hermes UI がアクティブプロバイダーを正しく表示するようになり、追加 / 有効化 / 削除アクションが正しく動作
### Hermes プロバイダーの永続化
- プロバイダーは `custom_providers:` の下に永続化され、`api_mode``model` が再起動 / 設定再読み込みを生き延びる
### Hermes ヘルスチェックが OpenClaw のスキーマを流用していた問題
- 以前 Hermes プロバイダーは `check_additive_app_stream`(OpenClaw のディスパッチャー)にルーティングされており、これは camelCase の `baseUrl` / `apiKey` / `api` を読むため、Hermes フィールドをすべて記入しても "OpenClaw provider is missing baseUrl" と表示されていた
- `check_hermes_stream` を導入し、Hermes 専用のエクストラクターで `api_mode``chat_completions` / `anthropic_messages` / `codex_responses`)を対応する `check_claude_stream``api_format` にマッピング。`bedrock_converse` は非対応として返す
- URL / API キーの抽出前に `api_mode` を解決することで、`bedrock_converse` を選んだユーザーには「missing base_url」という誤解を招くメッセージではなく実際の原因が表示される
### Hermes / OpenClaw 向け Usage クエリモーダル
- `getProviderCredentials` が Hermessnake_case の `base_url` / `api_key`)と OpenClawcamelCase の `baseUrl` / `apiKey`)のフラットな `settingsConfig` フィールドを読むようになり、SiliconFlow などマッチするプロバイダーで「official balance」テンプレートが自動選択される
- BALANCE と TOKEN_PLAN テストパスをリファクタリングし、`env.ANTHROPIC_*` を直接再読するのではなく、事前計算された `providerCredentials` を再利用するように変更。これにより非 Claude アプリでキーが設定されていても「empty key」エラーが出ていた問題を修正
### Codex `cache_control` 保持
- Codex フォーマット変換中に system prompt をマージする際の `cache_control` を保持 (#1946, 感謝 @yovinchen)
### Claude プロンプトキャッシュキーのリーク
- Claude chat 変換時にプロンプトキャッシュキーを送信しないように修正 (#2003, 感謝 @yovinchen)
### プロキシ Hop-by-Hop レスポンスヘッダーの削除
- RFC 7230 に従ってプロキシレスポンスの hop-by-hop ヘッダー(Connection、Keep-Alive、Transfer-Encoding など)を削除 (#2060, 感謝 @yovinchen)
### プロキシの寛容な CORS レイヤー削除
- プロキシの寛容な CORS レイヤーを削除 (#1915, 感謝 @zerone0x)
### プロキシトーストでのバックエンドエラー詳細表示
- プロキシ関連のトーストメッセージで、汎用的な失敗文字列ではなくバックエンドのエラーペイロードの詳細を表示
### Usage ログの重複排除
- プロキシとセッションログの用量レコードを重複排除し、同じリクエストが二重にカウントされないように修正
- リクエストログの時間範囲をダッシュボードの 1d / 7d / 30d セレクターと同期
### Common Config チェックボックスの永続化
- Claude / Codex / Gemini の common-config トグルのチェック状態が再オープンをまたいで正しく保持されるように修正 (#2191, 感謝 @zxZeng)
### Claude プラグイン `settings.json` 同期
- 現在のプロバイダーを編集すると、Claude プラグインパスの `settings.json` に同期されるように修正 (#1905, 感謝 @chengww5217)
### Google Official Gemini の env 保持
- Google Official Gemini プロバイダーを保存しても `env` ブロックが消えないように修正
### OpenCode の JSON5 による末尾カンマ解析
- OpenCode 設定読み取りが JSON5 パーサーにより末尾カンマを許容するように修正 (#2023, 感謝 @wwminger)
### プリセットの刷新
- DeepSeek と Claude 1M の古いコンテキストウィンドウを刷新
- 古いモデル ID を刷新。Hermes のモデルリストをバックフィル
- Nous エンドポイントを修正し、Hermes のプレースホルダーアイコンを Nous ブランドのアートワークに置き換え
- 未使用の公式 Hermes プリセットを整理
### 検索ヒット時の折り畳みメッセージの自動展開
- 隠されたコンテンツ内部で検索マッチが発生した場合、折り畳みメッセージを自動展開してマッチを示す
### 不明なサブスクリプション配額ティアの非表示
- プロバイダーカードは不明なサブスクリプション配額ティアを表示しないように変更
### weekly_limit ラベルの統一
- `weekly_limit` ティアラベルを公式の「7 日」命名にロケール間で揃えた
### ルートレベルの Skill リポジトリインストール
- リポジトリのルート自体が skill の場合のインストール失敗を修正
### Session ID 解析の clippy 警告
- session ID 解析内の冗長なクロージャを削除(clippy 警告)
### Stream Check デフォルトモデルの刷新
- Stream Check のデフォルト探索モデルを各ベンダーの現行ラインナップに合わせて更新
### Skills インポートの同期
- インポートされた Skills はデータベースに記録されるだけでなく、有効化されたアプリディレクトリにも即座に同期されるように変更 (#2101, 感謝 @yaoguohh)
- UI が「インストール済み」と表示しているのに対象アプリディレクトリに skill が存在しない状態を解消
### Ghostty セッション復元
- Ghostty セッション復元の起動を `--working-directory` 付きのシェル実行に変更 (#1976, 感謝 @Suda202)
- パスにスペースや特殊文字が含まれる場合の `cwd` エスケープ問題を回避
---
## ドキュメント
### README スポンサー更新
- SiliconFlow のサインアップボーナスを ¥16 に更新
- SSSAiCode のスポンサー文面を簡潔化
- パートナーロゴを更新
- 新しいスポンサーとして LemonData を追加
### グローバルプロキシヒントの明確化
- 三言語でグローバルプロキシと Local Routing の関係を明確化
### Takeover → Routing ドキュメントのリネーム
- テイクオーバー関連ドキュメントを三言語で routing にリネームし、アンカーを同期更新
### PIPELLM ウェブサイト URL
- PIPELLM スポンサーのウェブサイト URL を `code.pipellm.ai` に更新
---
## ⚠️ 重要な変更(Breaking
### Hermes は明示的な `api_mode` が必須
- `Auto` モードは廃止。インポートまたはディープリンクで取得したプロバイダーはデフォルトで `chat_completions`
- 既存の `Auto` 設定のユーザーはプロトコルを選択するよう促される
### Claude Quick-Set から `ANTHROPIC_REASONING_MODEL` を削除
- レガシーフィールドは公開されなくなった。既存の設定は自動的にクリーンアップされる
### プロバイダー単位のプロキシ設定を削除
- グローバル Local Routing 設定に移行
- 既存のプロバイダー単位のプロキシ値は無視される
### データベーススキーマ v9 → v10
- `mcp_servers``skills``enabled_hermes` カラムを追加
- `DEFAULT 0` で自動マイグレーション、データ損失なし
### Pricing テーブルの再シード(v8 → v9)
- 新しいモデルと修正済み価格を取り込むため、初回起動時に `model_pricing` テーブルがクリアされ再シードされる
### XCodeAPI プリセットの削除
- XCodeAPI プリセットを使用していたユーザーは別のプロバイダーに切り替える必要がある
---
## ⚠️ リスクに関する注意事項
本リリースは、リバースプロキシ型機能について 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#-リスクに関する注意事項) を参照してください。
これらの機能を有効にすることで、ユーザーは**すべての関連リスクを自己責任で受諾**したものとみなされます。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 |
### Windows
| ファイル | 説明 |
| ---------------------------------------- | ------------------------------------------- |
| `CC-Switch-v3.14.0-Windows.msi` | **推奨** - MSI インストーラー、自動更新対応 |
| `CC-Switch-v3.14.0-Windows-Portable.zip` | ポータブル版、解凍して実行、レジストリ不要 |
### macOS
| ファイル | 説明 |
| -------------------------------- | -------------------------------------------------------- |
| `CC-Switch-v3.14.0-macOS.dmg` | **推奨** - DMG インストーラー、Applications にドラッグ |
| `CC-Switch-v3.14.0-macOS.zip` | 解凍して Applications にドラッグ、Universal Binary |
| `CC-Switch-v3.14.0-macOS.tar.gz` | Homebrew インストールと自動更新用 |
> macOS 版は Apple のコード署名および公証済みで、直接インストールして使用できます。
### HomebrewmacOS
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
| ディストリビューション | 推奨形式 | インストール方法 |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| 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` |
+468
View File
@@ -0,0 +1,468 @@
# CC Switch v3.14.0
> Hermes Agent 成为第 6 个受管应用、Claude Opus 4.7 全面接入、Gemini Native API 代理、Local Routing 统一重命名、应用级窗口控件
**[English →](v3.14.0-en.md) | [日本語版 →](v3.14.0-ja.md)**
---
## 概览
CC Switch v3.14.0 是一次大版本更新,核心焦点是把 **Hermes Agent 作为第 6 个一等受管应用**接入 CC Switch,并把 **Claude Opus 4.7** 铺设到全部聚合器与 Bedrock 预设矩阵。Hermes 支持覆盖数据库 v9 → v10 迁移、完整的 Rust 命令面、基于 YAML 的 `~/.hermes/config.yaml` 读写(含原子备份)、MCP 同步、Skills 同步、SQLite + JSONL 会话管理,以及专属的前端面板和 Memory 编辑面板;与 Hermes Agent 0.10.0 schema 对齐的四种协议(`chat_completions``anthropic_messages``codex_responses``bedrock_converse`)全部可选。用户自行维护的 `providers:` dict 条目以只读卡片形式呈现,深度 YAML 配置则直接委托给 Hermes Web UI。
除了 Hermes,本次还新增了 **Gemini Native API 代理**`api_format = "gemini_native"`),让代理可以把请求直接转发到 Google 的 `generateContent` 端点,完整支持流式、schema 转换和 shadow 请求;把老的 "Local Proxy Takeover" 在三语 UI / README / 文档中统一重命名为 **Local Routing**;新增 **应用级窗口控件**,在 Linux Wayland 等合成器绘制按钮失灵的场景下可选让 CC Switch 自绘最小化 / 最大化 / 关闭按钮;并在本版本发布前额外合入了从工具栏直接启动 `hermes dashboard`、LemonData 全应用预设、DDSHub Codex 端点以及若干 Hermes 健康检查与 Usage 模态框的修复。
会话侧通过 `@tanstack/react-virtual` **虚拟化会话列表**,让上千条记录的长会话也能流畅滚动,长消息默认折叠;Usage 面板新增**日期范围选择器**(今日 / 1d / 7d / 14d / 30d + 自定义日期时间)和翻页输入;**Stream Check 错误分类**以彩色 toast 呈现,默认探测模型重新梳理,"模型不存在"响应被单独识别;并新增在 Local Routing 激活时**阻止切换到官方供应商**的保护,以免官方流量被引入本地代理造成账号风险。Pricing 数据库 v8 → v9 重新种入约 50 个新模型条目(包括 Claude 4.7、Opus 4.7 Adaptive Thinking、Grok 4、Qwen 3.5/3.6、MiniMax M2.5/M2.7、Doubao Seed 2.0 系列、GLM-5/5.1 等),并修正了多项陈旧价格。
**发布日期**2026-04-21
**更新规模**100 commits | 219 files changed | +20,548 / -3,569 lines
---
## 重点内容
- **Hermes Agent 支持(第 6 个受管应用)**:数据库 v9 → v10 迁移、完整 Rust 命令面、YAML 读写带原子备份、MCP 同步、Skills 同步、SQLite + JSONL 会话管理、专属前端面板、四种 API 协议(`chat_completions` / `anthropic_messages` / `codex_responses` / `bedrock_converse`
- **Claude Opus 4.7 全面接入**:自适应思维白名单、按百万 token 定价种子、Bedrock SKU`anthropic.claude-opus-4-7` / `global.anthropic.claude-opus-4-7`,丢弃老 `-v1` 后缀),全部聚合器 / Bedrock 预设升级为默认 Opus 模型
- **Claude `max` 推理力度**:推理下拉从 `high` 升级到 `max`
- **Gemini Native API 代理**:新增 `api_format = "gemini_native"`,代理可直达 Google `generateContent`,完整流式 / schema 转换 / shadow 请求
- **GitHub Copilot 企业版**:为 Copilot 型 Claude 供应商新增 GHES 认证与端点配置
- **Copilot 次数消耗深度优化**:转发前主动剥离 thinking 块、`tool_result` 消息归类修正、subagent 检测、`x-interaction-id` 合并计费、orphan `tool_result` 清理、默认启用 warmup 降级 —— 系统性降低 premium 交互消耗
- **会话列表虚拟化**:长会话流畅滚动,长消息默认折叠降低文字布局成本
- **Codex / OpenClaw 会话标题提取**:自动抽取有意义标题,两行显示,剥离 OpenClaw `message_id` 尾噪声
- **Usage 日期范围选择器**Today / 1d / 7d / 14d / 30d 预设 + 自定义日期时间日历;分页列表支持页码跳转输入
- **Stream Check 错误分类**:错误按类别分色 toast;默认探测模型刷新;单独识别 "model not found"
- **Local Routing 激活时阻止官方供应商切换**:官方流量走本地代理有账号暂停风险,强制拦截并 toast 警告
- **Pricing 数据库刷新(v8 → v9)**:新增 ~50 条模型条目并修正陈旧价格
- **应用级窗口控件**:可选让 CC Switch 自绘 min/max/close,显著改善 Linux Wayland 体验
- **Hermes 接入统一 Skills 管理**Skills 安装 / 启用 / 过滤现覆盖 Hermes
- **Hermes / OpenClaw 配置目录自定义**:在设置里指定 `~/.hermes/config.yaml``openclaw.json` 的自定义位置
- **从工具栏启动 Hermes Dashboard**Web UI 探测失败时,点击可在用户首选终端中启动 `hermes dashboard`
- **新合作伙伴预设**:LemonData 覆盖全部 6 个应用;DDSHub 新增 Codex 端点;StepFun Step Plan
---
## 新功能
### Hermes Agent 支持(第 6 个受管应用)
CC Switch 首次支持 Hermes Agent 作为一等受管应用,与 Claude / Codex / Gemini / OpenCode / OpenClaw 并列。
- **数据库迁移 v9 → v10**:为 `mcp_servers``skills` 表新增 `enabled_hermes` 列(`DEFAULT 0` 自动迁移,无数据丢失)
- **YAML 配置读写**`~/.hermes/config.yaml` 读写带原子备份;`tests/hermes_roundtrip.rs` 守护不损坏不相关键和 OAuth MCP `auth`
- **四种 API 协议**:与 Hermes Agent 0.10.0 对齐的 `chat_completions` / `anthropic_messages` / `codex_responses` / `bedrock_converse`;新 deeplink 默认为 `chat_completions`
- **用户 `providers:` dict 只读呈现**:用户在 YAML 里手写的 providers 条目在 CC Switch 中以只读卡片展示,深度配置跳转到 Hermes Web UI
- **累加式切换**:与 Claude / Codex 的"覆盖式"切换不同,Hermes 所有供应商共存于同一 YAML
### Hermes Memory 面板
- 新增 Memory 面板直接编辑 `MEMORY.md` / `USER.md`,带启用开关、字符数限制和保存流
- 替换 Hermes 的 Prompts 入口
### Hermes 供应商预设(约 50 个)
- 覆盖 Nous Research、胜算云、OpenRouter、DeepSeek、Together AI、StepFun、智谱 GLM、百炼、Kimi、MiniMax、豆包、百灵、魔搭、KAT-Coder、PackyCode、Cubence、AIGoCode、RightCode、AICodeMirror、AICoding、CrazyRouter、SSSAiCode、Micu、CTok.ai、DDSHub、E-FlowCode、LionCCAPI、PIPELLM、Compshare、SiliconFlow、AiHubMix、DMXAPI、TheRouter、Novita、Nvidia、小米 MiMo
### 从工具栏启动 Hermes Dashboard
- Hermes Web UI 探测失败时,工具栏按钮改为弹出确认框,提供在用户首选终端里运行 `hermes dashboard`
- 通过临时 bash / batch 脚本启动,`hermes dashboard` 就绪后自动打开浏览器,无需轮询
- Memory 面板和 Health banner 保留原有 toast 行为
- 顺便修正了离线 toast 里过时的 `hermes web` 提示(正确命令是 `hermes dashboard`
- Linux 终端探测改为先 `which` 后 stat,提升兼容性
### Claude Opus 4.7 支持
- 新增 Claude Opus 4.7 及其自适应思维白名单、按百万 token 定价种子、Bedrock SKU`anthropic.claude-opus-4-7` / `global.anthropic.claude-opus-4-7`,丢弃老 `-v1` 后缀)
- 全部聚合器 / Bedrock 预设升级为默认 Opus 模型
### Claude `max` 推理力度
- Claude 推理下拉从 `high` 升级到 `max`,解锁更强的思考容量
### Gemini Native API 代理
- 新增 `api_format = "gemini_native"`,代理可直接转发到 Google `generateContent` API (#1918, 感谢 @yovinchen)
- 完整支持流式、schema 转换、shadow 请求
- 在 proxy providers 模块下新增 `gemini_url.rs``gemini_schema.rs``gemini_shadow.rs``streaming_gemini.rs``transform_gemini.rs`
### GitHub Copilot 企业版(GHES
- 为 Copilot 型 Claude 供应商新增 GHES 认证与端点配置 (#2175, 感谢 @hotelbe)
### 会话列表虚拟化
- 通过 `@tanstack/react-virtual` 虚拟化会话列表,上千条记录流畅滚动
- 长会话消息默认折叠,减少文字布局开销
### Codex / OpenClaw 会话标题提取
- Codex 和 OpenClaw 会话自动抽取有意义的标题,两行显示
- 剥离 OpenClaw `message_id` 后缀噪声
### Usage 日期范围选择器
- Usage 面板新增日期范围选择器,预设 TabToday / 1d / 7d / 14d / 30d+ 自定义日期 + 时间日历 (#2002, 感谢 @yovinchen)
- 分页列表新增页码跳转输入
### 模型映射快速填入
- 供应商表单的模型映射字段旁新增快速填入按钮,加快编辑 (#2179, 感谢 @lispking)
### Stream Check 错误分类
- 按类别为 Stream Check 错误上色并以 toast 呈现
- 刷新所有厂商默认探测模型到当前主力机型
- 对 "model not found" 响应做单独识别
### Local Routing 激活时阻止官方供应商切换
- 在 Local Routing 激活状态下,切换到官方供应商会被强制拦截并弹出警告 toast
- 原因:官方 API 流量经由本地代理存在账号暂停风险
### Pricing 数据库刷新(v8 → v9
- 迁移时重新种入定价表
- 新增约 50 条模型条目,覆盖 Claude 4.7、Opus 4.7 Adaptive Thinking、Grok 4、Qwen 3.5/3.6、MiniMax M2.5/M2.7、Doubao Seed 2.0 系列、GLM-5/5.1
- 修正 DeepSeek、Kimi K2.5 等陈旧价格
### 应用级窗口控件
- 新增可选设置,让 CC Switch 自绘最小化 / 切换最大化 / 关闭按钮,代替系统装饰 (#1119, 感谢 @git1677967754)
- 在合成器按钮可能失灵的 Linux Wayland 上显著改善体验
### Hermes 接入统一 Skills 管理
- 统一的 Skills 界面新增 Hermes
- Skills 安装 / 启用 / 过滤现覆盖 Hermes,与 Claude / Codex / Gemini / OpenCode / OpenClaw 并列
### OpenClaw 配置目录自定义
- 新增设置项,允许把 CC Switch 指向自定义的 `openclaw.json` 位置 (#1518, 感谢 @mrFranklin)
### Hermes 配置目录自定义
- 新增设置项,允许把 CC Switch 指向自定义的 `~/.hermes/config.yaml` 位置,底层通过数据驱动 dispatch
### StepFun Step Plan 预设
- 新增 StepFun Step PlanEN / ZH)供应商预设 (#2155, 感谢 @hengm3467)
### New API 用量脚本模板
- 为 New API 用量脚本模板新增 User-Agent 头,提升上游兼容性
### LemonData 全应用预设
- LemonData 作为第三方合作伙伴预设覆盖 Claude / Codex / Gemini / OpenCode / OpenClaw / Hermes 全部 6 个应用
- 含图标资源和 zh / en / ja 三语合作伙伴推广文案
- Claude 预设使用 `ANTHROPIC_API_KEY` 认证,OpenAI 兼容应用目标为 `gpt-5.4`
### DDSHub Codex 预设
- 新增 DDSHub 的 Codex 兼容端点(与 Claude 服务同 host
- base URL 省略 `/v1` 后缀,由网关自动路由 OpenAI SDK 路径
---
## 变更
### "Local Proxy Takeover" → "Local Routing"
- 三语 UI 文案、README、文档中全部统一重命名
- 功能行为保持不变
### Hermes `Auto` api_mode 移除
- 用户必须显式选择协议;新 deeplink 默认为 `chat_completions`
- 消除了基于 URL 的启发式识别带来的意外
### Hermes 供应商表单
- 新增 API mode 下拉和按供应商的模型编辑器
- 切换激活供应商时,把按供应商的模型绑定到顶层 `model:`
### Hermes 深度配置委托
- 深度 YAML 配置不再在 CC Switch 表单里重复,直接通过"启动 Hermes Web UI"按钮交给 Web UI
### Hermes 工具栏布局
- Web UI 按钮图标从 `ExternalLink` 换成 `LayoutDashboard` —— 点击可能启动 `hermes dashboard` 而非仅仅打开 URL,面板式图标语义更准
- MCP 移到工具栏末尾,与 Claude / Codex / Gemini / OpenCode 的布局对齐
### Claude Quick-Set 移除 `ANTHROPIC_REASONING_MODEL`
- 把推理能力和模型选择解耦,quick-set 表单不再暴露该遗留字段
### 按供应商代理配置移除
- 统一到全局的 Local Routing
- 按供应商的代理开关和存储都已移除
### 统一工具栏图标按钮宽度
- 在 Claude / Codex / Gemini / OpenCode / OpenClaw / Hermes 面板之间规格化图标按钮宽度,表头视觉一致
### Rust Toolchain 锁定 1.95
- 全仓库采纳 clippy 1.95 建议并锁定 toolchain,防止 nightly 漂移
### 托盘菜单 ID 常量
- 托盘标识符从硬编码字符串 `"main"` 改为 `TRAY_ID` 常量(`"cc-switch"`),所有调用点同步 (#1978, 感谢 @lidaxian121)
### Copilot 次数消耗深度优化
一次系统性优化专门降低 Copilot 反向代理的 premium 交互消耗,涵盖以下多项改进:
- **转发前主动剥离 thinking 块**Anthropic 的 `thinking` / `redacted_thinking` 块会被 OpenAI 兼容端点拒绝,过去一次请求先失败消耗一次 premium 交互、再由 `thinking_rectifier` 触发重试。新增主动剥离步骤(Copilot 优化管线第 3.5 步,位于 `tool_result` 合并之后),直接省掉那一次无谓的 premium 消耗
- **请求分类修正**:含 `tool_result` 的消息归类为代理继续,而不是用户发起的新请求 —— 避免每次工具调用都被错误计入 premium 次数
- **subagent 检测**:通过 `__SUBAGENT_MARKER__``metadata._agent_` 回退识别 subagent,设置 `x-interaction-type=conversation-subagent`
- **确定性 `x-interaction-id` 合并计费**:从 session ID 推导 `x-interaction-id`,把同一会话内的多次请求合并为一次计费交互
- **Orphan `tool_result` 清理**:清理孤立的 `tool_result`,避免触发上游错误导致重试和重复计费
- **Warmup 降级默认开启**:使用 `gpt-5-mini` 作为默认降级模型
- **优化管线重排**classify → sanitize → merge → warmup,让分类看到原始 `tool_result` 语义
- 修复 `CopilotOptimizerConfig` 默认值不一致(统一到 `gpt-5-mini`
### 用量脚本内网支持
- 移除 usage script 的私网 IP / 可疑主机名屏蔽,解锁企业内网、Docker、自建 API 端点
- 内置模板仍强制 HTTPS(localhost 除外)和同源检查;自定义模板仍由用户控制,这类请求 URL 检查跳过
### Failover 队列备注
- 供应商备注现在在 failover 队列选择器和队列行中显示,方便在多供应商队列里识别 (#2138, 感谢 @Coconut-Fish)
---
## Bug 修复
### 工具栏最大化后持续折叠
- 窗口最大化 / 还原后,工具栏不再卡在折叠状态;折叠判定会随尺寸变化重新计算
### Hermes YAML 污染与 OAuth MCP `auth` 丢失
- 经 CC Switch 往返写入不再丢失 OAuth MCP `auth` 块、也不污染不相关的 YAML 键
- 新增 `tests/hermes_roundtrip.rs` 作为守护测试
### Hermes 激活供应商展示
- Hermes UI 现在正确展示激活供应商,并连通添加 / 启用 / 移除动作
### Hermes 供应商持久化
- 供应商持久化到 `custom_providers:` 下,`api_mode``model` 可跨重启 / 配置重载存活
### Hermes 健康检查错借 OpenClaw schema
- 以前 Hermes 供应商被路由到 `check_additive_app_stream`(OpenClaw 的调度器),后者读 camelCase 的 `baseUrl` / `apiKey` / `api`,导致即便 Hermes 字段全填还是报 "OpenClaw provider is missing baseUrl"
- 新增 `check_hermes_stream`,用 Hermes 专用提取器把 `api_mode``chat_completions` / `anthropic_messages` / `codex_responses`)映射到对应的 `check_claude_stream` `api_format``bedrock_converse` 明确标记为不支持
- 先解析 `api_mode` 再抽 URL / API key,让 `bedrock_converse` 用户看到真实原因,而不是误导性的 "missing base_url"
### Usage 查询模态框支持 Hermes / OpenClaw
- `getProviderCredentials` 新增对 Hermessnake_case `base_url` / `api_key`)和 OpenClawcamelCase `baseUrl` / `apiKey`)的扁平 `settingsConfig` 字段读取,让 SiliconFlow 等匹配供应商自动选中 "official balance" 模板
- 重构 BALANCE 和 TOKEN_PLAN 测试路径复用 `providerCredentials`,不再直接读 `env.ANTHROPIC_*`,修正了非 Claude 应用即使配置了 key 也报 "empty key" 的问题
### Codex `cache_control` 保留
- 在 Codex 格式转换合并 system prompt 时保留 `cache_control` (#1946, 感谢 @yovinchen)
### Claude prompt cache key 泄漏
- Claude chat 转换时不再发送 prompt cache key (#2003, 感谢 @yovinchen)
### 代理逐跳响应头剥离
- 按 RFC 7230 剥离代理响应的 hop-by-hop 头(Connection、Keep-Alive、Transfer-Encoding 等) (#2060, 感谢 @yovinchen)
### 代理 CORS 层移除
- 移除代理中过于宽松的 CORS 层 (#1915, 感谢 @zerone0x)
### 代理 toast 显示后端错误详情
- 代理相关 toast 现在展示后端错误 payload 的详情,而不是一句笼统的失败
### Usage 日志去重
- 代理和会话日志的用量记录去重,相同请求不再被重复计数
- 请求日志时间范围与面板的 1d / 7d / 30d 选择器同步
### Common Config 勾选持久化
- Claude / Codex / Gemini common-config 勾选状态重开后正确保留 (#2191, 感谢 @zxZeng)
### Claude 插件 `settings.json` 同步
- 编辑当前供应商时,会同步回 Claude 插件路径下的 `settings.json` (#1905, 感谢 @chengww5217)
### Google Official Gemini env 保留
- 保存 Google Official Gemini 供应商时不再清空 `env`
### OpenCode JSON5 尾逗号解析
- OpenCode 配置读取容忍尾逗号(JSON5) (#2023, 感谢 @wwminger)
### 预设刷新
- 刷新 DeepSeek 和 Claude 1M 的陈旧 context 窗口
- 刷新陈旧模型 ID,回填 Hermes 模型列表
- 修正 Nous 端点,Hermes 占位图替换为 Nous 品牌图
- 移除未使用的官方 Hermes 预设
### 搜索命中时折叠消息自动展开
- 搜索匹配落在折叠内容内部时,消息自动展开以定位匹配
### 未知订阅配额等级隐藏
- 供应商卡片不再渲染未知订阅配额等级
### weekly_limit 标签统一
- 跨语言把 `weekly_limit` 等级标签对齐到官方的"7 天"命名
### 根级 Skill 仓库安装
- 修复当仓库根本身就是一个 skill 时的安装失败
### Session ID 解析 clippy
- 移除 session ID 解析里的冗余闭包(clippy 警告)
### Stream Check 默认探测模型刷新
- 默认探测模型更新到每家厂商当前主力
### Skills 导入同步
- 导入的 Skills 即时同步到启用应用目录,不再仅记录在数据库里导致 UI 显示"已安装"但目标目录空缺 (#2101, 感谢 @yaoguohh)
### Ghostty 会话恢复
- 改为通过 shell 执行 + `--working-directory` 启动 Ghostty 会话恢复 (#1976, 感谢 @Suda202)
- 避免路径含空格 / 特殊字符时 `cwd` 转义问题
---
## 文档
### README 赞助商更新
- SiliconFlow 注册赠送更新为 ¥16
- 精简 SSSAiCode 赞助文案
- 更新合作伙伴 logo
- 新增 LemonData 赞助商
### 全局代理提示澄清
- 三语澄清全局代理与 Local Routing 的关系
### Takeover → Routing 文档重命名
- 接管相关文档在三语下重命名为 routing,同步更新锚点
### PIPELLM 网站 URL
- PIPELLM 赞助商网站 URL 更新为 `code.pipellm.ai`
---
## ⚠️ 重要变更(Breaking
### Hermes 必须显式 `api_mode`
- `Auto` 模式移除;导入或 deeplink 得到的供应商默认落到 `chat_completions`
- 既有 `Auto` 配置的用户会被提示选择协议
### Claude Quick-Set 移除 `ANTHROPIC_REASONING_MODEL`
- 该遗留字段不再暴露;既有设置自动清理
### 按供应商代理配置移除
- 迁移到全局 Local Routing 设置
- 既有按供应商代理值被忽略
### 数据库 schema v9 → v10
-`mcp_servers``skills` 表新增 `enabled_hermes`
- 自动迁移,`DEFAULT 0`,无数据丢失
### Pricing 表 v8 → v9 重置
- 首次启动时 `model_pricing` 表被清空并重新种入,以应用新模型和修正后的价格
### XCodeAPI 预设移除
- 使用 XCodeAPI 预设的用户请迁移到其它供应商
---
## ⚠️ 风险提示
本版本在涉及反向代理类功能上沿用 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#-风险提示)。
用户启用上述功能即表示**自行承担所有风险**。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 |
### Windows
| 文件 | 说明 |
| ---------------------------------------- | ----------------------------------- |
| `CC-Switch-v3.14.0-Windows.msi` | **推荐** - MSI 安装包,支持自动更新 |
| `CC-Switch-v3.14.0-Windows-Portable.zip` | 便携版,解压即用,不写入注册表 |
### macOS
| 文件 | 说明 |
| -------------------------------- | --------------------------------------------- |
| `CC-Switch-v3.14.0-macOS.dmg` | **推荐** - DMG 安装包,拖入 Applications 即可 |
| `CC-Switch-v3.14.0-macOS.zip` | 解压后拖入 ApplicationsUniversal Binary |
| `CC-Switch-v3.14.0-macOS.tar.gz` | 用于 Homebrew 安装和自动更新 |
> macOS 版本已通过 Apple 代码签名和公证,可直接安装使用。
### HomebrewmacOS
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
| 发行版 | 推荐格式 | 安装方式 |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| 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` |
+185
View File
@@ -0,0 +1,185 @@
# CC Switch v3.14.1
> Tray usage visibility, Codex OAuth stability fixes, Skills import/install reliability, and removal of the Hermes config health scanner
**[中文版 →](v3.14.1-zh.md) | [日本語版 →](v3.14.1-ja.md)**
---
## Overview
CC Switch v3.14.1 is a patch release following v3.14.0, focused on **Codex OAuth reverse-proxy stability**, **tray usage visibility**, **Skills import / install reliability**, **Gemini session restore paths**, and **simplifying Hermes configuration health handling**.
For the first time, the system tray surfaces **cached usage** for the current Claude / Codex / Gemini provider directly in its submenus — including subscription summaries and usage-script summaries with color-coded utilization markers. For Chinese coding-plan providers like Kimi / Zhipu / MiniMax, the tray additionally renders a **5-hour + weekly window** layout in the `🟢 h12% w80%` style (worst utilization drives the emoji), semantically identical to the official subscription badges. Creating a Claude provider whose `ANTHROPIC_BASE_URL` matches a known coding-plan host now auto-injects `meta.usage_script` so the tray lights up without opening the Usage Script modal.
Several Codex OAuth reverse-proxy stability issues are addressed this release: client-provided session IDs are now used as both `prompt_cache_key` and the Codex session header to avoid UUID-driven cache churn; non-streaming Anthropic clients receive proper JSON responses even when the ChatGPT Codex upstream forces OpenAI Responses SSE; and Stream Check now builds probes with the same `store: false`, encrypted reasoning include, and provider FAST mode setting as production requests, eliminating the "check fails but it actually works" mismatch. Paired with a new explicit **FAST mode toggle**, users can now opt into `service_tier="priority"` on Codex OAuth-backed Claude providers, trading latency against ChatGPT quota consumption on their own terms.
Additionally, the in-app **Hermes config health scanner** and its warning banner are removed (along with the `scan_hermes_config_health` command, `HermesHealthWarning` type, and `HermesWriteOutcome.warnings` payload), refocusing the Hermes surface on active provider display, switching defaults, memory editing, and launching the Hermes Web UI — deep configuration health is now Hermes's own responsibility.
**Release Date**: 2026-04-23
**Update Scale**: 13 commits | 48 files changed | +1,883 / -808 lines
---
## Highlights
- **Tray Usage Visibility**: Claude / Codex / Gemini tray submenus show cached usage for the current provider, including subscription and script-based summaries with color markers; refreshes are throttled, limited to visible apps, and synchronized back into React Query (#2184, thanks @TuYv)
- **Tray Coding-Plan Usage (Kimi / Zhipu / MiniMax)**: The tray renders 5-hour + weekly window usage using the `🟢 h12% w80%` layout; Claude providers whose base URL matches a known host auto-inject `meta.usage_script`
- **Codex OAuth FAST Mode**: New explicit FAST mode toggle for Codex OAuth-backed Claude providers; when enabled, converted Responses requests send `service_tier="priority"`. Off by default (#2210, thanks @JesusDR01)
- **Codex OAuth Stability**: Fixed reverse-proxy cache routing (#2218, thanks @majiayu000), Responses SSE aggregation (#2235, thanks @xpfo-go), and Stream Check parity with production (#2210, thanks @JesusDR01)
- **Hermes Config Health Scanner Removed**: Refocuses the Hermes surface on provider management, memory editing, and launching the Web UI — no longer duplicates deep configuration health judgments
- **Skills Import / Install Reliability**: Import dialog disables actions while pending and deduplicates results by ID (#2211, thanks @TuYv); model quick-set / one-click config applies against the latest form state (#2249, thanks @Coconut-Fish); root-level `SKILL.md` repo installs are stable (#2231, thanks @santugege)
- **Gemini Session Restore Paths**: Session scanning reads `.project_root` metadata and passes the original project directory back into restore flows (#2240, thanks @tisonkun)
- **Session / Settings Layout Polish**: Hardened the scroll-area viewport with width containment to fix horizontal overflow; tightened app bottom and settings footer spacing (#2201, thanks @Coconut-Fish)
---
## Added
### Tray Usage Visibility
- System tray submenus now show **cached usage** for the current Claude / Codex / Gemini provider (#2184, thanks @TuYv)
- Includes subscription quota summaries and usage-script summaries with color-coded utilization markers
- Tray-triggered refreshes are **throttled**, **limited to visible apps**, and synchronized back into React Query so the main window and tray share the same usage data
### Tray Coding-Plan Usage (Kimi / Zhipu / MiniMax)
- The tray renders **5-hour + weekly window** usage for Chinese coding-plan providers
- Uses the same `🟢 h12% w80%` two-window layout as official subscription badges (worst utilization drives the emoji color)
- Creating a Claude provider whose `ANTHROPIC_BASE_URL` matches a known coding-plan host **auto-injects** `meta.usage_script`, so the tray lights up without opening the Usage Script modal
- Existing `usage_script` values are **preserved on update**, never clobbering user customizations
### Codex OAuth FAST Mode
- New explicit FAST mode toggle for Codex OAuth-backed Claude providers (#2210, thanks @JesusDR01)
- When enabled, converted Responses requests send `service_tier="priority"` for lower latency
- Off by default to avoid unexpectedly increasing ChatGPT quota consumption
---
## Changed
### Session and Settings Layout Polish
- Hardened the scroll-area viewport with width containment to fix horizontal overflow (#2201, thanks @Coconut-Fish)
- Tightened app bottom and settings footer spacing so long session / settings views fit more cleanly
---
## Removed
### Hermes Config Health Scanner
- Removed the in-app Hermes config health scanner and its warning banner
- Removed the `scan_hermes_config_health` command, `HermesHealthWarning` type, and `HermesWriteOutcome.warnings` payload
- The CC Switch Hermes surface now focuses on its core job: active provider display, default provider switching, memory editing, and launching the Hermes Web UI for deep configuration
---
## Fixed
### Codex OAuth Cache Routing
- Use the client-provided session ID as both `prompt_cache_key` and the Codex session header, preserving explicit cache keys (#2218, thanks @majiayu000)
- Stop generating UUIDs that caused cache-identity churn, stabilizing the ChatGPT Codex reverse-proxy cache identity
### Codex OAuth Responses SSE Aggregation
- Non-streaming Anthropic clients now receive proper JSON even when the ChatGPT Codex upstream forces OpenAI Responses SSE (#2235, thanks @xpfo-go)
- CC Switch aggregates the upstream SSE events before running the non-streaming transform
### Codex OAuth Stream Check Parity
- Stream Check now builds Codex OAuth probe requests with the same `store: false`, encrypted reasoning include, and provider FAST mode setting as production proxy traffic (#2210, thanks @JesusDR01)
- Eliminates the "check fails but it actually works" mismatch
### Codex Model Extraction
- Reading the `model` field from Codex config now uses TOML parsing instead of first-line regex matching (#2227, thanks @nmsn)
- Multiline TOML is handled correctly
### Model Quick-Set / One-Click Config
- Model quick-set now applies against the **latest** provider form config (#2249, thanks @Coconut-Fish)
- Fixes stale form state preventing one-click configuration from succeeding
### Skills Import Duplicates
- The Skills import dialog disables actions while import is pending (#2211, thanks @TuYv)
- The installed-skills cache deduplicates imported results by ID, preventing double-clicks from adding duplicate installed entries (#2139)
### Root-Level Skill Repos
- Skill install and update flows now consistently resolve three source patterns: direct nested paths, install-name recursive search, and repository-root `SKILL.md` sources (#2231, thanks @santugege)
### Gemini Session Restore Paths
- Gemini session scanning now reads `.project_root` metadata (#2240, thanks @tisonkun)
- Restore flows can pass the original project directory when available
### Provider Hover Names
- Provider icons now expose the provider name on hover for inline SVG, image URL, and fallback initials render paths (#2237, thanks @tisonkun)
---
## Notes & Caveats
- **Hermes Health Scanner Removed**: If you were relying on CC Switch to surface deep Hermes YAML configuration issues, switch to the "Launch Hermes Web UI" toolbar button and inspect them in Hermes's own panel. Day-to-day provider management, switching, memory editing, and MCP / Skills sync continue to be handled by CC Switch.
- **Codex OAuth FAST Mode Off by Default**: Only turn it on if you accept potentially increased ChatGPT quota consumption in exchange for lower latency.
- **Tray Cached Usage**: Refreshes are throttled and limited to the currently visible app to avoid unnecessary upstream API calls; values are synchronized into React Query so the main window and tray stay in sync.
---
## 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 |
### Windows
| File | Description |
| ---------------------------------------- | ----------------------------------------------------- |
| `CC-Switch-v3.14.1-Windows.msi` | **Recommended** - MSI installer, supports auto-update |
| `CC-Switch-v3.14.1-Windows-Portable.zip` | Portable, extract and run, no registry writes |
### macOS
| File | Description |
| -------------------------------- | ------------------------------------------------------- |
| `CC-Switch-v3.14.1-macOS.dmg` | **Recommended** - DMG installer, drag into Applications |
| `CC-Switch-v3.14.1-macOS.zip` | Extract and drag into Applications, Universal Binary |
| `CC-Switch-v3.14.1-macOS.tar.gz` | For Homebrew installation and auto-update |
> macOS builds are Apple code-signed and notarized — install directly.
### Homebrew (macOS)
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
Update:
```bash
brew upgrade --cask cc-switch
```
### Linux
| 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` |
+185
View File
@@ -0,0 +1,185 @@
# CC Switch v3.14.1
> トレイでの用量可視化、Codex OAuth の複数の安定性修正、Skills インポート/インストールの信頼性向上、Hermes 設定ヘルススキャナーの削除
**[中文版 →](v3.14.1-zh.md) | [English →](v3.14.1-en.md)**
---
## 概要
CC Switch v3.14.1 は v3.14.0 に続くパッチリリースで、**Codex OAuth リバースプロキシの安定性**、**トレイでの用量可視化**、**Skills インポート / インストールの信頼性**、**Gemini セッション復元パス**、および **Hermes 設定ヘルス処理の簡素化**を中心に据えています。
システムトレイは初めて、現在の Claude / Codex / Gemini プロバイダーの**キャッシュ済み用量**をサブメニューに直接表示するようになりました — サブスクリプション要約と用量スクリプト要約を、使用率に応じた色分けマーカーとともに表示します。Kimi / Zhipu / MiniMax のような中国系コーディングプランプロバイダーには、公式サブスクリプションバッジと同じ `🟢 h12% w80%` スタイルで **5 時間 + 週次ウィンドウ**の 2 ウィンドウレイアウトを追加描画します(より厳しい方の使用率が絵文字色を決定)。`ANTHROPIC_BASE_URL` が既知のコーディングプランホストに一致する Claude プロバイダーを作成すると、`meta.usage_script` が自動注入されるため、Usage Script モーダルを開かなくてもトレイが点灯します。
Codex OAuth 側では、複数のリバースプロキシ安定性の問題を修正しました: クライアント提供の session ID を `prompt_cache_key` と Codex session ヘッダーの両方に使用し、UUID 生成によるキャッシュ揺らぎを回避。ChatGPT Codex 上流が OpenAI Responses SSE を強制する場合でも、非ストリーミングの Anthropic クライアントが適切な JSON レスポンスを受け取れるようになりました。Stream Check は、本番環境と同じ `store: false`、暗号化 reasoning include、およびプロバイダーの FAST モード設定でプローブを構築するようになり、「検出は失敗するのに実際は動く」というズレが解消されました。新しい明示的な **FAST モードトグル**と組み合わせることで、ユーザーは Codex OAuth バックの Claude プロバイダーで `service_tier="priority"` を選択的に送信でき、レイテンシと ChatGPT 配額消費の間で自分で選べるようになりました。
さらに、CC Switch 内蔵の **Hermes 設定ヘルススキャナー**と警告バナー(および対応する `scan_hermes_config_health` コマンド、`HermesHealthWarning` 型、`HermesWriteOutcome.warnings` ペイロード)を削除し、Hermes サーフェスをアクティブプロバイダー表示、デフォルト切り替え、Memory 編集、および Hermes Web UI の起動に再フォーカスしました — 深い設定ヘルスは Hermes 自身の責任になります。
**リリース日**: 2026-04-23
**更新規模**: 13 commits | 48 files changed | +1,883 / -808 lines
---
## ハイライト
- **トレイでの用量可視化**: Claude / Codex / Gemini のトレイサブメニューに、現在のプロバイダーのキャッシュ済み用量(サブスクリプション要約とスクリプト要約、色分けマーカー付き)を表示。リフレッシュはスロットル、可視アプリに限定、React Query に同期 (#2184, 感謝 @TuYv)
- **トレイのコーディングプラン用量(Kimi / Zhipu / MiniMax**: トレイが 5 時間 + 週次ウィンドウの用量を `🟢 h12% w80%` レイアウトで描画。既知のホストにマッチする Claude プロバイダーは `meta.usage_script` を自動注入
- **Codex OAuth FAST モード**: Codex OAuth バックの Claude プロバイダーに明示的な FAST モードトグルを追加。有効時は変換された Responses リクエストに `service_tier="priority"` を送信、デフォルトは OFF (#2210, 感謝 @JesusDR01)
- **Codex OAuth 安定性**: リバースプロキシのキャッシュルーティング (#2218, 感謝 @majiayu000)、Responses SSE 集約 (#2235, 感謝 @xpfo-go)、Stream Check と本番の一致性 (#2210, 感謝 @JesusDR01) を修正
- **Hermes 設定ヘルススキャナー削除**: Hermes サーフェスをプロバイダー管理、Memory 編集、Web UI 起動に再フォーカス。深い設定ヘルス判定を重複して担わなくなる
- **Skills インポート / インストールの信頼性**: インポート中はダイアログのアクションを無効化し、結果を ID で重複排除 (#2211, 感謝 @TuYv); ワンクリック設定は最新のフォーム状態に基づいて適用 (#2249, 感謝 @Coconut-Fish); ルートレベルの `SKILL.md` リポジトリインストールが安定 (#2231, 感謝 @santugege)
- **Gemini セッション復元パス**: セッションスキャン時に `.project_root` メタデータを読み、元のプロジェクトディレクトリを復元フローに渡す (#2240, 感謝 @tisonkun)
- **セッション / 設定レイアウトの磨き込み**: スクロールエリアビューポートに幅制約を追加して横方向のはみ出しを修正。アプリ下部と設定フッター間隔をよりタイトに (#2201, 感謝 @Coconut-Fish)
---
## 新機能
### トレイでの用量可視化
- システムトレイサブメニューに、現在の Claude / Codex / Gemini プロバイダーの**キャッシュ済み用量**を表示 (#2184, 感謝 @TuYv)
- サブスクリプション配額要約と用量スクリプト要約を含み、使用率に応じた色分けマーカー付き
- トレイ起因のリフレッシュは**スロットル**、**可視アプリに限定**、React Query に同期されるため、メインウィンドウとトレイが同じ用量データを共有
### トレイのコーディングプラン用量(Kimi / Zhipu / MiniMax
- 中国系コーディングプランプロバイダー向けに、トレイが **5 時間 + 週次ウィンドウ**の用量を描画
- 公式サブスクリプションバッジと同じ `🟢 h12% w80%` の 2 ウィンドウレイアウトを使用(より厳しい使用率が絵文字色を決定)
- `ANTHROPIC_BASE_URL` が既知のコーディングプランホストにマッチする Claude プロバイダーを作成すると、`meta.usage_script` が**自動注入**され、Usage Script モーダルを開かなくてもトレイが点灯
- 更新時は既存の `usage_script` 値を**保持**し、ユーザーカスタマイズを上書きしない
### Codex OAuth FAST モード
- Codex OAuth バックの Claude プロバイダーに明示的な FAST モードトグルを追加 (#2210, 感謝 @JesusDR01)
- 有効時は変換された Responses リクエストに `service_tier="priority"` を送信してレイテンシを低減
- 予期せぬ ChatGPT 配額消費の増加を避けるため、デフォルトは OFF
---
## 変更
### セッション・設定レイアウトの磨き込み
- スクロールエリアビューポートに幅制約を追加して横方向のはみ出しを修正 (#2201, 感謝 @Coconut-Fish)
- アプリ下部と設定フッター間隔をよりタイトにし、長いセッション / 設定ビューをすっきり表示
---
## 削除
### Hermes 設定ヘルススキャナー
- アプリ内の Hermes 設定ヘルススキャナーと警告バナーを削除
- `scan_hermes_config_health` コマンド、`HermesHealthWarning` 型、`HermesWriteOutcome.warnings` ペイロードを削除
- CC Switch の Hermes サーフェスは本来の役割に回帰: アクティブプロバイダー表示、デフォルトプロバイダー切り替え、Memory 編集、および深い設定用の Hermes Web UI 起動
---
## バグ修正
### Codex OAuth キャッシュルーティング
- クライアント提供の session ID を `prompt_cache_key` と Codex session ヘッダーの両方に使用し、明示的なキャッシュキーを保持 (#2218, 感謝 @majiayu000)
- キャッシュアイデンティティの揺らぎを引き起こしていた UUID 生成を停止し、ChatGPT Codex リバースプロキシのキャッシュアイデンティティを安定化
### Codex OAuth Responses SSE 集約
- ChatGPT Codex 上流が OpenAI Responses SSE を強制する場合でも、非ストリーミングの Anthropic クライアントが適切な JSON を受け取れるように修正 (#2235, 感謝 @xpfo-go)
- CC Switch が非ストリーミング変換を実行する前に上流 SSE イベントを集約
### Codex OAuth Stream Check の一致性
- Stream Check が構築する Codex OAuth プローブリクエストは、本番プロキシと同じ `store: false`、暗号化 reasoning include、プロバイダー FAST モード設定を使用するように修正 (#2210, 感謝 @JesusDR01)
- 「検出は失敗するのに実際は動く」ズレを解消
### Codex モデル抽出
- Codex 設定の `model` フィールドを読む際、先頭行の正規表現マッチではなく TOML パーサーを使用するように変更 (#2227, 感謝 @nmsn)
- 複数行 TOML も正しく処理
### モデルのクイック入力 / ワンクリック設定
- モデルクイック入力は**最新の**プロバイダーフォーム設定に対して適用されるように修正 (#2249, 感謝 @Coconut-Fish)
- 古いフォーム状態によってワンクリック設定が失敗する問題を修正
### Skills インポートの重複排除
- Skills インポートダイアログは、インポート中にすべてのアクションボタンを無効化 (#2211, 感謝 @TuYv)
- インストール済み Skills のキャッシュを ID で重複排除し、ダブルクリックによる重複したインストール済みエントリを防止 (#2139)
### ルートレベルの Skill リポジトリ
- Skill のインストールと更新フローが 3 つのソースパターンを一貫して解決: 直接ネストパス、install-name の再帰検索、およびリポジトリルートの `SKILL.md` ソース (#2231, 感謝 @santugege)
### Gemini セッション復元パス
- Gemini セッションスキャンが `.project_root` メタデータを読み取るように修正 (#2240, 感謝 @tisonkun)
- 復元フローは利用可能な場合に元のプロジェクトディレクトリを渡せる
### プロバイダー名のホバー表示
- プロバイダーアイコンは、inline SVG、画像 URL、およびフォールバックの頭文字レンダリングパスで、ホバー時にプロバイダー名を表示 (#2237, 感謝 @tisonkun)
---
## 備考・注意事項
- **Hermes ヘルススキャナー削除済み**: Hermes YAML の深い設定の問題提示を CC Switch に頼っていた場合は、ツールバーの「Hermes Web UI を起動」ボタンから Hermes 自身のパネルで確認してください。日常のプロバイダー管理、切り替え、Memory 編集、MCP / Skills 同期は引き続き CC Switch が担います。
- **Codex OAuth FAST モードはデフォルト OFF**: レイテンシ低減と引き換えに ChatGPT 配額消費が増える可能性を許容する場合にのみ有効化してください。
- **トレイのキャッシュ用量**: リフレッシュはスロットル済み、かつ現在可視のアプリに限定されており、不要な上流 API 呼び出しを回避します。値は React Query に同期されるため、メインウィンドウとトレイで同じ値が見えます。
---
## ダウンロード・インストール
[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 |
### Windows
| ファイル | 説明 |
| ---------------------------------------- | ------------------------------------------- |
| `CC-Switch-v3.14.1-Windows.msi` | **推奨** - MSI インストーラー、自動更新対応 |
| `CC-Switch-v3.14.1-Windows-Portable.zip` | ポータブル版、解凍して実行、レジストリ不要 |
### macOS
| ファイル | 説明 |
| -------------------------------- | ------------------------------------------------------ |
| `CC-Switch-v3.14.1-macOS.dmg` | **推奨** - DMG インストーラー、Applications にドラッグ |
| `CC-Switch-v3.14.1-macOS.zip` | 解凍して Applications にドラッグ、Universal Binary |
| `CC-Switch-v3.14.1-macOS.tar.gz` | Homebrew インストールと自動更新用 |
> macOS 版は Apple のコード署名および公証済みで、直接インストールして使用できます。
### HomebrewmacOS
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
| ディストリビューション | 推奨形式 | インストール方法 |
| --------------------------------------- | ----------- | -------------------------------------------------------------------------- |
| 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` |
+185
View File
@@ -0,0 +1,185 @@
# CC Switch v3.14.1
> 托盘用量可见化、Codex OAuth 多项稳定性修复、Skills 导入/安装可靠性提升、Hermes 配置健康扫描器移除
**[English →](v3.14.1-en.md) | [日本語版 →](v3.14.1-ja.md)**
---
## 概览
CC Switch v3.14.1 是 v3.14.0 之后的一次补丁版本,围绕 **Codex OAuth 反代稳定性**、**托盘用量可见化**、**Skills 导入 / 安装可靠性**、**Gemini 会话恢复路径**,以及**简化 Hermes 配置健康处理**展开。
系统托盘第一次把当前 Claude / Codex / Gemini 供应商的**缓存用量**直接呈现在子菜单里——包含订阅额度摘要和用量脚本摘要,并用颜色标记利用率;针对 Kimi / 智谱 / MiniMax 这类中国编码套餐供应商,托盘还会额外渲染 `🟢 h12% w80%` 风格的 **5 小时 + 周窗口**双窗口排版,语义与官方订阅徽章完全一致(取更紧的那个驱动 emoji)。创建 Claude 供应商时,如果 `ANTHROPIC_BASE_URL` 命中已知的编码套餐 host,会自动注入 `meta.usage_script`,托盘可以不打开 Usage Script 模态框就直接点亮。
Codex OAuth 侧修复了多项反代稳定性问题:使用客户端自带的 session ID 作为 `prompt_cache_key` 和 Codex session 头,避免生成 UUID 造成缓存抖动,显著提高缓存命中率;非流式 Anthropic 客户端在 ChatGPT Codex 上游强制 OpenAI Responses SSE 时也能正确拿到 JSON 响应;Stream Check 现在会以和生产一致的 `store: false`、encrypted reasoning include 以及供应商 FAST 模式构造探测请求,避免出现"检测失败但实际能用"的错位。配合新增的 **FAST 模式显式开关**,让用户可以在 Codex OAuth 型 Claude 供应商上按需发 `service_tier="priority"`,在延迟和 ChatGPT 配额消耗之间自己选。
另外,移除了 CC Switch 内置的 **Hermes 配置健康扫描器**及其警告横幅(以及对应的 `scan_hermes_config_health` 命令、`HermesHealthWarning` 类型和 `HermesWriteOutcome.warnings` 载荷),把 Hermes 面板聚焦回当前供应商展示、默认切换、Memory 编辑和启动 Hermes Web UI,深度配置健康度由 Hermes 自己负责。
**发布日期**2026-04-23
**更新规模**13 commits | 48 files changed | +1,883 / -808 lines
---
## 重点内容
- **托盘用量可见化**Claude / Codex / Gemini 托盘子菜单展示当前供应商缓存用量,含订阅与脚本摘要及颜色标记;刷新带节流、仅针对可见应用、并回写到 React Query (#2184, 感谢 @TuYv)
- **托盘编码套餐用量(Kimi / 智谱 / MiniMax**:托盘渲染 5 小时 + 周窗口双窗口用量,沿用 `🟢 h12% w80%` 排版;命中已知 host 的 Claude 供应商自动注入 `meta.usage_script`
- **Codex OAuth FAST 模式**:为 Codex OAuth 型 Claude 供应商新增显式 FAST 开关,开启后转换后的 Responses 请求发 `service_tier="priority"`,默认关闭 (#2210, 感谢 @JesusDR01)
- **Codex OAuth 稳定性**:修复反代缓存路由 (#2218, 感谢 @majiayu000)、Responses SSE 聚合 (#2235, 感谢 @xpfo-go)、Stream Check 与生产一致性 (#2210, 感谢 @JesusDR01)
- **Hermes 配置健康扫描器移除**:把 Hermes 面板聚焦回供应商管理、Memory 编辑和 Web UI 启动,不再重复承担深度配置健康判断
- **Skills 导入 / 安装可靠性**:导入过程中禁用操作按钮、结果按 ID 去重 (#2211, 感谢 @TuYv);一键配置基于最新表单状态 (#2249, 感谢 @Coconut-Fish);根级 `SKILL.md` 仓库安装稳定 (#2231, 感谢 @santugege)
- **Gemini 会话恢复路径**:扫描会话时读取 `.project_root` 元数据,把原始项目目录带回恢复流程 (#2240, 感谢 @tisonkun)
- **Session / 设置布局打磨**:滚动区域视口加宽度约束修复横向溢出,应用底部和设置页底部间距更紧凑 (#2201, 感谢 @Coconut-Fish)
---
## 新功能
### 托盘用量可见化
- 系统托盘子菜单新增当前 Claude / Codex / Gemini 供应商的**缓存用量**展示 (#2184, 感谢 @TuYv)
- 包含订阅额度摘要和用量脚本摘要,并用颜色标记利用率
- 托盘触发的刷新**带节流**、**只覆盖可见应用**,并同步回 React Query,主窗口和托盘共享同一份用量数据
### 托盘编码套餐用量(Kimi / 智谱 / MiniMax
- 托盘为中国编码套餐供应商渲染 **5 小时 + 周窗口**双窗口用量
- 使用与官方订阅徽章一致的 `🟢 h12% w80%` 两窗口排版,取更紧的那个利用率驱动 emoji 颜色
- 创建 Claude 供应商时,如果 `ANTHROPIC_BASE_URL` 匹配已知编码套餐 host,会**自动注入** `meta.usage_script`,托盘不打开 Usage Script 模态框也能直接点亮
- 更新时会**保留已有** `usage_script` 值,不覆盖用户自定义
### Codex OAuth FAST 模式
- 为 Codex OAuth 型 Claude 供应商新增显式 FAST 模式开关 (#2210, 感谢 @JesusDR01)
- 开启时,转换后的 Responses 请求会发 `service_tier="priority"` 以降低延迟
- 默认关闭,避免意外增加 ChatGPT 配额消耗
---
## 变更
### Session 与设置布局打磨
- 滚动区域视口加上宽度约束,修复横向溢出 (#2201, 感谢 @Coconut-Fish)
- 应用底部和设置页底部间距更紧凑,让长 Session / 设置视图看起来更干净
---
## 移除
### Hermes 配置健康扫描器
- 移除应用内的 Hermes 配置健康扫描器和警告横幅
- 移除 `scan_hermes_config_health` 命令、`HermesHealthWarning` 类型以及 `HermesWriteOutcome.warnings` 载荷
- CC Switch 的 Hermes 面板回归核心职责:当前供应商展示、切换默认供应商、Memory 编辑、以及启动 Hermes Web UI 处理深度配置
---
## 修复
### Codex OAuth 缓存路由
- 使用客户端自带的 session ID 作为 `prompt_cache_key` 和 Codex session 头,保留显式缓存 key (#2218, 感谢 @majiayu000)
- 停止生成 UUID 导致的缓存抖动,让 ChatGPT Codex 反代的缓存身份更稳定
### Codex OAuth Responses SSE 聚合
- ChatGPT Codex 上游强制 OpenAI Responses SSE 时,非流式 Anthropic 客户端也能正确拿到 JSON (#2235, 感谢 @xpfo-go)
- CC Switch 会在非流式转换之前先聚合上游 SSE 事件
### Codex OAuth Stream Check 对齐
- Stream Check 构造的 Codex OAuth 测试请求现在与生产代理一致,使用相同的 `store: false`、加密 reasoning include 和供应商 FAST 模式设置 (#2210, 感谢 @JesusDR01)
- 避免"检测失败但实际能用"的错位
### Codex 模型提取
- 读取 Codex 配置的 `model` 字段时,改用 TOML 解析替代首行正则匹配 (#2227, 感谢 @nmsn)
- 多行 TOML 也能正确处理
### 模型快速填入 / 一键配置
- 模型快速填入现在基于**最新的**供应商表单配置应用 (#2249, 感谢 @Coconut-Fish)
- 修复陈旧表单状态导致一键配置失败的问题
### Skills 导入去重
- Skills 导入对话框在导入进行时禁用所有操作按钮 (#2211, 感谢 @TuYv)
- 已安装 Skills 的缓存按 ID 去重,避免双击造成重复的已安装条目 (#2139)
### 根级 Skill 仓库
- Skill 的安装与更新流程现在能一致地识别三种源路径:直接嵌套路径、按 install-name 递归搜索、以及仓库根的 `SKILL.md` 源 (#2231, 感谢 @santugege)
### Gemini 会话恢复路径
- Gemini 会话扫描时读取 `.project_root` 元数据 (#2240, 感谢 @tisonkun)
- 恢复流程可以在可用时把原始项目目录传回
### 供应商名悬浮提示
- 供应商图标在 inline SVG、图像 URL、以及首字母回退渲染路径下都会在 hover 时展示供应商名称 (#2237, 感谢 @tisonkun)
---
## 说明与注意事项
- **Hermes 健康扫描器已移除**:如果你依赖 CC Switch 提示 Hermes YAML 的深度配置问题,请改为通过工具栏的"启动 Hermes Web UI"按钮在 Hermes 原生面板里查看。日常供应商管理、切换、Memory 编辑、MCP 与 Skills 同步仍然由 CC Switch 负责。
- **Codex OAuth FAST 模式默认关闭**:只有在你接受可能增加 ChatGPT 配额消耗换取更低延迟时,才需要打开。
- **托盘缓存用量**:刷新带节流,只覆盖当前显示的应用,避免无必要的上游 API 调用;数据会回写到 React Query,因此主窗口和托盘看到的值一致。
---
## 下载与安装
访问 [Releases](https://github.com/farion1231/cc-switch/releases/latest) 下载对应版本。
### 系统要求
| 系统 | 最低版本 | 架构 |
| ------- | -------------------------- | ----------------------------------- |
| Windows | Windows 10 及以上 | x64 |
| macOS | macOS 12 (Monterey) 及以上 | Intel (x64) / Apple Silicon (arm64) |
| Linux | 见下表 | x64 |
### Windows
| 文件 | 说明 |
| ---------------------------------------- | ----------------------------------- |
| `CC-Switch-v3.14.1-Windows.msi` | **推荐** - MSI 安装包,支持自动更新 |
| `CC-Switch-v3.14.1-Windows-Portable.zip` | 便携版,解压即用,不写入注册表 |
### macOS
| 文件 | 说明 |
| -------------------------------- | --------------------------------------------- |
| `CC-Switch-v3.14.1-macOS.dmg` | **推荐** - DMG 安装包,拖入 Applications 即可 |
| `CC-Switch-v3.14.1-macOS.zip` | 解压后拖入 ApplicationsUniversal Binary |
| `CC-Switch-v3.14.1-macOS.tar.gz` | 用于 Homebrew 安装和自动更新 |
> macOS 版本已通过 Apple 代码签名和公证,可直接安装使用。
### HomebrewmacOS
```bash
brew tap farion1231/ccswitch
brew install --cask cc-switch
```
更新:
```bash
brew upgrade --cask cc-switch
```
### Linux
| 发行版 | 推荐格式 | 安装方式 |
| --------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| 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` |
+498
View File
@@ -0,0 +1,498 @@
# 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)**
---
## 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)
```bash
brew tap farion1231/ccswitch
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` |
+498
View File
@@ -0,0 +1,498 @@
# CC Switch v3.15.0
> Claude Desktop が一等管理パネルに昇格(プロキシゲートウェイ経由のサードパーティプロバイダー切り替えを含む)、ロールベースのモデルマッピング、リバースプロキシの大幅強化、Codex OAuth ライブモデル検出、Usage ダッシュボードのフィルター駆動 Hero カード
**[English →](v3.15.0-en.md) | [中文 →](v3.15.0-zh.md)**
---
## 概要
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
```bash
brew tap farion1231/ccswitch
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` |
+498
View File
@@ -0,0 +1,498 @@
# CC Switch v3.15.0
> Claude Desktop 升级为一等管理面板(含第三方供应商代理切换)、按角色的模型映射、反向代理大幅强化、Codex OAuth 实时模型发现、用量看板筛选驱动 Hero 卡
**[English →](v3.15.0-en.md) | [日本語版 →](v3.15.0-ja.md)**
---
## 概览
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
```bash
brew tap farion1231/ccswitch
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` |
@@ -1,6 +1,6 @@
## Major architecture refactoring with enhanced config sync and data protection
**[中文更新说明 Chinese Documentation →](https://github.com/farion1231/cc-switch/blob/main/docs/release-note-v3.6.0-zh.md)**
**[中文更新说明 Chinese Documentation →](https://github.com/farion1231/cc-switch/blob/main/docs/release-notes/v3.6.0-zh.md)**
---
@@ -2,7 +2,7 @@
> 全栈架构重构,增强配置同步与数据保护
**[English Version →](../release-note-v3.6.0.md)**
**[English Version →](v3.6.0-en.md)**
---
@@ -2,7 +2,7 @@
> Stability improvements and user experience optimization (based on v3.6.0)
**[中文更新说明 Chinese Documentation →](https://github.com/farion1231/cc-switch/blob/main/docs/release-note-v3.6.1-zh.md)**
**[中文更新说明 Chinese Documentation →](https://github.com/farion1231/cc-switch/blob/main/docs/release-notes/v3.6.1-zh.md)**
---
@@ -2,7 +2,7 @@
> 稳定性提升与用户体验优化(基于 v3.6.0)
**[English Version →](../release-note-v3.6.1.md)**
**[English Version →](v3.6.1-en.md)**
---
@@ -2,7 +2,7 @@
> From Provider Switcher to All-in-One AI CLI Management Platform
**[中文更新说明 Chinese Documentation →](release-note-v3.7.0-zh.md)**
**[中文更新说明 Chinese Documentation →](v3.7.0-zh.md)**
---
@@ -2,7 +2,7 @@
> 从供应商切换器到 AI CLI 一体化管理平台
**[English Version →](release-note-v3.7.0-en.md)**
**[English Version →](v3.7.0-en.md)**
---
@@ -2,7 +2,7 @@
> Stability Enhancements and User Experience Improvements
**[中文更新说明 Chinese Documentation →](release-note-v3.7.1-zh.md)**
**[中文更新说明 Chinese Documentation →](v3.7.1-zh.md)**
---

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