docs/release-notes/v3.19.2-en.md
The through-line of this release is getting the numbers right and pinning down the boundaries: Codex usage accounting fixes a defect that could count an interleaved-counter file several times over — new data is correct immediately after upgrading, and inflated history can be corrected with a one-time manual rebuild (see "Upgrade Notes"); a six-part security hardening pass caps every unbounded read across usage scripts, session logs, catalog files, and buffered proxy response bodies. The everyday conveniences are filled in too: the MCP / prompt / Skills panels can be searched, and MCP and Skills gain one-click per-app bulk toggles; the Auth Center shows each ChatGPT account's subscription usage; OMO users get a working integration back. With two write paths batched, backup imports, automatic sync, and usage re-imports no longer stall at every turn on large databases. This release has no database migration.
ANTHROPIC_AUTH_TOKEN placeholder instead and enters with no dialog at all.~/.omo/omo.jsonc and the legacy file is no longer read, so provider switches used to look successful while landing nowhere. CC Switch now detects the unified file (omo.jsonc or omo.json) and writes into its "[opencode]" section. The OMO form's model pickers also merge in the runtime models opencode models actually reports.~/.hermes/SOUL.md, the file Hermes actually loads, instead of the AGENTS.md it never reads there.The changes in this release center on usage statistics and the extension-management panels. The following docs are worth reading alongside it:
[!WARNING]
Only Official Channels (Please Read)
CC Switch is a fully free and open-source desktop app, and we do not charge users any fees. Please only obtain the software through the official channels listed below:
Channel Only Official Website ccswitch.io Source github.com/farion1231/cc-switch Downloads GitHub Releases Author @farion1231 Report an Imposter GitHub Issues Any "CC Switch" website or client that asks you for payment, top-ups, or login credentials is fake. If you have been tricked into paying, stop the transaction immediately and file a report through GitHub Issues.
CC Switch v3.19.2 is a correctness-focused maintenance release along three lines. The first is getting the numbers right: the Codex session importer could over-count usage several times over on files with interleaved counters (#3011); this release switches to an algorithm that prefers each turn's explicit delta and recognizes replays by their full signature, closed out by replaying nearly 1,900 real session files; the backup and usage-import write paths are batched at the same time, markedly easing import stalls on large databases (#2100 will likely benefit).
The second is pinning down the boundaries: an externally contributed security hardening pass caps every unbounded read across the usage-script runtime, Grok session logs, Codex catalog files, and buffered proxy response bodies, and the deep-link import confirmation gains two credential fields it used to collect without displaying. The third is filling in the everyday conveniences: search across the MCP / prompt / Skills panels, bulk per-app toggles for MCP and Skills, per-account subscription usage in the Auth Center, and two OMO adaptations — the unified config and runtime models. On top of that come seven specific fixes covering Copilot sign-in, Hermes prompts, Skill installs, and more. This release has no database schema migration (the version stays at v16), so upgrading is light.
Release date: 2026-08-06
Change size: 24 commits | 109 files changed | +12,340 / -1,897 lines
The MCP, prompt, and Skills panels share a new search box — Esc clears it, and it only intercepts the global back shortcut while it has content, so your usual habits are unaffected. The per-app count badges atop the MCP and Skills lists become three-state toggle buttons: one click enables or disables an app across the whole list — the days of flipping switches row by row are over (#5954, #5935).
Bulk operations deliberately run serially rather than concurrently — each app's live config is a single file, and concurrent writes would overwrite each other; failed entries are collected and reported in one go. A bulk toggle acts on the whole list, not the search-filtered subset, avoiding the ambiguity of "thought I only toggled the filtered results, actual state unclear".
Two long-standing data-layer problems get fixed along the way: MCP toggles move from read-whole-row / modify in memory / write-whole-row to a single-column atomic UPDATE, so two apps toggled at nearly the same time no longer lose each other's updates; Skill updates re-confirm before writing that the record still exists with its install generation unchanged, so a slow update task can no longer resurrect a Skill that was just uninstalled. The search index is an explicit whitelist — environment variables and request headers never enter the searchable text.
Settings → Auth Center now shows each ChatGPT (Codex OAuth) account's subscription usage inline, reusing the query the provider card footer already runs — deduplicated by account, cached for five minutes, fetched once on mount with no polling. Multi-account users no longer have to switch around to check their quota. (#4887)
The OMO form's model pickers used to offer only a static list; they now also run opencode models and merge in the models the locally installed OpenCode actually reports. The helper process is deliberately sandboxed: project-level config discovery is disabled and the working directory is pinned to the OpenCode config directory — opening a form can never execute some project's .opencode/ plugins; the whole run has a 20-second deadline, after which the entire process tree is killed (process groups on macOS / Linux, taskkill /T on Windows, and an in-distro timeout for WSL installs). Any failure falls back to the static list with a toast. (#5522)
qwen3.8-max is seeded at the official list price: $2 input / $6 output per million tokens, $0.25 cache read, $2.50 cache write (125% of input, the official explicit context-cache rate). Seeding is insert-if-absent, so a price you edited yourself is untouched. (#6053)
The NekoCode and Unity2.ai partner presets are removed from every app, the READMEs, and all locale files; the Qiniu preset's position in the ordering is adjusted.
The session importer used to derive deltas from a single high-water mark over cumulative totals — correct when a file carries one monotonic counter, but real-world logs contain two interleaved shapes: a gateway replaying the same unchanged snapshot under changing rate-limit buckets, and two genuinely distinct cumulative counters alternating. The old algorithm treated both replays and alternation as new increments; files from the field measured six to eight times their true usage.
The importer now prefers the explicit last-turn usage each event carries, and recognizes replays by their full token signature. Deduplication is deliberately narrow: a snapshot is compared only against the same source's own previous signature or the immediately preceding token event — never against other sources' older signatures, because a legitimate counter reset reproduces old values and a full-table scan would swallow it. The totals-only legacy format falls back to a single global baseline, with the same semantics as before.
The fix is validated by replaying nearly 1,900 real session files totalling 1.7 GB: within 0.001% of an independently recomputed ideal, with every residual difference being a legitimate recovery of a counter reset the old algorithm clamped away. Historical data is deliberately not rewritten — see "Upgrade Notes" for how to correct it. (#3011, #3015)
Third-party Chat gateways occasionally return tool calls with missing function names; the Chat → Responses transform used to drop them silently and still report the turn completed — Codex saw a "successful turn with nothing left to do" and quietly ended its agent loop, turning a diagnosable upstream failure into a silent stall.
Now, when every tool call in a turn has been dropped and none remains usable, the streaming path emits response.failed and the non-streaming path reports a transform error; the check is gated on status == "completed", so finish_reason: length truncation keeps its own incomplete semantics. All three drop sites log structured, content-free fields — call-id presence, argument byte counts, finish reason — so problems like #4341 can finally be diagnosed from real traffic. Turns with a valid tool call, text-only turns, and truncated turns behave as before.
OMO 4.19.3 unified its configuration into ~/.omo/omo.jsonc (then omo.json), and its migration renames the legacy per-app file out of the way. From then on CC Switch — which only knew the legacy path — kept writing a file outside OMO's config chain, so provider switches looked successful while landing nowhere (#5945).
When the unified file is detected, the OpenCode configuration is now written into OMO's "[opencode]" section — and only there, because OMO validates its root schema strictly and discards the whole file over any unknown root key. Writes treat the document as JSON5: comments, key order, and line endings survive, and nothing is written when nothing changed; before every write, the result is re-parsed and compared semantically against the intent — if serialization would corrupt the document, the write is refused and the original file left untouched rather than saving a broken one (see "Upgrade Notes" for the known trigger). The same change also moves atomic file writes on Windows to ReplaceFileW for every managed app, closing the brief window in the old delete-then-rename sequence where the target file did not exist.
Current Claude Code releases show a confirmation dialog for an unrecognized API key, with "No (recommended)" preselected — and the ANTHROPIC_API_KEY placeholder Copilot takeover used to write ran straight into it: follow the recommendation and the key is ignored, leaving a signed-out session. Takeover now writes the ANTHROPIC_AUTH_TOKEN placeholder, entering with no dialog; a provider that explicitly selected the ANTHROPIC_API_KEY field in the form's advanced section keeps the old behavior. The Copilot forwarding path also gains the [1M] context-marker strip the other paths already had, so a claude-*[1M] model ID no longer reaches GitHub's API verbatim. (#5832)
The identity file Hermes loads from ~/.hermes/ is SOUL.md; it never looks for AGENTS.md there — that name is project-level context, discovered upward from the working directory. CC Switch's prompt management had written ~/.hermes/AGENTS.md since the day Hermes support was added, so enabling a Hermes prompt produced a dead file. It now reads and writes ~/.hermes/SOUL.md, and the existing back-fill still applies: a SOUL.md you wrote yourself is imported into the database before being replaced. (#5777)
Installing ast-grep's official Skill failed with "SKILL.md missing": that repository keeps a wrapper directory named after the Skill at its root, with the real Skill nested deeper, and the resolver returned the first directory whose name matched. Source resolution is now anchored on SKILL.md itself — a directory without one is never selected — which also fixes the phantom "update available" that update checks kept reporting against such repositories. (#4141)
The skills.sh discovery flow reports only a Skill's basename; installation resolved the real nested directory, but the stored README link was still built from the basename guess — a 404 on click. The link is now generated from the directory the installer actually resolved. The fix applies to the install path only — records written by earlier versions need a one-time reinstall, see "Upgrade Notes". (#6111)
With every app tab, the profile switcher, and the takeover toggles visible at once, the header overflowed and the add-provider button was clipped. Primary actions now live in a non-shrinking cluster, and the app switcher is width-aware: apps that no longer fit collapse into a "more" popover, with the active app always visible.
The route status indicator's pulse animation kept running while the window was unfocused, occupying the GPU for a purely decorative effect. Window focus now gates the heartbeat through a data attribute and CSS — an unfocused window freezes the animation at full opacity, and the system's reduced-motion preference disables it entirely. Data polling is unaffected; only the decoration pauses. (#5767)
A six-part externally contributed hardening pass (#5919):
while(true) could hang the backend thread forever. The runtime now enforces a 5-second interrupt, a 16 MiB memory cap, and a 256 KiB stack cap.~/.grok/sessions could previously overflow the stack.model_catalog_json used to trust any absolute path on the file name alone; it must now resolve inside the Codex config directory — re-checked after canonicalize, so a symlink cannot escape — with a 32 MiB per-read cap.usageAccessToken and usageUserId without ever showing them; both now display before you approve, the token masked as usual.Each direction had its own independent cost. On the export side, every row used to be its own INSERT, so importing a large backup had SQLite parsing, preparing, and destroying tens of thousands of statements one by one; exports now generate multi-row INSERTs in batches of 200 rows / 1 MB, cutting the statement count by two orders of magnitude and shrinking the backup file itself by roughly 4x. On the restore side, every WebDAV / S3 sync import ends by writing back the locally retained tables, and each row used to be its own implicit transaction — one full journal write and one fsync per row, exactly what made automatic sync stall the app periodically on large databases; the whole restore now runs in a single transaction.
Old single-row backups still import as before, and the new format is within what every SQLite shipped with the app supports — compatible in both directions across versions. The cross-machine import freeze reported in #2100 will likely ease — real-world results on that issue are welcome. (#6122)
A full re-import — triggered by importing a pre-v16 SQL backup, by cursor mismatches after a cross-machine restore, or by a manual rebuild — could pin a CPU core for minutes on a large corpus: every token event formed its own auto-commit transaction, paying a full journal create / fsync / delete cycle per row, and every archived file ran a cursor-inheritance query that could not use an index.
Events now commit in batches of 1,000, with the connection lock released between batches so UI queries can slip in; the cursor advances in the same transaction as the final batch, so a crash can never leave it ahead of the data; cursors and model pricing are preloaded once per pass, and hot statements use the prepared-statement cache. A real corpus of 1,920 files / 1.7 GB drops from 36.3 to 11.1 seconds on macOS (release build); on Windows, where each per-row fsync costs milliseconds, the absolute win is an order of magnitude larger. Replaying the same corpus before and after verifies equivalence: 82,000 imported rows are byte-identical across all exported columns, with identical import / skip counts.
v3.19.2 contains no schema migration (the version stays at v16), triggers no pre-upgrade backup, and is ready to use immediately.
The interleaved-counter fix only guarantees correctness going forward: historical rows are deliberately not rewritten, and there is no automatic rebuild. If your dashboard's Codex numbers look impossibly high and your session files carry the interleaved shape, go to Usage page → Codex usage maintenance → "Rebuild Codex usage" once after upgrading — the database is backed up automatically before the rebuild; history whose session logs were already deleted cannot be re-imported. This release's import speedup makes the rebuild roughly 3x faster than before.
Most installations are unaffected: on data without the interleaved shape, the old and new algorithms differ by less than one part in a thousand.
An existing Skill installed through skills.sh whose README link 404s recovers the correct link after an uninstall and reinstall; an in-place "update" will not rewrite it.
The backup dump format changed, and the sync protocol treats it as an opaque artifact hashed as a whole, so the first WebDAV / S3 sync after upgrading re-transfers db.sql in full — one-time and harmless.
The AUTH_TOKEN placeholder takes effect the next time takeover rewrites the live config — switch providers or restart takeover. Providers that explicitly selected the ANTHROPIC_API_KEY field in the form's advanced section are unaffected; your choice is preserved as is.
The decision is based on whether the file exists, not on the OMO version: when ~/.omo/omo.jsonc (or omo.json) exists, it is edited in place; when neither exists, the legacy OpenCode-layer file is written as before. Known limitation: if the unified file contains block comments (/* … */), writes fail with an error to protect the document — line comments (//) are unaffected. Until the upstream JSON5 writer is fixed, remove block comments before switching providers.
The management panels' bulk per-app toggles act on every entry, not the search-filtered subset.
Proxy responses that must be buffered in full — non-streaming responses and error bodies — fail with a 502 above 128 MiB instead of being forwarded; streamed passthrough responses are unaffected. A normal LLM response is a few MB at most, so the cap only triggers on upstream anomalies; such a failure terminates the request and does not trigger failover to the next address.
xAI Grok OAuth sign-in: reuses the public OAuth client identity of the official Grok CLI; using it could lead to account restriction or suspension — see the v3.18.0 release notes for details.
Codex OAuth reverse proxy: using a ChatGPT subscription's Codex OAuth through a reverse proxy may violate OpenAI's terms of service. See the v3.13.0 release notes for details.
SuperGrok quota queries: the quota display on provider cards depends on a non-public billing endpoint at grok.com and may stop working once xAI changes the interface — see the v3.19.0 release notes for details.
Third-party provider routing: when the CC Switch local proxy converts and forwards Codex, Claude Desktop, or Grok Build requests to a third-party provider, each provider has different constraints on billing, compliance, and data retention. Please read the target provider's terms of service before use.
By enabling these features, users accept the associated risks. CC Switch is not responsible for any account restriction, warning, or service suspension resulting from their use.
Thirteen of this release's 24 commits are PRs from outside contributors — nine of them, covering nearly every main line from the headline usage fix to the security hardening.
total_token_usage is non-monotonic and that replays were being counted as new increments — the problem definition behind this release's headline fix comes straight from that report; @KeShih also proposed the repair direction early in #3015.Visit Releases and download the build for your system, or get it from the official site ccswitch.io (downloads are distributed through Cloudflare edge nodes and do not depend on GitHub being reachable).
| System | Minimum Version | Architecture |
|---|---|---|
| Windows | Windows 10 and later | x64 / ARM64 |
| macOS | macOS 12 (Monterey)+ | Intel (x64) / Apple Silicon (arm64) |
| Linux | See table below | x64 / ARM64 |
| File | Description |
|---|---|
CC-Switch-v3.19.2-Windows.msi | Recommended - MSI installer with auto-update |
CC-Switch-v3.19.2-Windows-Portable.zip | Portable build, unzip and run |
Windows ARM64 devices should pick the artifact whose file name carries the arm64 tag.
| File | Description |
|---|---|
CC-Switch-v3.19.2-macOS.dmg | Recommended - DMG installer, drag to Applications |
CC-Switch-v3.19.2-macOS.zip | Unzip and drag to Applications, Universal Binary |
CC-Switch-v3.19.2-macOS.tar.gz | For Homebrew install and auto-update |
Homebrew install:
brew install --cask cc-switch
Upgrade:
brew upgrade --cask cc-switch
Linux assets are available for both x86_64 and ARM64 (aarch64). Choose the file whose architecture tag matches your machine's uname -m output:
CC-Switch-v3.19.2-Linux-x86_64.AppImage / .deb / .rpmCC-Switch-v3.19.2-Linux-arm64.AppImage / .deb / .rpm| Distribution | Recommended Format | Install Command |
|---|---|---|
| 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 | Make executable and run directly, or use AUR |
| Other distributions / unsure | .AppImage | chmod +x CC-Switch-*.AppImage && ./CC-Switch-*.AppImage |