From 8d1b3306d09a27b9d8fc29694791d8421aba5f93 Mon Sep 17 00:00:00 2001 From: Jason Date: Wed, 1 Jul 2026 23:55:55 +0800 Subject: [PATCH] chore(release): v3.16.5 --- CHANGELOG.md | 43 ++++++++++++++++++++++++++++++++++++++- package.json | 2 +- src-tauri/Cargo.lock | 2 +- src-tauri/Cargo.toml | 2 +- src-tauri/tauri.conf.json | 2 +- 5 files changed, 46 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9b970c2f..8f948bbdc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,11 +5,52 @@ 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). -## [Unreleased] +## [3.16.5] - 2026-07-01 + +Development since v3.16.4 reworks the Codex native-Responses path — restoring a generated model catalog for proxy-less direct-connect, decoupling model mapping from the local-routing toggle, and adding a host/model-prefix blacklist that disables Codex's built-in web_search on gateways that reject it — alongside a broad wave of new provider presets (Qiniu and Code0.ai across all seven apps, the FennoAI/ZetaAPI/TeamoRouter/NekoCode partners, and the non-partner Amux), Claude Sonnet 5 pricing plus a default-tier bump to it, a categorized two-level session view with group-level batch selection, live auto-sync of the shared Claude common config on switch, and a run of credential-safety, tool-detection, Doubao model-id, branding, and icon-size fixes. + +**Stats**: 36 commits | 93 files changed | +5,678 insertions | -2,804 deletions + +### Added + +- **Codex Native Responses Direct-Connect Regenerates a Model Catalog**: Reverses the v3.16.4 direction that dropped the catalog — Codex providers now run in two explicit modes, and native direct-connect once again ships a catalog file. Providers with `apiFormat: "openai_responses"` run with no proxy, and cc-switch generates `~/.codex/cc-switch-model-catalog.json` (`CC_SWITCH_CODEX_MODEL_CATALOG_FILENAME`, provider id `custom`) so Codex Desktop actually shows the custom models and tools work without the freeform `apply_patch` (`type=custom`) tool that native gateways like MiMo reject — editing falls back to `shell_command`. Catalog generation is keyed on `apiFormat` via `CodexCatalogToolProfile` and decoupled from the route-takeover toggle, so a native provider persists a catalog without enabling local route mapping, while `openai_chat` keeps the existing Responses↔Chat proxy conversion unchanged. Codex's parser requires `base_instructions` on every entry, so the native template (`codex_native_responses_template.json`, slug `gpt-5.5`) carries a neutral default that per-vendor official text overrides (MiMo, MiniMax); synthesized catalogs for Qwen/Doubao/LongCat use the neutral default. Existing native providers must be re-saved once to regenerate a valid catalog (no DB migration). +- **Categorized Session View With Two-Level Grouping**: The Session Manager gains a grouped view mode alongside the flat list, toggled via a List/ListTree Select in the toolbar and persisted to `localStorage` under `cc-switch.sessionManager.listViewMode`. The new `groupSessionsByProviderAndDirectory` helper builds a two-level hierarchy (provider group → project-directory group): directory groups are keyed by `getSessionDirectoryGroupKey(providerId, projectDir)` and labeled with `getBaseName(projectDir)`, and sessions lacking a `projectDir` fall into an "unknown directory" bucket (`UNKNOWN_PROJECT_DIR_KEY = __unknown_project_dir__`). Both levels are Radix Collapsible sections whose expansion state is serialized to `cc-switch.sessionManager.groupExpansionState` (pruned to valid keys after load), with a "collapse all" button; in batch mode each group header gains a tri-state checkbox that selects/deselects every selectable session (those with a `sourcePath`) at once, backed by a `Minus`-glyph indeterminate state added to `ui/checkbox.tsx` and a selected/selectable count badge. New keys were added across all four locales (zh/en/ja/zh-TW). The change is entirely frontend — no Tauri commands or DAO changes. (#4776) +- **Qiniu (七牛云) Provider Preset Across All Seven Apps**: Added the Qiniu Cloud AI gateway as a partner aggregator spanning Claude Code, Claude Desktop, Codex, Gemini, OpenCode, OpenClaw, and Hermes — the widest coverage of the batch and the only one carrying a Gemini preset. Because Qiniu relays native Claude/GPT/Gemini rather than remapping to domestic models, Claude Code/Desktop use the Anthropic-compatible bare host with native passthrough (no model pinning), Codex hits native Responses at `https://api.qnaigc.com/bypass/openai/v1` defaulting to `gpt-5.5`, and Gemini uses `gemini-3.1-pro-preview` via `https://api.qnaigc.com/bypass/vertex`; OpenCode/OpenClaw/Hermes default to `gpt-5.5` over the OpenAI-compatible `/v1`. Each type carries `endpointCandidates` listing the `api.qnaigc.com` primary plus the `api.modelink.ai` overseas mirror for failover. It is marked `isPartner` with referral `https://s.qiniu.com/nMvAvy`, a localized display name via `nameKey` (`providerForm.presets.qiniu`) and a partner-promotion blurb in all four locales (zh/en/ja/zh-TW), and registers the `qiniu.png` icon through URL import plus `iconUrls` and metadata. +- **FennoAI, ZetaAPI, and TeamoRouter Partner Presets**: Added three partner aggregators — FennoAI (`api.fenno.ai`), ZetaAPI (`api.zetaapi.ai`), and TeamoRouter (`api.teamorouter.com`) — each covering Claude Code, Claude Desktop, Codex, OpenCode, OpenClaw, and Hermes with no Gemini preset, since these relay native Claude/GPT only. In every case Claude Code/Desktop use the Anthropic-compatible bare host with native passthrough, Codex uses native Responses (FennoAI at `api.fenno.ai`, ZetaAPI and TeamoRouter at their `/v1` paths) defaulting to `gpt-5.5`, and OpenCode/OpenClaw/Hermes default to `gpt-5.5` over the OpenAI-compatible `/v1`. All three are `isPartner` with referral `apiKeyUrls` (FennoAI's ¥9.9 Coding Plan link, ZetaAPI's `zetaapi.ai/go/ccs`, TeamoRouter's `teamorouter.com` with `utm_source=cc_switch` — its in-app link stays English while README links are per-language), each ships a localized promo blurb in zh/en/ja/zh-TW plus a sponsor row in all four READMEs, and each registers its own icon (`fenno-icon.webp`, `zetaapi-icon.png`, `teamorouter`). Two carry surfaced discount codes: ZetaAPI gives a first-recharge 10% discount with promo code `CC-SWITCH`, and TeamoRouter gives new users 10% off their first top-up. +- **Amux Aggregator Preset**: Added Amux (`api.amux.ai`) as a non-partner aggregator across Claude Code, Claude Desktop, Codex, OpenCode, OpenClaw, and Hermes, with no Gemini preset. Claude Code/Desktop use the bare Anthropic-compatible host, Codex uses native Responses over the `/v1` path, and the remaining three apps default to `gpt-5.5` over the OpenAI-compatible endpoint. Unlike the partner presets in this batch it carries no `isPartner` flag, referral link, or promo copy; the `amuxapi-icon.svg` is registered as an inline `currentColor` icon in `src/icons/extracted/index.ts` and `metadata.ts` rather than a raster URL import. +- **Code0.ai Partner Preset Across All Seven Apps**: Added Code0.ai (`code0.ai`) as a partner aggregator spanning all seven apps — Claude Code, Claude Desktop, Codex, Gemini, OpenCode, OpenClaw, and Hermes. Claude Code, Claude Desktop, and Gemini use the bare `https://code0.ai` host (Anthropic-native passthrough with no model pinning for the two Claude apps, `gemini-3.1-pro-preview` for Gemini), Codex hits native Responses at `https://code0.ai/v1`, and OpenCode/OpenClaw/Hermes default to `gpt-5.5` over the OpenAI-compatible `/v1`. It is marked `isPartner` with a `?source=ccswitch` referral on the API-key signup link, a partner-promotion blurb surfacing the CC Switch test-credit offer in all four locales (zh/en/ja/zh-TW), a sponsor row in all four READMEs, and the `code0.png` icon registered via URL import. +- **NekoCode Partner Preset Across Six Apps**: Added NekoCode (`nekocode.ai`) as a partner aggregator spanning six apps — Claude Code, Claude Desktop, Codex, OpenCode, OpenClaw, and Hermes (no Gemini preset). Claude Code and Claude Desktop use the bare `https://nekocode.ai` host (Anthropic-native passthrough with no model pinning), Codex hits native Responses at `https://nekocode.ai/v1`, and OpenCode/OpenClaw/Hermes default to `gpt-5.5` over the OpenAI-compatible `/v1`. It is marked `isPartner` with a `?aff=CCSWITCH` referral on the API-key signup link (kept off the actual request endpoints), a partner-promotion blurb in all four locales (zh/en/ja/zh-TW), and a sponsor row in all four READMEs, both surfacing the CC Switch offer — 10% off top-ups with promo code `cc-switch` at recharge. The `nekocode-icon.png` icon is registered via URL import. +- **Claude Sonnet 5 Model Pricing**: Seeded a `claude-sonnet-5` pricing row in `schema.rs` at Anthropic list price — $3/$15 per Mtok input/output and $0.30/$3.75 cache read/write, identical to the Sonnet 4.6 rates. The introductory $2/$10 promo (valid through 2026-08-31) is deliberately not seeded, so accounting reflects steady-state list pricing rather than a temporary discount. The row is applied on next app start via `ensure_model_pricing_seeded` and requires no `SCHEMA_VERSION` bump. + +### Changed + +- **Decoupled Codex Model Mapping From the Local-Routing Toggle**: Aligns the Codex provider form with Claude Code — the model-mapping catalog is now independent of route takeover, since native Responses providers (MiMo, Doubao, MiniMax) need it for proxy-less direct connect while Chat providers use the proxy regardless of any per-provider flag. The "Needs Local Routing" toggle is removed: it had no backend field and only gated catalog/reasoning persistence, which is equivalent to whether the mapping is filled. Model mapping is now always shown for non-official providers and persisted whenever the list is non-empty (the backend already keys off `modelCatalog.models`), while reasoning visibility/persistence is gated on the Chat format instead of the toggle. The Chat upstream-format option is marked "routing required" with a refreshed advanced-section hint across all four locales (zh/en/ja/zh-TW), dead `localRouting*` keys are dropped, and the model-mapping block moves above the custom User-Agent block. Also fixes `useCodexConfigState` dropping `supportsParallelToolCalls`/`inputModalities`/`baseInstructions` when loading a saved provider — which silently lost parallel tools, image input, and the official base instructions on edit — by preserving them on load (camelCase and snake_case) and comparing them in the row sync. +- **Auto-Sync Claude Common Config From Live settings.json on Switch**: When switching away from a Claude provider that has `common_config_enabled`, the service now re-extracts the shareable portion of its live `settings.json` and replaces the stored common-config snippet, instead of only writing the snippet one way. This captures config the user added directly in the running app (`enabledPlugins`, `hooks`, `env`, `theme`, shared prefs) so it isn't silently lost on the next switch, and it propagates deletions so a removed key isn't re-injected later. The sync in `services/provider/mod.rs` is scoped strictly to Claude providers with `common_config_enabled`, is skipped when the snippet was explicitly cleared, and all failures are non-fatal (warn-only) and never block the switch. Four integration tests cover capture / delete-sync / opt-out / cleared. +- **Default Sonnet Tier Now Pins to Claude Sonnet 5**: Bumped every default Sonnet pin from `claude-sonnet-4-6`/`claude-sonnet-4.6` to `claude-sonnet-5` across all provider presets (`claudeProviderPresets`, `claudeDesktopProviderPresets`, `hermesProviderPresets`, `openclawProviderPresets`, `opencodeProviderPresets`, and universal `NEWAPI_DEFAULT_MODELS`), covering the `ANTHROPIC_MODEL` / `ANTHROPIC_DEFAULT_SONNET_MODEL` / `ANTHROPIC_DEFAULT_OPUS_MODEL` env keys and prefixed variants like `anthropic/claude-sonnet-5` and `global.anthropic.claude-sonnet-5`. The Claude Desktop `DEFAULT_PROXY_ROUTES` sonnet `route_id` in `claude_desktop_config.rs` also moves to `claude-sonnet-5` (`supports_1m` preserved), and the route-derivation test expectations were updated to match. Non-Anthropic pins (gpt/gemini/glm/sonnet-4-5) were left untouched. +- **Doubao Dated Model Id and YYMMDD Pricing Normalization**: Switched the Doubao (DouBaoSeed) preset model id to the dated form `doubao-seed-2-1-pro-260628` across every app surface (config default, generated Codex catalog, and OpenClaw namespaced refs), because Volcengine Ark rejects the bare `doubao-seed-2-1-pro` with a 404 ("model does not exist or you do not have access to it") even after activation and only accepts the full dated id. Because real usage now arrives with a date suffix, `strip_model_date_suffix` in `usage_stats.rs` was extended to also strip Volcengine's 6-digit YYMMDD form (`-260628`, `-250615`) in addition to the existing 8-digit YYYYMMDD/ISO handling; the 6-digit branch validates month 01-12 and day 01-31 to avoid eating non-date version suffixes like `-123456`, then falls back to `None` for exact matching. This keeps the bare-name seed row as the canonical pricing identity, fixing the $0-cost display for every Volcengine Doubao model. Unit and end-to-end regression tests were added. +- **"Write Common Config" Renamed to "Apply Common Config"**: The original label "Write Common Config" (写入通用配置) was ambiguous about data-flow direction, reading as "write the current config INTO the common config" when the actual behavior is the reverse — the saved common-config snippet is merged INTO this provider's config. The checkbox is renamed to "Apply Common Config" across all four locales (zh/en/ja/zh-TW), including every hint/guide/notice reference and the `CommonConfigEditor` / `GeminiConfigSections` defaultValue fallbacks, and the Gemini hint wording is aligned with the claude/codex "when checked" phrasing. The Japanese user manual (`docs/user-manual/ja/2-providers/2.1-add.md`) and `README_JA.md` were also synced to 共通設定を適用 / 共有設定を適用. (#4829) +- **OpenClaw Doubao Context Window Aligned to 262144**: The OpenClaw DouBaoSeed preset hard-coded `contextWindow` 128000 while the Codex preset/catalog used 262144 for the same model, giving OpenClaw users a too-small window that could compress or truncate long context prematurely. Bumped `openclawProviderPresets.ts` to 262144 and added a cross-preset consistency test asserting the OpenClaw and Codex Doubao context windows stay equal so the two sides cannot silently drift apart again. +- **Volcengine/Doubao/BytePlus Website Links Restored to Official Homepages**: The `websiteUrl` for the 火山Agentplan, BytePlus, and DouBaoSeed presets had accidentally been set to the same invite/console link as `apiKeyUrl`, so the "visit official site" button routed users to the referral/API-key page instead of the product homepage. Restored clean official homepages across all six app preset files — 火山Agentplan to `https://www.volcengine.com/product/ark`, DouBaoSeed to `https://www.volcengine.com/product/doubao`, and BytePlus to `https://www.byteplus.com/en/product/modelark` (dropping the utm params) — while leaving the `apiKeyUrl` referral links intact. +- **Kimi and SiliconFlow Referral Links Refreshed**: Updated two sponsor referral sets across presets and READMEs. Following Moonshot's console rebrand to Kimi, the Kimi preset referral links and the domestic (ZH) README banner moved to the new `platform.kimi.com` domain — the domestic console `platform.moonshot.cn/console` → `platform.kimi.com`, the API-key page → `platform.kimi.com/console/api-keys`, and the Coding Plan link `www.kimi.com/code/docs/` → `www.kimi.com/code/` — and the missing `?aff=cc-switch` attribution param was added to the codex and openclaw entries. API endpoints (`api.moonshot.cn`, `api.kimi.com/coding`) were left unchanged, and the presets have no overseas variant (the separate EN/DE/JA README switch to `platform.kimi.ai` is covered under Docs below). Separately, the SiliconFlow invite code was rotated from `drGuwc9k` to `YflgU2Ve` across all README locales and the claude, claude-desktop, codex, hermes, and openclaw presets. +- **Downscaled Oversized Provider Icons to 256px**: Shrank a batch of bundled provider icons that shipped far larger than their ~32px on-screen render size in `ProviderIcon`, cutting bundle weight with no code, filename, or import changes (aspect ratio preserved, rendered via `` object-contain). Raster PNGs: ZetaAPI 1254×1254/940KB→40KB, relaxcode 1462×1076/1.16MB→42KB, sudocode 2048×2048/432KB→37KB, hermes 512×512/125KB→38KB, claudecn 512×512/109KB→46KB, atlascloud 3525×3300/105KB→9KB. Two "fake vector" SVGs wrapping a single oversized base64 PNG were re-embedded at a 256px max dimension keeping the SVG wrapper: ccsub 1.16MB→60KB and shengsuanyun 212KB→51KB. Also removed `dds.svg`, a 1.4MB genuine 2222-path vector that was never imported in `index.ts` nor referenced under `src/`, so it only bloated the repo without ever shipping. ### Fixed +- **Disable web_search for Native Codex Gateways That Reject It**: Some native `/responses` gateways whose first-party models lack OpenAI's hosted `web_search` tool reject it with "tool type 'web_search' is not supported by this gateway phase" (`responses_feature_not_supported`), and Codex sends the tool by default (config-driven, not gated by the catalog's `supports_search_tool`), producing hard 400s. cc-switch now writes the top-level TOML line `web_search = "disabled"` for those vendors via `set_codex_native_web_search_field`, injected alongside `model_catalog_json` at switch time. Scope is a blacklist (default-on): only providers matched by `base_url` host — `CODEX_WEB_SEARCH_REJECT_HOSTS = xiaomimimo.com, longcat.chat, minimax.io, minimaxi.com` — or by model brand prefix — `CODEX_WEB_SEARCH_REJECT_MODEL_PREFIXES = mimo, longcat, minimax, qwen3-coder` — are disabled, so relays serving real GPT, DouBao, general Qwen, and any unknown provider keep Codex's default. The `qwen3-coder` prefix suppresses the tool for the native `qwen3-coder-plus` direct-connect preset (百炼/DashScope marks built-in tools unsupported for the coder series) while general Qwen models sharing the DashScope host stay enabled — matching is on the model axis (after stripping any aggregator `vendor/` path segment like `MiniMaxAI/MiniMax-M3` or `qwen/qwen3-coder-plus`), so it also catches aggregators such as SiliconFlow fronting a reject vendor's model. A blacklist was chosen over a fuzzy "is this GPT?" whitelist because wrongly keeping `web_search` ON fails with a hard 400, and an ownership sentinel means cc-switch only ever removes a `web_search` key whose value equals its own `disabled`, so existing providers need no re-save and switching back re-enables web search. Also corrects the LongCat-2.0-Preview preset context window from 131072 (128K) to its real 1048576 (1M), aligning with the MiMo/Qwen 2^20 convention, and tightens the native Responses preset tests to assert exact model→contextWindow catalogs instead of only checking catalog presence. +- **Strip All Credential-Like Keys From the Shared Claude Common-Config Snippet**: `extract_claude_common_config` previously only redacted `ANTHROPIC_API_KEY` and `ANTHROPIC_AUTH_TOKEN`, but Claude providers legitimately carry other credentials (`OPENROUTER_API_KEY`, `GOOGLE_API_KEY`, and possibly OpenAI/Gemini/AWS Bedrock/Vertex secrets), which could leak into the shared snippet and then be injected into other providers. Extraction now pattern-matches and strips any credential-shaped env key (`*_API_KEY` / `*_AUTH_TOKEN` / `*secret*` / `*token*`, etc.), while preserving plural `*_TOKENS` values like `MAX_OUTPUT_TOKENS` as legitimately shareable. This also closes the same pre-existing leak in the manual Extract and one-time auto-extract paths, and is covered by a dedicated credential-stripping unit test. +- **Usage-Script Credentials Persisted Only as Explicit Overrides**: Provider usage scripts store optional `api_key`/`base_url` fields that override the provider's live credentials when querying quota, but these were silently mirroring the provider's own credentials — so copying a provider or editing its main API key/base URL left the usage script pinned to the old endpoint and key, and quota queries kept hitting the stale target. `ProviderService::add`/`update` now run `normalize_usage_script_credential_overrides` before persisting: if the script's trimmed `api_key` or slash-normalized `base_url` matches the provider's resolved usage credentials (or is blank) it is cleared to `None` so the query falls back to `resolve_usage_credentials` from the live config, while genuinely distinct overrides are kept and `template_type == "token_plan"` scripts are left untouched. The deeplink import path gained matching `normalize_deeplink_api_key`/`base_url` helpers, and the frontend now invalidates `usageKeys.script(id, appId)` (including the `originalId` when a provider is renamed) on update so the homepage re-queries with the corrected config instead of the test-time cache. (#4654) +- **Hermes Config Dir Now Resolves Correctly on Windows**: CC Switch hardcoded `~/.hermes` as the Hermes config directory, but Hermes itself resolves it via `get_hermes_home()` — the `HERMES_HOME` env var, then a platform default of `%LOCALAPPDATA%\hermes` on Windows (`~/.hermes` on mac/Linux). On Windows this meant CC Switch wrote provider configs to a path Hermes never reads, so provider switches had no effect. `get_hermes_dir()` now mirrors Hermes' own resolution order — `settings.hermes_config_dir` explicit override, then `HERMES_HOME` taken verbatim (trimmed, non-empty, no `~` expansion, matching Hermes' `Path(val)`), then the platform default reading the actual `LOCALAPPDATA` env var (falling back to `~\AppData\Local\hermes`) on Windows and `~/.hermes` elsewhere. This deliberately re-honors the `HERMES_HOME` that #3470 had dropped, since unlike Codex/Claude the Hermes Windows installer sets `HERMES_HOME` as a first-class mechanism for relocated installs. Config-dir tests were also isolated from ambient `HERMES_HOME`/`LOCALAPPDATA`. (#4680, refs #3178, #3470) - **Linux Wayland: Override the AppImage's Forced `GDK_BACKEND=x11`**: The AppImage's GTK launch hook (`linuxdeploy-plugin-gtk.sh`) unconditionally exports `GDK_BACKEND=x11` to dodge a historical native-Wayland crash (tauri-apps/tauri#8541). On newer Wayland + NVIDIA setups this forced XWayland leaves the WebKitGTK web content unable to receive pointer events — the GTK title bar stays clickable but the page is dead — and black-screens on resize; the existing `WEBKIT_DISABLE_*` mitigations don't help because the root cause is the forced window backend, not rendering. Since the hook also overrides any user-set `GDK_BACKEND`, there was no way to switch back without unpacking the AppImage. `main.rs` now reads an opt-in `CC_SWITCH_GDK_BACKEND` escape hatch (which the hook never touches) before GTK init: leaving it unset keeps the current x11 behavior unchanged (zero regression), while `CC_SWITCH_GDK_BACKEND=wayland` forces native Wayland. The override is generic, so users on tiling Wayland compositors hitting the inverse input bug can set `CC_SWITCH_GDK_BACKEND=x11`. (#4351, fixes #4350) +- **Get API Key Link Now Shows in Claude Desktop, OpenClaw, and Hermes Forms**: The "Get API Key" link and partner-promotion block below the API key input was only wired for claude/codex/gemini/opencode. Claude Desktop rendered a bare Input that never showed it, and OpenClaw/Hermes were blocked by two gaps: `useApiKeyLink` whitelisted only those four appIds (so the link was suppressed even when a preset carried `apiKeyUrl`), and `useProviderCategory` only parsed the `/^(claude|codex|gemini|opencode)-(\d+)$/` preset-id pattern (so OpenClaw/Hermes category stayed undefined and the cn_official/aggregator/third_party link condition never held). `ClaudeDesktopProviderForm` now calls `useApiKeyLink` and uses the shared `ApiKeySection`; the `useApiKeyLink` whitelist and its `PresetEntry` union add claude-desktop/openclaw/hermes; and `useProviderCategory` now resolves openclaw/hermes preset categories. Additionally, `HermesFormFields` and `OpenClawFormFields` no longer let an "official" category disable the key input, since these apps have no OAuth-only official providers (e.g. Hermes' Nous Research is official but still needs a user-supplied key). +- **Deduplicated Windows Codex npm Shims in Tool Detection**: On Windows, npm installs a tool as three sibling files — `codex.cmd`, `codex.exe`, and an extensionless Unix shim named `codex` — and CC Switch's `tool_executable_candidates` listed all three, so the extensionless shim (which Windows cannot execute directly) was probed as a redundant/failing candidate. `tool_executable_candidates` now appends the extensionless path only when `windows_runnable_sibling_for_extensionless_tool` finds no adjacent `.cmd`/`.exe` sibling, and `resolve_path_default` likewise prefers a runnable `.cmd`/`.exe` sibling before canonicalizing a bare extensionless PATH hit. This keeps version detection and launching anchored to the actually-runnable Windows shim instead of the shadowed Unix one. (#4782) +- **Scroll Bounds for Long Select Dropdowns**: The `SelectContent` popover used `overflow-hidden` with no height cap, so dropdowns with many options (e.g. long model or provider lists) rendered taller than the viewport and clipped their overflowing items with no way to reach them. It now sets `max-h-[min(24rem,var(--radix-select-content-available-height))]` and `overflow-y-auto overflow-x-hidden`, bounding the content to 24rem or the Radix-computed available height and letting the list scroll vertically while still clipping horizontally. (#4798) +- **Date-Range Picker Calendar Stays On-Screen in Narrow Popovers**: The custom date-range picker switched to its two-column layout (date fields | calendar) based on the viewport width via Tailwind's `sm:` (640px) breakpoint, but the popover is clamped to `100vw - 2rem` and anchored to its trigger with `align="end"`, so its real available width is narrower than the viewport. On narrow windows the two-column layout could activate while the popover only had room for one column, pushing the calendar column off the right edge where it was clipped — the month header and 4 of 7 weekday columns cut off and unreachable. The layout now keys off the popover's own inline size via a CSS container query (`w-[620px] max-w-[calc(100vw-2rem)]`) instead of the viewport, so it collapses to one column exactly when the popover itself is narrow, keeping the calendar fully visible at any window width. (#4860) + +### Docs + +- **Documented the `CC_SWITCH_GDK_BACKEND` Escape Hatch in README and User Manual**: Added an FAQ entry for the opt-in `CC_SWITCH_GDK_BACKEND` environment variable (see the corresponding Fixed entry) across all four README locales (`README.md`, `README_ZH.md`, `README_JA.md`, `README_DE.md`) and the zh/en/ja user-manual troubleshooting pages (`docs/user-manual/{zh,en,ja}/5-faq/5.2-questions.md`), explaining how Wayland + NVIDIA users can switch back to native Wayland when the webview goes click-dead and black-screens on resize, and how tiling-Wayland users can set it to `x11` for the inverse input bug. +- **Overseas Kimi READMEs Point to platform.kimi.ai With a Coding Plan Link**: Updated the Kimi K2.7 Code partner section across the English, German, and Japanese READMEs so the banner image and both inline CTAs point to `https://platform.kimi.ai?aff=cc-switch` instead of the old `platform.kimi.com` host, keeping the `aff=cc-switch` referral tag intact. All four localized READMEs (`README.md`, `README_DE.md`, `README_JA.md`, `README_ZH.md`) also gained a new line promoting the Kimi For Coding subscription plan linked to `https://www.kimi.com/code/?aff=cc-switch`; note the ZH README kept its existing `platform.kimi.com` link and only received the Coding Plan addition. +- **GitHub Global Top-100 Milestone Banner in v3.16.4 Release Notes**: Prepended a celebratory callout blockquote to all three localized v3.16.4 release notes (`docs/release-notes/v3.16.4-en.md`, `-ja.md`, `-zh.md`) announcing that CC Switch has entered the global top 100 GitHub projects by star count, thanking users, contributors, and stargazers. This is a docs-only addition to the release-notes header and does not change any product behavior. ## [3.16.4] - 2026-06-27 diff --git a/package.json b/package.json index bfd6c33f0..9c07d1650 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cc-switch", - "version": "3.16.4", + "version": "3.16.5", "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 502e5d769..a1e858710 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -758,7 +758,7 @@ dependencies = [ [[package]] name = "cc-switch" -version = "3.16.4" +version = "3.16.5" dependencies = [ "anyhow", "arboard", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index d1c05ce1a..e0a13d056 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cc-switch" -version = "3.16.4" +version = "3.16.5" 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 8ba4c9a7a..313d0c9c9 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": "3.16.4", + "version": "3.16.5", "identifier": "com.ccswitch.desktop", "build": { "frontendDist": "../dist",