Commit Graph
224 Commits
Author SHA1 Message Date
Jason 7cc3141cae style(providers): mark additive default providers in blue
The default provider in OpenCode, OpenClaw, Hermes and Kimi used a gray
card and dot. Use the same blue as an in-use switch-mode card instead,
and drop the now-unused neutral card tone.
2026-10-23 11:15:35 +08:00
Jason d6a2324196 feat(kimi): give provider cards real add/remove actions
Kimi is additive, but both card groups only offered "Switch", which
wrote the provider into config.toml and changed default_model at once,
so the Added / Available split did nothing.

- Available cards get "Add": a new add_provider_to_live_config command
  writes the provider and its models into config.toml without changing
  default_model, so they show up in Kimi's /model list. A node already in
  config.toml belongs to Kimi and is never overwritten from the archive.
- Added cards get a "Remove" button; "Set as default" (select the
  provider's model) moves into the more menu, as for OpenCode/OpenClaw.
- The provider owning default_model is marked with the gray "Default"
  status like OpenCode, and cannot be removed.
2026-10-23 11:15:35 +08:00
Jason 44e0fc9630 feat(kimi): name separate official accounts "Kimi 订阅 <nickname>"
Kimi Code shows a provider's key as its name in the model picker, so
separate accounts appeared as "kimi-code-ccs-<hash>". New separate
accounts are now keyed "Kimi 订阅 <nickname>" ("Kimi Subscription" when
CC Switch is not in Chinese), matching Kimi's own label for its default
login and limited to the characters Kimi accepts, numbered on clashes.

The credential slot and model aliases keep the stable
"kimi-code-ccs-<hash>" name, so default_model stays an ASCII key and
ownership checks are unchanged. A returning account is also recognised
by its credential slot, not only by the local identity cache. Card names
fall back to the readable key when no nickname is cached.
2026-10-23 11:15:35 +08:00
Jason cdd2190df2 feat(kimi): identify, remove and show quota for official accounts
Follow-up to #8726, which lets the Authorization Center hold several Kimi
official subscriptions, each with its own provider and credential slot.

Identity: after sign-in (and for logins found on disk) read /me to show
the account's nickname on its row and card. Signing in to an account that
is already listed writes back to its slot instead of adding a duplicate,
and the slot is chosen when the login completes, so a native Kimi login
made meanwhile is never overwritten. New separate slots are named from a
hash of region and user id, stable across devices. Opening the Kimi page
reads identities too, so card names carry the nickname without a visit to
the Authorization Center first.

Remove instead of sign out: a separate account is deleted together with
its provider node, models, credential and card (refused while in use);
web search/fetch pointing at it moves to Kimi's own default login. Kimi's
own login is only hidden from the list - CC Switch never logs Kimi out -
and stays hidden across Kimi's token rotations until the user signs in to
it again here. An empty list caused by that says so instead of "signed
out".

Quota: each account row and official card shows its quota. Tokens close
to expiry are refreshed under the same proper-lockfile-compatible lock
Kimi uses (mkdir <slot>.lock, 5 s stale takeover), with Kimi's revoked
token recovery. Windows, where Kimi takes no lock, only reads.

Also: re-login keeps custom fields such as custom_headers on the node;
deleting a card whose node was removed elsewhere deletes the leftover
CC Switch-owned credential; the card's switch button works for official
accounts after checking they are signed in on this machine; account rows
use the same compact layout as the other Authorization Center groups.
2026-10-23 11:15:35 +08:00
funkpopo 07265bc970 feat(kimi): support multiple official accounts in Auth Center (#8726)
* feat(kimi): manage multiple official accounts in auth center

Isolate account credentials, providers and model aliases; preserve native logins and protect official OAuth nodes. Fix session image access, drop unpublished usage repair paths and the kimi-cli alias, and synchronize all four READMEs.

* fix(kimi): address account compatibility review feedback

Restore the native default credential slot for the first account, stop rewriting tool services on account switches, allow deleting profiles removed from native config, and fix official-account test fixtures and documentation.

* fix(kimi): pin OAuth endpoints to the login region

Use fixed official hosts for mainland and global sign-ins, keep existing account regions and credential slots during reauthentication, and preserve sanitized transport error causes. Add regional routing and network-error regression coverage.
2026-10-23 08:30:23 +08:00
funkpopo 7da255387f feat(kimi): add official OAuth login and provider switching (#8710) 2026-10-22 23:35:49 +08:00
funkpopo e4873bc8aa feat(kimi): add Kimi Code support (#8687)
Add Kimi Code as the 12th managed app (additive mode): native multi-provider config in ~/.kimi-code/config.toml (honors KIMI_CODE_HOME), presets derived from the Pi catalog, MCP (stdio/HTTP/SSE), Skills with native-directory protection, global prompts, session browsing/resume, and session-log usage import. Local routing and aggregation do not apply; official OAuth stays managed by Kimi Code. Schema v21 -> v22 adds enabled_kimi columns.
2026-10-22 16:50:37 +08:00
Jason cb90a2440d docs(release): add v4.0.18 release notes 2026-10-21 23:57:09 +08:00
Jason 92ec18d774 docs(aggregation): correct the workaround for the exhausted-quota lock
Since route and aggregation mode keep the ChatGPT login (#8431), the
route table writes requires_openai_auth = true whenever a login is on
disk, so making a third-party card the aggregation default no longer
keeps Codex from locking the send button to Luna Reserve once the
official 5-hour quota runs out.

The guide and the 4.6 manual pages now describe the method that still
works: switch to Direct, keep "Keep official login for direct switches"
off, switch to a third-party card and fully restart Codex; switch back
to Aggregation once the quota resets. The old method is marked as no
longer working.

Refs #7962
2026-10-21 17:04:27 +08:00
funkpopoandthefool cdfdff5ee7 fix(installer): make Windows desktop shortcut optional (#8601)
Add a "Create a desktop shortcut" checkbox to the MSI install-directory page and a public CREATEDESKTOPSHORTCUT property for silent installs. Upgrades keep the current state of the desktop shortcut, and clearing the option during an upgrade removes the old one.

The desktop shortcut is now copied from the Start Menu shortcut by custom actions with Return="ignore", so a Desktop that cannot be written no longer blocks or rolls back the install.

Fixes #5667

Co-authored-by: thefool <thefoolyuzhe@gmail.com>
2026-10-21 16:41:46 +08:00
Jason 3854c6134f refactor(agy): launch API-key providers from the terminal instead of a shell wrapper
agy only reads GEMINI_API_KEY and GOOGLE_GEMINI_BASE_URL from the process
environment, and modelProvider is global. The previous approach wrote the key
to a file, installed a wrapper script and edited .zshenv/.zprofile/.zshrc so
every agy picked it up.

Now the native settings.json always stays in login mode: login cards set the
model (display name) and drop modelProvider; key cards only drop
modelProvider. A key card applies to agy started from the card's "Open
Terminal": `agy --gemini_dir=<private dir>` under ~/.cc-switch/agy/<id>, whose
settings carry modelProvider and the model and whose config links back to
~/.gemini/config so MCP, Skills and prompts stay shared. The key and endpoint
reach that one process through the environment only.

The terminal launcher now takes a per-app launch description (command, env,
temp files) so Claude Code and agy share the terminal layer. On macOS/Linux
env values are read from a 0600 file that is deleted right away and passed
via `env`, so values exported by the user's rc files cannot override them;
on Windows they live in a setlocal block. Claude's temporary settings file is
now written 0600 as well, and temp files are removed before handing over to
the interactive shell (exec skipped the EXIT trap).

On startup, wrappers, env files and PATH blocks left by earlier test builds
are removed (only CC Switch-marked content) and the current provider is
reapplied so modelProvider returns to login mode.
2026-10-20 23:56:05 +08:00
OwlbayandpeterLwk888 c7dceb8036 feat(agy): integrate Antigravity CLI management (#8268)
Add Antigravity CLI (agy) as a managed app: provider switching for the native login and API-key modes, MCP and Skills sync through ~/.gemini/config, session browsing and session-log usage import.

Co-authored-by: peterLwk888 <lwk1124@outlook.com>
2026-10-20 23:35:51 +08:00
Jason 19798e2f92 docs(release): add v4.0.17 release notes 2026-10-20 22:08:53 +08:00
Jason f92ff0b039 docs(release): add v4.0.16 release notes 2026-10-19 18:26:47 +08:00
funkpopo a94f997f1e fix(codex): honor configured GPT context windows (#8385)
Explicit provider-scoped or per-model context windows now apply to mirrored official GPT catalog entries (context_window and max_context_window), with the auto-compact limit kept in sync; official defaults remain when nothing is configured. Gemini input-overflow errors on the Codex Chat path are normalized to context_length_exceeded and returned as a response.failed stream so Codex can compact, and non-string SSE error codes are stringified so upstream messages survive.

Fixes #8366
2026-10-19 16:24:54 +08:00
Lu Chong 75e93281a8 fix(proxy): allow unforced Claude WebSearch through Codex OAuth (#7936) 2026-10-19 10:54:06 +08:00
Jason 79e754ab1b docs(release): add v4.0.15 release notes 2026-10-17 23:20:46 +08:00
SmileMachine 5cc94b8dac fix(proxy): report routed switches without unconditional restart prompts (#8378)
Route switches now return what was actually applied (remembered / route / stack) and whether the client configuration was rewritten, and the success toast is built from that instead of always asking Codex / Gemini CLI / Grok Build users to restart. A restart hint is shown only when client files changed. Direct-mode switches serialize unchanged. Fixes #8347.
2026-10-17 21:40:27 +08:00
Jason 5de6feb4e5 docs(release): add v4.0.14 release notes 2026-10-16 20:16:22 +08:00
Jason 0a8d064591 docs(release): update v4.0.13 release notes 2026-10-16 00:07:45 +08:00
Jason 4ec75e7135 docs(release): add v4.0.13 release notes 2026-10-15 22:12:24 +08:00
Jason e70e844cc0 feat(codex): let Auto Review use another model
Codex's automatic approval (Approve for me) sends every sandbox
escalation to a reviewer model on the same provider as the
conversation. Third-party cards had no way to pick it: without a model
list Codex asks the provider for its hidden codex-auto-review model
(404 on most relays), and with a list the main model reviews itself
(#8015, #5903, #3855). Codex reads the choice from the
auto_review_model_override field on the main model's catalog row, so
CC Switch now writes it there.

- Direct and Routing: a new "Auto Review model" field on the Codex card
  (modelCatalog.autoReviewModel), limited to the card's own model
  list. It is written on every row of the card's catalog; a value that
  left the list is not written. Hidden for official cards; disabled
  with an explanation when the card has no model list.
- Aggregation: a device setting (codexStackAutoReviewModel) in the
  Aggregation settings sheet, picking any published ccs- model so
  approvals can go to another provider. It is checked against the
  merged catalog on every rewrite, like the sub-agent model, and the
  card value is ignored in this mode. The default label follows the
  default provider: official Auto Review, or the main model.
- Changing the catalog needs a Codex restart; the existing stale
  catalog notice covers it.
- Inside a form, Radix Select's hidden native select reported an empty
  value when the saved pick and the list arrived in the same render,
  which cleared the field when editing a card; empty values are now
  ignored.
- Docs and the four locales updated.
2026-10-15 21:34:24 +08:00
Jason 6aeaeb17ab feat(codex): pick the aggregation sub-agent model and default classic tools on
Aggregation mode used to strip [agents] default_subagent_model, so Codex
sub-agents always followed the main model (#8286). Users can now choose a
sub-agent model and reasoning effort for aggregation, both in the
"Switch to Aggregation" dialog and in a new Aggregation settings sheet on
the Stack tab.

- The choice is a device setting (settings.json). On every rewrite it is
  checked against the merged model catalog: an id that is no longer
  published (member removed, or it is now the default provider) is not
  written, so sub-agents fall back to the main model instead of every
  spawn failing, and it comes back when the member is re-added. An effort
  the model does not support is dropped.
- Codex reads [agents] when a thread starts: new conversations pick up a
  change without a restart; open ones keep the old value.
- The classic sub-agent tools toggle moves from Settings into the sheet
  and is now on by default: with the newer tools the main agent's
  provider encrypts the task and a sub-agent on another provider gets
  nothing (#8253). It is stored under a new key, codexStackClassicTools;
  the old codexStackClassicSubagents key was written as false on every
  save since v4.0.10, so it is no longer read.
- Docs and the four locales updated.
2026-10-15 21:34:24 +08:00
Jason 51ac86f1c5 docs(release): add v4.0.12 release notes 2026-10-14 18:36:57 +08:00
Jason 7a8087f688 feat(usage): scan session logs at the selected interval while the usage page is open
The usage page's auto-refresh interval only re-read the database, so
session usage still waited for the fixed 60-second background scan, and
routed usage already updated in real time through usage-log-recorded.
The interval now controls how often session logs are scanned:

- The background scan drops to every 10 minutes as a safety net against
  CLIs pruning old session files.
- While the usage page is visible it scans right away, again whenever
  the window becomes visible, and then at the selected interval
  (5/10/30/60s, default 60s). The first scan waits until settings load,
  so it never runs when automatic scanning is off.
- The "Off" option is removed (a saved 0 falls back to 60s), and the
  interval menu is hidden when automatic scanning is off.
- Statistics no longer poll. Imports refresh them through the
  usage-log-recorded event, which is always on again, and time-relative
  ranges re-run once a minute so "Today" rolls over at midnight and
  rolling windows drop old records without new usage.

Copy is updated in zh, zh-TW, en, ja and tr, and in the zh/en/ja manual.
2026-10-14 17:42:42 +08:00
funkpopo cc81627a8e fix(usage): sync session usage at the selected auto-refresh interval (#8301) 2026-10-14 17:00:14 +08:00
Jason 2635dfffce docs(release): add v4.0.11 release notes 2026-10-13 23:14:19 +08:00
Jason 90fb37ffb7 docs(release): add v4.0.10 release notes 2026-10-13 00:19:45 +08:00
Jason 4c263a85ec docs(manual): describe My Icons in the add-provider icon section
Section 2.1 still said the icon area lets you pick a preset icon and
customize its color. There has been no color control for a while (the
color comes from the built-in icon's metadata), and icons can now be
uploaded to My Icons. Point 2.1 at the full description in 2.3, and
drop "and color" from the icon row of the 2.3 field table.
2026-10-13 00:19:37 +08:00
Jason 68411d82fb feat(providers): keep uploaded icons in a named "My Icons" library
Uploading an icon used to attach the image to the one provider being
edited, shown as a lone "Custom icon" strip above the built-in grid. It
had no name, could not be searched and had to be uploaded again for
every provider that wanted it.

The icon picker now has two groups, filtered by the same search box:

- My Icons: the first tile uploads an image. After it is resized, a
  dialog asks for a name (the file name by default); "Save and Use"
  stores it in the library and selects it. Library icons show their
  names, can be picked by any provider in any app, and can be renamed or
  deleted from the buttons that appear on hover. Uploading an image that
  is already in the library reuses the existing entry. A current custom
  icon that is not in the library (for example one from an import link)
  shows as "Current icon" and can be saved, named after the provider.
- Built-in Icons, as before.

Clicking an icon now selects it and closes the picker, so the "Done"
button is gone; "Clear icon" next to the search box removes the icon.

The library lives in the settings table under `custom_icons`, which is
already cloud-synced. Providers still store the image itself, not a
library id, so renaming or deleting a library entry never changes a
provider that uses it, and a provider shows its icon on a device whose
library differs. Adding to the library decodes the PNG fully like
saving a provider does, caps the library at 100 icons and names at 64
characters. SQL import and cloud sync drop library entries whose image
is invalid, alongside the existing provider and universal provider
cleanup; unknown fields on the remaining entries are kept.

The naming dialog stops its submit event from propagating: React events
bubble through portals, so without it saving a name would also submit
the provider form the picker is rendered in.

The user manual's icon section (2.3, zh/en/ja) describes the new flow.
2026-10-13 00:07:38 +08:00
Jason 0962337b5d docs(deeplink): add English and Japanese site owner guides
Translate the site owner integration guide into English and Japanese,
quoting UI labels from the app's own locale files and using each
language's Sub2API template fallback message. The three versions link to
each other. Manual 5.3 (en/ja) and the English, German and Japanese
READMEs now point to the guide in their own language.
2026-10-12 23:26:43 +08:00
Jason 3d5f847185 docs(deeplink): note that New API and Sub2API ship an import button
Site owners running New API or Sub2API already have an "Import to CC
Switch" button in the key list. Say so up front, and point out that New
API's link carries no usage script, so users see no balance after import.
2026-10-12 23:26:43 +08:00
Jason 502d681b73 docs: point the deep link generator to ccswitch.io and link the site owner guide
The manual linked the generator at farion1231.github.io, but GitHub Pages
was never enabled for the repository, so the link returned 404. The page
is now hosted on the website at ccswitch.io/deplink.html; the manual
(zh/en/ja), the four READMEs and the site owner guide point there.

The generator inlines its favicon and logo so the same file works both in
the repository and on the website. Manual 5.3 gains a pointer to the site
owner guide, and its usage steps list the Skill repository type.
2026-10-12 23:26:43 +08:00
Jason ea1ab8091f docs(deeplink): show site owners how to wire the import button
The guide explained how to build a link but not how to put it on a page.
Add a section on fetching the link from the backend when the button is
clicked (so the key never sits in the page source), the button markup,
and what to show when CC Switch is not installed. Add a fast path at the
top and fold the sections most sites can skip.

The link generator folds the Base64 tool and the MCP, prompt and Skill
examples, opens them when reached from the sidebar or an anchor, and
gains an FAQ entry pointing to the new section.
2026-10-12 23:26:43 +08:00
Jason fb719d99d3 docs(usage): document the Sub2API template and add it to the link generator
The user manual (zh/en/ja) gains a Sub2API template section, and the link
generator and the site owner guide gain a Sub2API example. All of them use
the same script as the in-app template.
2026-10-12 23:26:43 +08:00
Jason 7577ca9572 docs(deeplink): rework the link generator and document iconUrl
deplink.html becomes a generator for site owners instead of a test page:
a sidebar layout with light and dark themes, tabs for provider, MCP,
prompt and Skill links, per-app `apiFormat` choices, usage script
templates, and examples that follow the v4.0.10 rules (Pi providers,
the activation toggle, `apiFormat`).

iconUrl:
- The generator gets an `iconUrl` field and checks it with the same
  shape rules as the app (https, a domain, default port, no
  credentials), so a link is never generated with an address CC Switch
  would drop. Built-in `icon` names are checked against the same
  whitelist as the parser.
- The parser marks `icon` and `iconUrl` values that would be dropped.
- New example and FAQ entry for a site's own icon.
- The integration guide adds `iconUrl` to the Node.js sample and a
  debugging step pointing at the log line. The zh and ja manuals list
  `iconUrl` and say what `icon` accepts.
2026-10-12 23:26:43 +08:00
Jason 6af00ecb0c docs(deeplink): add a Chinese integration guide for site owners 2026-10-12 23:26:43 +08:00
Jason 16e7ff1c9d feat(deeplink): let links declare the API format, import Pi providers, and leave activation to the user
- Add a single `apiFormat` parameter (anthropic / openai_chat /
  openai_responses / gemini_native) that 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.
- Support Pi provider links. They write a models.json node and must carry
  a model.
- The confirmation dialog now has a switch for "switch after import"
  (providers), "add to the app config" (additive apps, on by default) and
  "enable after import" (prompts). The link's `enabled` only sets its
  initial state.
- Turning the switch off really only saves the row: a new
  `ProviderService::add_without_switching` skips the first-provider path
  in `add` that would otherwise write the client config. The deep-link
  golden rows now have is_current false accordingly.
- Reject link values that additive apps would expand: Pi keys starting
  with `!` and `$NAME` / `${NAME}`, OpenCode `{env:}` / `{file:}`, and
  `${...}` for OpenClaw and Hermes. These would run a command or send
  local secrets and files to the link's endpoint. Checked when parsing,
  when merging `config`, and when building the provider.
- Update the deep-link manual in zh/en/ja.
2026-10-12 23:26:43 +08:00
Jason db93ac2083 fix(grokbuild): point session_summary at the active provider and keep a link's model profile
Session titles: when `models.session_summary` is unset, Grok Build
(verified on 1.0.50) generates titles with the built-in `grok-4.6`
model but sends the request to the default model table's endpoint, so
third-party upstreams reject it and title generation fails. Switching
never wrote this key, so fixing the row templates alone would not
reach live. The Grok switch patch now makes session_summary follow the
provider when it is unset or names a table CC Switch wrote (the
target, the write record, or a table retired in this switch): it points
at the target table, or is removed when switching to the official
account. A user's own choice (a built-in model or their own table) is
left alone.

Deep links: a Grok Build link carrying a config.toml no longer gets
rebuilt into a fixed template that dropped the profile's display name,
description, API backend and context window. The table named by
`[models] default` is kept through an allowlist of Grok 1.0.50 profile
fields; the endpoint, key and model come from the link parameters.
Links whose table uses auth_provider, env_http_headers or
mtls_cert_dir are rejected, and env_key is still dropped. Only one
model table is imported, since a provider owns one table in live.
Links without a config keep the old template byte for byte.

Fixes #7003
Refs #6457
2026-10-12 23:26:43 +08:00
Jason 11e1326bf5 fix(deeplink): keep a Codex link's provider config instead of rebuilding a fixed template
A Codex provider link could carry a full config.toml, but import only
pulled the key, endpoint and model out of it and rebuilt a fixed
template, silently dropping the provider's auth mode, headers, websocket
support and model catalog URL.

When a link carries a config, keep the parts that belong to the
provider, using the same field lists the live projection writes on
switch:

- from the selected [model_providers.*] table: connection and auth
  fields (wire_api, requires_openai_auth, http_headers, query_params,
  supports_websockets, retries/timeouts, capabilities, ...); the route
  is always renamed to `custom`
- model_catalog_url only on the same origin as the endpoint, since
  Codex sends the provider's credentials when fetching it
- top-level key and provider-exclusive fields (model, reasoning effort,
  web_search, context window, subagent model)

Global settings ([features], [tools], MCP, approval_policy, notify,
local file paths) are not imported. Links whose provider table makes
Codex run a command or read local credentials (auth, aws,
gateway_oauth, env_http_headers) are rejected; env_key is dropped in
favor of the link's own key, and an env_key-only link is rejected.
URL params still take priority, and a table's bearer token is reset to
the final key.

Links without a config keep the old template byte for byte; a new
golden snapshot locks the shape of config-carrying imports. The confirm
dialog notes that only provider settings are imported, and the manual
documents the rules (and that configUrl is rejected).

Refs #7438, #7942, #5510
2026-10-12 23:26:43 +08:00
Jason 450bc039f0 feat(deeplink): enable imported usage scripts by default
A provider link that carries a usage script now enables usage query
unless it says `usageEnabled=false`. Site owners attach the script so
users see their balance; making them switch it on again after import
was an extra step with little safety benefit: the script runs in the
QuickJS sandbox, sends a single request, and deep-link scripts have no
template type, so that request must be same-origin HTTPS with the base
URL.

Links without a script still import usage fields disabled. The
confirmation badge follows the same rule as the backend, and the
script body is still shown in full before the user imports.
2026-10-12 23:26:43 +08:00
Jason 04bd15c9f8 fix(i18n): use 詳細オプション for the advanced options toggle in Japanese
高級オプション reads as "luxury options" in Japanese. Rename the toggle and the docs that quote it (README_JA, the Japanese routing guides and the user manual FAQ).
2026-10-12 00:20:53 +08:00
Jason 8845b1ef79 docs(release): add v4.0.9 release notes 2026-10-11 23:29:48 +08:00
Allen Xu f88068b9e5 fix(proxy): let clients reach local routing through a separate connection address (#7878)
The proxy URL written into client configs (including Claude Desktop's gateway URL) was always derived from the listen address, with 0.0.0.0 written as 127.0.0.1, so clients outside the host's loopback, such as Claude Desktop sessions in WSL2 NAT mode, got an unreachable address.

Add an optional per-device "connection address" in Settings > Routing, stored in ~/.cc-switch/settings.json so cloud sync never carries it to another machine. When set it replaces the host in every proxy URL written to clients; saving rewrites routed clients without restarting the service and is safe to retry.

Fixes #7877
2026-10-11 17:58:46 +08:00
Jason df40d53c36 docs(release): add v4.0.8 release notes 2026-10-10 23:32:26 +08:00
Jason 3784fd9e4d fix(ui): soften dark-mode text colors to reduce glare
The three dark-mode text tiers all sat close to white (15.5 / 11.1 / 8.4
contrast on the app background), so screens full of table data and labels
looked harsh and the hierarchy flattened.

- --text-1 #f4f4f5 -> #e4e4e7, and the shadcn --foreground family follows
  so inherited body text matches
- --text-2 #d0d0d8 -> #ababb3, --text-3 #b5b5bd -> #9a9aa2
- --muted-foreground aligned with --text-2

Contrast is now about 13.4 / 7.5 / 6.1; the secondary and tertiary tiers
stay at or above 4.5:1 on card and selected backgrounds. Light mode is
unchanged.
2026-10-10 23:23:54 +08:00
Jason 1f786dadd0 docs(release): expand the Codex session compression section in v4.0.7 notes
Explain how the switch maps to config.toml, when Codex actually compresses
sessions, how resuming and CC Switch's session list and usage handle
compressed rollouts, and what to watch out for (Codex version, startup
notice, turning it off, other tools that read .jsonl). Move it to the top
of the new features.
2026-10-10 18:44:33 +08:00
Jason 790ed8009d docs(release): add v4.0.7 release notes 2026-10-10 16:53:17 +08:00
Jason 347c60c3f7 docs(aggregation): add Codex troubleshooting for sub-agent tasks and the official quota lock
- Explain why Codex sub-agents on another provider cannot read encrypted tasks
  and how the classic sub-agent tools setting avoids it
- Explain that Codex locks the picker to Luna Reserve once the official 5-hour
  quota runs out, and describe the workaround of temporarily making a
  third-party provider the default (#7945, #7962, #7974)
- Update the Chinese guide and the Chinese, English, and Japanese manuals
2026-10-10 10:49:23 +08:00
Jason c261126630 docs(release): add v4.0.6 release notes 2026-10-09 22:15:03 +08:00