mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-10-27 02:35:30 +08:00
chore(release): v4.0.10
This commit is contained in:
1 parent
4c263a85ec
commit
db29caefb7
5 files changed
+56
-4
No files matched your search
@@ -5,6 +5,58 @@ All notable changes to CC Switch will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [4.0.10] - 2026-10-13
|
||||
|
||||
The sixth patch release on the 4.0 stable line, centered on `ccswitch://` import links. Links clicked while CC Switch is not running are no longer lost; links can declare the API format, import Pi providers and bring the site's own icon; Codex and Grok Build links keep the provider settings carried in their `config.toml` instead of being rebuilt from a fixed template; values that additive apps would expand into commands or local secrets are rejected; and the confirmation dialog lets the user decide whether to switch right away. Site owners get a guide in three languages and an online link generator. Provider icons can be uploaded into a named "My Icons" library, and the usage page shows first-token time, estimated from session logs when routing is off. Fixes cover the routed Claude Code haiku alias being sent with thinking disabled, Codex sessions recorded under the retired `cc-switch-official` provider, Grok Build session titles on third-party providers, empty balances shown as an expired plan, Codex usage after an in-thread model change, settings autosave carrying unconfirmed directories, flicker when opening provider pages on Windows, and MSI upgrades recreating a deleted desktop shortcut.
|
||||
|
||||
**Stats**: 32 commits | 123 files changed | +12435 insertions | -2355 deletions
|
||||
|
||||
### Added
|
||||
|
||||
- **Deep Link `apiFormat` and Pi Providers**: A single `apiFormat` parameter (`anthropic` / `openai_chat` / `openai_responses` / `gemini_native`) maps to each app's own field: `meta.apiFormat` for Claude Code, Codex and Grok Build (non-native formats need local routing), `npm` for OpenCode, `api` for OpenClaw and Pi, `api_mode` for Hermes. Unsupported combinations are rejected while parsing; links without it keep the previous defaults byte for byte. Pi provider links are now supported; they write a `models.json` node and must carry a model.
|
||||
- **Deep Link Activation Switch**: The confirmation dialog has a switch for "switch after import" (providers, off unless the link sets `enabled=true`, with a warning when on), "add to the app config" (additive apps, on by default), "enable in Pi" and "enable after import" (prompts). The link's `enabled` only sets the initial state. Turning the switch off only saves the row: a new `ProviderService::add_without_switching` skips the first-provider path in `add` that would otherwise write the client config.
|
||||
- **Deep Link `iconUrl`** (closes #8117): A provider link can carry an https address of the site's logo. The confirmation dialog downloads it on open and shows it; importing stores it as the card's custom icon, and any failure silently falls back to `icon` or the name's initials. The address is never stored or rendered and the import command never downloads. The download (`deeplink/icon_fetch.rs`) drops non-https, IP, non-default-port and credentialed addresses, requires every resolved address to be public and pins the connection to them, follows up to 3 redirects by hand with each hop rechecked, uses no system proxy, cookies or Referer, times out after 5 s, caps the body at 256 KB, and requires a PNG / JPEG / WebP / SVG Content-Type matching the magic bytes with bitmap dimensions up to 4096. 198.18.0.0/15 is allowed on purpose for Clash / Surge fake-ip mode. Errors are logged without the URL.
|
||||
- **Custom Provider Icons and "My Icons"** (refs #8117): The icon picker has two groups filtered by one search box. "My Icons" starts with an upload tile (PNG, JPG, WebP or SVG, up to 2 MB and 4096 px); the image is redrawn on a canvas into a 96×96 PNG and a naming dialog (file name by default) saves it to the library and selects it. Library icons can be picked by any provider in any app and renamed or deleted on hover; uploading an image already in the library reuses the entry, and a current custom icon outside the library (for example from an import link) shows as "Current icon" and can be saved. Clicking an icon selects it and closes the picker; "Clear icon" sits next to the search box. Providers store the image itself as a data URI in the existing `icon` column, not a library id, so library changes never alter a provider. The library lives in the cloud-synced settings key `custom_icons` (up to 100 icons, names up to 64 characters). SVG is loaded through `<img>` and rasterized, re-encoding drops EXIF, and custom icons are only ever rendered with `<img>`. Saving a provider or universal provider, syncing a universal provider and adding to the library fully decode the PNG with the `png` crate under a 1 MiB decode limit and cap it at 64 KiB and 256×256; SQL import and cloud sync drop invalid images from `providers`, the universal provider JSON and the library before replacing the main database; rendering checks the PNG signature and IHDR dimensions first. Aggregation no longer derives model key prefixes from a custom icon, and the deep-link `icon` parameter only accepts built-in names.
|
||||
- **First-Token Time on the Usage Page**: Provider and model stats gain a First token column with the median over successful streaming requests through the routing service, and the request log gains a First token column after Speed. Without routing, first-token time is derived from session logs and shown with ≈: for Claude Code, a reply that starts with a thinking block gives the block's write time minus `thinkingDurationMs`; for Codex, newer rollouts record `started_at_ms` on `item_completed`, and the earliest reasoning or agent message item marks the start. Replies that open with text or a tool call yield no estimate. Estimates are stored in `first_token_ms`, so exact and estimated values are told apart by `data_source`; estimated speed still divides by the whole duration, and earlier rows are not backfilled.
|
||||
- **Sub2API Usage Query Template**: Uses `GET /v1/usage` with the provider's key and base URL (with or without `/v1`), shows the plan name, and reports used/total only when the quota has a limit, so unlimited subscriptions no longer show a negative balance. The usage modal's hand-written template-type unions are replaced with the shared `TemplateType`.
|
||||
- **New Provider Preset**: NekoCode (nekoapi.ai) for Claude Code, Claude Desktop, Codex, OpenCode, OpenClaw, Hermes and Pi (MiniMax Code inherits the Pi preset). The site's default groups only serve Claude Code and Codex CLI, so the OpenCode, OpenClaw, Hermes and Pi presets carry the claude-cli User-Agent its "max (external)" group requires; Claude Desktop cannot set one and may be refused.
|
||||
|
||||
### Changed
|
||||
|
||||
- **Imported Usage Scripts Are Enabled by Default**: A provider link that carries a usage script now enables usage query unless it says `usageEnabled=false`. The script runs in the QuickJS sandbox and, without a template type, may only send one same-origin HTTPS request to the base URL. Links without a script still import usage fields disabled; the confirmation badge follows the backend rule and the script body is still shown in full.
|
||||
- **Connection Mode Help Leads With Each Mode's Strengths**: Direct keeps CC Switch out of the request path for the most native experience, Routing offers hot-switching, failover and format conversion, and Aggregation lets models from several providers be switched inside the client.
|
||||
- **Usage Tables Align to the Start**: All columns in the request log, provider, model and pricing tables align to the start (the pricing row actions stay at the end), first and last cells share their headers' 8px inset, and the request log's provider/model share drops from 40% to 32%.
|
||||
- **Presets**: YYLX shows as 鱼鱼连线 (魚魚連線 in zh-TW) through a `nameKey`, while the preset name and the written provider name stay "YYLX". OpenModel sign-up links point at the cc-switch referral URL.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Deep Links Lost on Cold Start**: On Windows and Linux the plugin emitted the startup URL before our handler was registered, and events fired before the JS listener existed (cold start, window rebuilt in lightweight mode) went nowhere. The parsed link or parse error now waits in a backend pending slot with a monotonic id; the dialog peeks on mount and on each `deeplink-pending` notification and acks by id only after showing it, processing serially so an older link can't replace a newer one. `get_current()` is read after registering the URL handler, and our own `RunEvent::Opened` handling on macOS is dropped since the plugin already emits it (links opened twice). `configUrl` is rejected up front, `mcode` is accepted for prompts and `pi` / `mcode` for MCP, and the tray menu refreshes after a provider import.
|
||||
- **Codex Deep Links Dropped Provider Settings** (refs #7438, #7942, #5510): A link carrying `config.toml` used to keep only the key, endpoint and model and rebuild a fixed template, dropping auth mode, headers, websocket support and the model catalog URL. The selected `[model_providers.*]` table now keeps its connection and auth fields (renamed to `custom`), `model_catalog_url` is kept only on the endpoint's origin, and top-level provider-exclusive fields (model, reasoning effort, web_search, context window, sub-agent model) are kept, using the same field lists as the live projection. Global settings are not imported. Tables using `auth`, `aws`, `gateway_oauth` or `env_http_headers` are rejected; `env_key` is dropped in favor of the link's key, and an `env_key`-only link is rejected. Links without a config keep the old template byte for byte.
|
||||
- **Grok Build Deep Links Dropped the Model Profile** (refs #6457): The table named by `[models] default` is kept through an allowlist of Grok 1.0.50 profile fields (display name, description, API backend, context window); endpoint, key and model come from the link. Tables using `auth_provider`, `env_http_headers` or `mtls_cert_dir` are rejected, `env_key` is dropped, and only one model table is imported.
|
||||
- **Deep Link Values Expanded by Additive Apps**: Pi values starting with `!` or containing `$NAME` / `${NAME}`, OpenCode `{env:}` / `{file:}`, and `${...}` for OpenClaw and Hermes would run a command or send local secrets and files to the link's endpoint. They are rejected when parsing, when merging `config` and when building the provider.
|
||||
- **Routed Claude Code Haiku Requests Rejected for Disabled Thinking** (fixes #8118): Routing writes stable role aliases, and Claude Code looks the alias up in its own model table to decide how to send thinking. `claude-haiku-4-5` is listed as able to disable thinking without adaptive thinking, so haiku-tier requests went out with thinking disabled and upstreams that require thinking rejected them. The alias is now `claude-haiku-5-5`, matching the sonnet and opus aliases; the proxy still maps by the "haiku" keyword.
|
||||
- **Codex Sessions Under the Retired `cc-switch-official` Provider** (refs #7948): v3.17–v3.20 recorded official-account sessions through routing under `cc-switch-official`, and resuming them in 4.0 failed with "Model provider `cc-switch-official` not found". On startup they are moved to the built-in `openai` bucket in the state DB and each rollout's `session_meta` line (compressed rollouts included), before the unify migration so that setting still works through its normal path; `config.toml` is untouched. The migration is skipped without recording completion when `config.toml` or a profile still selects `cc-switch-official`, or a state DB cannot be locked. Completion is recorded per Codex config directory and backups go to the existing session group migration folder.
|
||||
- **Grok Build Session Titles on Third-Party Providers** (fixes #7003): With `models.session_summary` unset, Grok Build (1.0.50) generates titles with the built-in `grok-4.6` model but sends the request to the default table's endpoint, so third-party upstreams reject it. The switch patch now points `session_summary` at the target table when it is unset or names a table CC Switch wrote, and removes it when switching to the official account; a user's own choice is left alone.
|
||||
- **Empty OpenRouter and Novita Balances Shown as an Expired Plan** (#8175, fixes #8148): A parsed balance of zero or less now stays valid and shows the existing "balance used up" line. Missing, malformed, non-finite or overflowing amounts return an error instead of a zero balance.
|
||||
- **Codex Usage After an In-Thread Model Change** (#8176): A model change recorded in `event_msg/thread_settings_applied` without a new `turn_context` was ignored, so later tokens were attributed and priced as the previous model (or `unknown`). `payload.thread_settings.model` is now read; existing rows can be corrected with Usage > Data sources > Rebuild Codex usage.
|
||||
- **Settings Autosave Committed Unconfirmed Directory Edits** (#8023, fixes #7849): Autosave of an unrelated setting now keeps the eight directory fields at their confirmed values unless the update changes that directory, and the directory display is reconciled with the effective path after the form resets.
|
||||
- **Flicker When Opening Provider Pages on Windows** (#8159, refs #8141): `FullScreenPanel` gains a `none` motion preset, used by the add and edit provider pages so the whole-panel fade no longer flickers.
|
||||
- **MSI Upgrades Recreated a Deleted Desktop Shortcut**: A major upgrade reinstalls from scratch and the shortcut component was unconditional. AppSearch now looks for the existing shortcut before the old version is removed, and the shortcut is installed only on a fresh install or when it is still present.
|
||||
- **Japanese Advanced Options Label**: 高級オプション is renamed to 詳細オプション in the UI and in the Japanese README, routing guides and user manual.
|
||||
|
||||
### Docs
|
||||
|
||||
- Site owner integration guide in Chinese, English and Japanese: building links, wiring an import button that fetches the link from the backend, the not-installed fallback, usage scripts (New API and Sub2API ship an import button already).
|
||||
- The link generator becomes a tool for site owners hosted at ccswitch.io/deplink.html (the old GitHub Pages link returned 404), with provider / MCP / prompt / Skill tabs, per-app `apiFormat` choices, usage script templates and `icon` / `iconUrl` checks matching the app.
|
||||
- The user manual covers `apiFormat`, Pi links, the activation switch, `iconUrl`, Codex config import rules, the Sub2API template and "My Icons".
|
||||
|
||||
### Upgrade notes
|
||||
|
||||
- **No database schema change** (still 20). The "My Icons" library is a settings key.
|
||||
- Routed Claude Code clients get the new haiku alias when CC Switch starts and reattaches.
|
||||
- The `cc-switch-official` session migration runs once per Codex config directory on startup.
|
||||
- New presets only affect newly added providers.
|
||||
|
||||
## [4.0.9] - 2026-10-11
|
||||
|
||||
The fifth patch release on the 4.0 stable line. Codex threads that carry tool results with no matching call, such as the create_thread receipt the Codex desktop app injects into new threads, no longer fail on strict Chat upstreams (HTTP 400) or xAI native Responses (HTTP 422). Clients that cannot reach the host's loopback, such as Claude Desktop sessions in WSL2, can be given a separate connection address for local routing. Fetched models are now picked in a dialog that can also remove them and shows each model's parameters, Codex can set a default sub-agent model and reasoning effort, and the provider forms move field explanations into help tips. Other fixes cover OpenAI-format Claude upstreams receiving `x-api-key`, aggregation compatibility switches, the UI language on cold start, macOS local network access and flicker when opening the provider editor.
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cc-switch",
|
||||
"version": "4.0.9",
|
||||
"version": "4.0.10",
|
||||
"description": "All-in-One Assistant for Claude Code, Codex & Gemini CLI",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
Generated
+1
-1
@@ -758,7 +758,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc-switch"
|
||||
version = "4.0.9"
|
||||
version = "4.0.10"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"arboard",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "cc-switch"
|
||||
version = "4.0.9"
|
||||
version = "4.0.10"
|
||||
description = "All-in-One Assistant for Claude Code, Codex & Gemini CLI"
|
||||
authors = ["Jason Young"]
|
||||
license = "MIT"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "CC Switch",
|
||||
"version": "4.0.9",
|
||||
"version": "4.0.10",
|
||||
"identifier": "com.ccswitch.desktop",
|
||||
"build": {
|
||||
"frontendDist": "../dist",
|
||||
|
||||
Reference in new issue
Block a user