diff --git a/CHANGELOG.md b/CHANGELOG.md index 75a4ab0bd..4a22b4dde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,38 @@ 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.17] - 2026-10-20 + +This release fixes two regressions from 4.0.16 and polishes the tray panel. Lightweight mode frees the tray panel's WebView again, so WebView2 processes exit on Windows, and Codex no longer gets stuck on the sign-in page after a long-expired stashed ChatGPT login was given back on entering routing. The tray panel keeps its rows in place while hovering between apps, fits high-DPI and small Windows displays, lines up quota bars with a time-until-reset, and shows remaining balances in green; on Windows a left click opens the main window again. The Hermes form now warns when a provider key is one of Hermes' built-in provider ids. Other fixes cover the proxy port staying taken after quitting on Windows, Codex remote compaction usage recorded as zero, MCP servers lost when several are toggled at once, URL-only MCP servers synced to Hermes and OpenCode as empty entries, smart quotes inside valid TOML strings being rewritten, WebDAV sync on Data Capsule, API keys capitalized by macOS, and MSI installs over a portable folder still treated as portable. + +**Stats**: 16 commits | 34 files changed | +1674 insertions | -164 deletions + +### Changed + +- **Hermes Built-in Provider Key Warning**: Hermes routes `model.provider` to its built-in provider whenever the name is a canonical built-in id, so a card keyed `deepseek` or `openrouter` was ignored and Hermes asked for the built-in's own API key env var. #8538 only fixed the two MiniMax presets. The provider key field now warns for any of the 52 canonical ids (generated from hermes-agent rc.3-v0.22.0) and suggests `cc-switch-`; a locked key gets a variant that says to re-add the provider under another key. Aliases such as `kimi` still reach the custom provider and are not flagged. Saving is not blocked. +- **Tray Panel Quota Lines**: Each quota block is one grid (label, bar, reset), so bars start and end at the same x across tiers and extend under the "In use" column. The absolute reset date is replaced by a compact time until reset (at most two units, e.g. "1d 23h"), and labels no longer wrap. A pay-as-you-go balance colors only the amount green, like the provider card; a used-up balance keeps its warning color. The panel payload carries a new `emphasis` field for this. +- **Windows Tray Left Click Opens the Main Window** (#8572): Left click always opens the main window; right click shows the selected tray style (panel or menu). The "Tray style" help text says so. macOS is unchanged: both buttons open the selected style. + +### Fixed + +- **Lightweight Mode Kept the Tray Panel WebView Alive** (refs #8612): Since the panel became the default in 4.0.16, it is a second WebView window that was only hidden after the first tray click, so WebView2 processes never exited in lightweight mode. In lightweight mode the panel is now destroyed whenever it is hidden (and right away when entering lightweight mode with it hidden), deferred to a later main-thread turn and re-checked before tearing down; the next tray click creates it again with a fresh theme state and, on macOS, fresh glass views. +- **Expired Stashed ChatGPT Login Given Back on Entering Routing** (refs #8573): The #8431 restore in 4.0.16 could hand back a login stashed months earlier, which made the route table require OpenAI auth and left Codex desktop stuck refreshing a dead token on every enter/exit. The restore now skips a login whose `access_token` JWT has expired; undecodable tokens are still restored, and the skipped login stays in the stash for switching back to an official card. +- **Tray Panel Rows Jumping and Clipped on Scaled Windows Displays** (#8572, #8595, fixes #8549, #8553, refs #8564): Both columns now follow the main panel's height and long provider lists scroll inside the sub panel, so hovering between apps no longer moves rows under the cursor or leaves blank space with a single app. On Windows, WebView CSS pixels and screen logical pixels are converted with the monitor scale factor, the panel is narrowed and clamped to the monitor work area, footer buttons can shrink, and a `devicePixelRatio` change after moving to another monitor relays out the panel and its clip region on the first show. +- **Proxy Port Still Taken After Quitting on Windows** (refs #8552): The locked mio 1.1.1 created inheritable listener sockets, and terminals or CLI tools started by CC Switch inherited them, so the port stayed LISTENING under the dead PID and the next start failed with os error 10048. mio is bumped to 1.2.1 (`WSA_FLAG_NO_HANDLE_INHERIT`), with a Windows test asserting the listener handle is not inheritable. +- **Codex Remote Compaction Usage Recorded as Zero** (#8479): Codex 0.153+ writes a `token_usage_record` per response, and a remote compaction follows it with an all-zero `last_token_usage`. Such records are now imported as `codex_thread:{root_thread_id}:usage:{response_id}`; matching `token_count` rows stay the only row, existing `event_index` values and cursors are kept, and lines scanned before the upgrade are not re-imported. +- **MCP Servers Lost When Toggled Concurrently** (refs #8580): `toggle_mcp_app` and `set_mcp_enabled` edited the live config without the per-app switch lock, so parallel toggles, or a toggle racing a provider switch or MCP resync, could drop servers from the live file while the database showed them enabled. Both commands now go through `McpService::toggle_app_locked`. +- **URL-only MCP Servers Synced as Empty Entries to Hermes and OpenCode** (refs #8579): A spec with a `url` but no `type` (from JSON mode or a deep link) was treated as stdio, giving Hermes an entry with only `enabled: true` and OpenCode a `local` entry with an empty command. Codex's transport inference moves to `mcp/validation.rs` and all three projections use it. +- **Smart Quotes Inside Valid TOML Strings Rewritten** (refs #8559): Normalization replaced every curly or fullwidth quote, so MCP import and validation and the Codex config editor turned `"don’t"` into `"don't"` and rejected valid values such as `["say“hello”"]`. Only smart quotes used as string delimiters become ASCII now; quotes inside ASCII-quoted strings are kept, multi-line strings and comments are handled, and the Chinese IME case still parses. Text without smart quotes is unchanged. +- **WebDAV Sync Failed on Data Capsule** (refs #8554): CSTCloud Data Capsule answered `PUT manifest.json` with 500 for multi-line JSON sent as `application/json`. The manifest is uploaded as `application/octet-stream`; its bytes and hash are unchanged and readers ignore Content-Type, so old and new versions read each other's manifests. S3 is unchanged. +- **macOS Capitalized Typed API Keys**: The API key field lacked the autocorrect, auto-capitalization and spellcheck opt-outs of the shared input, so a typed `sk-…` key shown in plain text could be saved as `Sk-…`. Pasted keys were not affected. +- **MSI Install Over a Portable Folder Still Treated as Portable** (#8529, refs #3132): A leftover `portable.ini` kept the app in portable mode, so the update button only opened the Releases page. The MSI now removes `INSTALLDIR/portable.ini` on install (not on uninstall, no wildcard). + +### Upgrade notes + +- **No database schema change** (still 20). +- On Windows a left click on the tray icon opens the main window again (it opened the panel in 4.0.16); right click shows the tray style chosen in Settings → General. +- Codex compaction lines scanned before upgrading stay unbilled; only lines read after the upgrade use the new path. + ## [4.0.16] - 2026-10-19 This release turns the tray into a quick panel and fixes a batch of Codex and routing issues. Clicking the tray icon now opens a panel with each app's in-use provider, mode, quota and usage; the native menu is still available under Settings → General → Tray style. In Codex aggregation mode, a session no longer gets stuck compacting on the provider it came from, and the ChatGPT login is no longer lost every time CC Switch restarts while Codex is routed. Codex through Chat upstreams keeps parallel tool results together around image notices, configured GPT context windows now apply to official GPT catalog entries, and the 272K GPT cap from 4.0.13 only applies to windows borrowed from the vendor entry. Claude Code routing and Claude Desktop route mode publish the 5.5 catalog ids for 5.5 upstreams. Other fixes cover Zhipu pay-as-you-go accounts showing "query failed", Volcengine plan quota turning red on new cards, fnm-managed Node CLIs on Windows, an idle card that could not be deleted, the "Get API Key" link in the edit form, and a softer grey macOS icon tile. OpenCode cards can now set OpenCode's default model. diff --git a/package.json b/package.json index 62c3ebfe2..1d67ca721 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cc-switch", - "version": "4.0.16", + "version": "4.0.17", "description": "All-in-One Assistant for Claude Code, Codex & Gemini CLI", "type": "module", "scripts": { diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 1d0bd5c55..d3e66f1dc 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -758,7 +758,7 @@ dependencies = [ [[package]] name = "cc-switch" -version = "4.0.16" +version = "4.0.17" dependencies = [ "anyhow", "arboard", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index b144eaca6..99648b241 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cc-switch" -version = "4.0.16" +version = "4.0.17" description = "All-in-One Assistant for Claude Code, Codex & Gemini CLI" authors = ["Jason Young"] license = "MIT" diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 3f569daab..a5477bc30 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "CC Switch", - "version": "4.0.16", + "version": "4.0.17", "identifier": "com.ccswitch.desktop", "build": { "frontendDist": "../dist",