Commit Graph
3175 Commits
Author SHA1 Message Date
94.mash 61af1c9853 fix(usage): show exact metric values in the app tooltip
The metric strip used native title attributes for the exact numbers.
Use HoverTip instead, anchored to the number and opening to the right,
so it does not cover the expanded token row. No tip while the cell
shows a placeholder.
2026-10-22 10:20:15 -04:00
94.mash 3260d05dc1 fix(usage): open pricing as a sub-page so its editor can be used
Pricing lived in a modal Dialog, but the add/edit pricing editor is a
FullScreenPanel portaled into #content-area. The dialog's overlay sat
above it and Radix set pointer-events: none on body while the dialog was
open, so the editor's fields and save button could not be used. Pricing
is now a FullScreenPanel too, the same pattern as other nested panels.
2026-10-22 10:20:15 -04:00
94.mash 76e2049793 fix(usage): shorten the auto-scan-off sync tooltip to one line
The longer sentence wrapped inside the pill-shaped tooltip and broke
mid-word.
2026-10-22 09:10:34 -04:00
94.mash 221c06902c fix(usage): keep heatmap tooltip rows on one line
The added hit-rate row made the label column wider, so the card near
the right edge wrapped values like "7640.5 万" and the label itself.
2026-10-22 09:08:19 -04:00
94.mash b21d4e7102 fix(usage): fix issues found in branch review
- Heatmap in hit-rate mode: a day with traffic but a 0% hit rate is now
  shaded instead of looking idle, and the tooltip shows the hit rate.
  The heatmap reuses the trend chart's hitRateOf instead of its own copy.
- Turkish: add the request log column labels and the columns menu title.
- Sync button: when auto scan is off, the tooltip says so.
- Columns menu: concurrent saves no longer drop later toggles; a failed
  save reverts only once the last save returns.
- Tab counts query only the open tab; other tabs show their cached count.
- UsageDashboard uses the shared useElementWidth instead of its own copy.
- Note the two-column limit of the pinned-column offset.
2026-10-22 09:04:55 -04:00
94.mash f9f818988f fix(usage): polish details found in review
- New-row highlight keeps a pinned column's edge shadow instead of replacing it.
- Pinned cells only follow row hover on rows that can be clicked.
- Update a stale comment about the metric strip spacing.
2026-10-22 08:29:24 -04:00
94.mash 81eb0eb67b feat(usage): let people pick how many request logs fit on a page
The pagination bar gets a rows-per-page menu (10 / 20 / 50, default 20),
remembered on this device. It stays visible on a single page as long as
there are more rows than the smallest size, so a larger choice can still be
undone. Changing the size keeps the first visible row on screen, and the
rows it adds are not animated as newly arrived requests.
2026-10-22 08:23:12 -04:00
94.mash a9ea3999f8 feat(usage): restructure the usage page layout
- Header: one sync button that shows when it last synced, next to a settings
  button; the settings sheet now holds data sources, display and pricing.
- Scope bar: date first, app chips, and one cascading provider / model menu.
- Overview: a selectable metric strip drives the trend chart and heatmap; the
  four token parts fold into an expandable second row. Hit-rate axis starts
  near the lowest value; hourly labels are short; new terracotta chart color.
- Detail panel: tabs with counts; tables scroll sideways at natural column
  widths, pin the time / app columns, group columns with wider gaps, and
  animate rows that arrive on refresh.
- Request detail drawer: no per-row dividers, no duplicate session rows.
- Empty values show an em dash; dark-mode surfaces use one token per role.
2026-10-22 08:18:43 -04: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 v4.0.18 2026-10-21 23:57:09 +08:00
Jason 4aec1aecaa chore(release): v4.0.18 2026-10-21 23:57:09 +08:00
Jason 04d0ebf568 fix(app): raise the open-file soft limit at startup on Unix
macOS GUI apps started from Finder or a login item inherit launchd's
soft RLIMIT_NOFILE of 256. The local router holds a client socket and an
upstream connection per in-flight request on top of the log, database
and config files, so a burst of parallel requests exhausted the
descriptors: accept() failed with EMFILE, upstream connects failed,
reading live-state.json failed and SQLite could not open the database.

Right after the logger is initialized, lift the soft limit to the hard
limit capped at 10240 (macOS OPEN_MAX; setrlimit rejects larger values
there). The hard limit is never touched and a limit that is already high
enough is left alone; failures are only logged.

Refs #8668
2026-10-21 23:23:26 +08:00
Jason 47ffdff8e0 fix(apps): give runtime CLI commands the login-shell PATH on Unix
When CC Switch is launched from Finder, its PATH is launchd's narrow
/usr/bin:/bin:/usr/sbin:/sbin. run_detected_tool_command_with_timeout
located the tool through a login shell but then spawned it with only the
tool's own directory prepended to that narrow PATH. An npm-installed CLI
is a `#!/usr/bin/env node` script, so when node lives in a different
directory (codex in /opt/homebrew/bin, node in /usr/local/bin) the
"Restart Codex daemon" action failed with `env: node: No such file or
directory`. The same helper runs `opencode models`.

Merge the login-shell PATH in front of the inherited PATH, as tool
install/update already does. login_shell_path now honours the caller's
deadline and spawns like resolve_path_default (stdin null, own session);
when it fails or times out the previous PATH is used unchanged.

Refs #8653
2026-10-21 23:23:26 +08:00
Jason 6226f5c468 fix(terminal): stop waiting for the launched console to close on Windows
Opening a terminal on Windows ran `cmd /C start ...` through
Command::output(). The console that `start` opens inherits the wrapper's
stdout/stderr pipe, so the pipe only reached EOF once the user closed
that window, and the command (and the open-terminal dialog) kept
spinning until then.

Point stdio at NUL and wait only for the wrapper's exit status. Launch
failures still surface through the exit code. Same approach as the
community PR #6716 by @umutcankurt, applied to the current code path.

Refs #6712
2026-10-21 23:23:26 +08:00
Dopetaiga ea8bc2c3ac fix(sessions): group a Claude session by its last /cd location (#8643) 2026-10-21 23:20:20 +08:00
cuiyf5516 e1821b5e43 fix(codex): hide reset countdown for unused quota windows (#8631) 2026-10-21 23:20:15 +08:00
Jason 132ab9cedb feat(presets): add hao.ai sponsor presets across eight apps
Add hao.ai as a full sponsor placed above Fenno: README rows and banner
in all four languages, the partner promotion copy, an inline tile icon,
and presets for Claude Code, Claude Desktop, Codex, Grok Build, OpenCode,
OpenClaw, Hermes and Pi. hao.ai serves Anthropic Messages under
/anthropic, OpenAI-compatible APIs under /v1 and xAI under /x-ai/v1, and
its catalog IDs carry a provider prefix. There is no Gemini preset since
the catalog has no Gemini models.
2026-10-21 23:14:08 +08:00
Jason 0a41250dc0 feat(presets): add DIT.ai sponsor presets across nine apps
DIT.ai (dit.ai), an AI token exchange routing each request across
competing providers, joins as a sponsor, placed directly below GrooRoute
Pro in the sponsor order (OpenModel in the Gemini file, which has no
GrooRoute preset).

- One key on api.dit.ai serves Chat Completions, Responses, Anthropic
  Messages and native Gemini (protocol docs at dit.ai/docs, catalog at
  dit.ai/models, checked 2026-10-21).
- The gateway has no Haiku 5.5 and only the dated
  claude-haiku-4-5-20251001, so Claude Code overrides the Haiku tier with
  it and Claude Desktop maps Sonnet 5.5 / Opus 5.5 / that Haiku.
- OpenCode, OpenClaw, Hermes and Pi use Anthropic Messages with Claude
  Opus 5.5 and Sonnet 5.5; Codex uses Responses with gpt-5.6-sol, Grok
  Build grok-4.7, Gemini CLI gemini-3.8-flash.
- Four-locale README sponsor rows with a banner, four-locale promo copy
  with the "ccswitch" coupon, and an inline icon from the official logo.
- Claude preset rows in the selector test go from 105 to 106.
2026-10-21 17:29:16 +08:00
Jason 8d4ec90fcb chore(presets): remove ZetaAPI sponsor and presets
ZetaAPI is no longer a sponsor; its presets go too.

- Drop the four-locale README sponsor rows and the banner.
- Remove the ZetaAPI presets from Claude Code, Claude Desktop, Codex,
  Grok Build, OpenCode, OpenClaw, Hermes and Pi.
- Remove partnerPromotion.zetaapi from every locale, Turkish included.
- Keep the zetaapi icon: existing providers saved from the preset still
  reference that icon key.
2026-10-21 17:28:05 +08:00
Jason e59252ee5b feat(presets): promote EveryAPI to a full sponsor
EveryAPI moves from the basic tier (in-app presets and website only) to
a full sponsor, placed directly below OpenModel in the sponsor order.

- Four-locale README sponsor rows with the new copy and a 1200px banner.
- The EveryAPI preset blocks in the seven preset files move below
  OpenModel so file order matches the README tables; the presets
  themselves are unchanged.
- The in-app promo copy adds "GPT from 15% of the official price" and
  folds the first top-up bonus and the "ccswitch" code into one perk,
  since they are the same offer.
2026-10-21 17:04:27 +08:00
Jason 6fabe63abb fix(agy): show Antigravity session-log rows as "Session log"
The frontend map of session placeholder names missed
"Antigravity (Session)", so the provider column showed the raw English
name and truncated it. Add the entry and a test that every placeholder
name in usage_stats.rs is translated.
2026-10-21 17:04:27 +08:00
Jason e91689f2da fix(agy): drop the Antigravity-only note on the usage page
No other app shows a pricing note above the usage tables, although
Codex, Gemini and the rest also estimate session-log amounts from API
prices. Remove the note, its locale key and the test that pinned it.
2026-10-21 17:04:27 +08:00
Jason 276eff8dce feat(agy): open all four quota windows from the card's quota column
The card keeps one line per group (Gemini, Claude/GPT) to fit, so the
5-hour and weekly windows could not both be seen anywhere on it. On
Antigravity cards the quota column is now one dropdown, like the resets
dropdown on Codex official cards, listing every window with its own
reset time. Refreshing moves to the ↻ button that appears on hover.
Other cards keep click-to-refresh.
2026-10-21 17:04:27 +08:00
Jason 997e78b565 feat(agy): show the bound account's quota on official cards
An official Antigravity card bound to an Auth Center account showed the
quota of whatever account agy was signed in with, which is a different
account until the card's terminal is opened. It now shows the bound
account's quota, shared with that account's row in the Auth Center, and
like Codex account cards it shows even when the card is not current.

Cards that follow agy's sign-in, and platforms that cannot switch
accounts, keep the signed-in quota.
2026-10-21 17:04:27 +08:00
Jason 2c63012b9e perf(agy): query the signed-in account's quota without starting agy
Official Antigravity cards asked agy's own /usage command for quota, which
starts agy and takes seven to nine seconds. On macOS the card now takes the
account agy is signed in with from the keychain, adds it to the Auth Center
if it is new, and asks Google directly with CC Switch's copy of the token,
the same way the Auth Center does (about one second).

agy's /usage is still used when the keychain holds no recognizable login,
when the user removed that account from CC Switch, and on platforms that
cannot switch accounts.
2026-10-21 17:04:27 +08:00
Jason c0490b0529 feat(agy): show each account's quota in the Auth Center
Every Antigravity row in the Auth Center now has a quota column, the
same one Copilot, ChatGPT and xAI rows use: Gemini and Claude/GPT, each
with a 5-hour and a weekly window. It is queried once when the page
opens and on the refresh button, through agy_account_quota, so accounts
agy is not signed in with show quota too. Accounts that need to sign in
again get no quota column.
2026-10-21 17:04:27 +08:00
Jason 8f9525b03d fix(agy): explain why an account is not eligible for Antigravity
Accounts that Google does not allow to use Antigravity, such as those
restricted by age, get the same 403 "You do not have a valid license,
contact your administrator" from the quota endpoint. That reads like a
CC Switch or licensing problem. On a 403 the quota query now asks
loadCodeAssist once, and when the account only has ineligible tiers it
shows Google's own reason instead.
2026-10-21 17:04:27 +08:00
Jason 5a08e230c0 feat(agy): query each Antigravity account's quota directly
The Auth Center can now show quota for every Antigravity account, not
only the one agy is signed in with. The new agy_account_quota command
calls Google's retrieveUserQuotaSummary with the account's own token, so
no switch is needed. The response carries the same buckets as agy's
/usage, and both now go through one tier builder.

The endpoint only answers clients that identify as Antigravity, so the
User-Agent is "cc-switch/<version> (antigravity)": it names CC Switch
and adds the word the server checks for. It only reads quota; it never
calls a model, warms up accounts or switches on low quota.

Tokens that expire within two minutes are refreshed first. The refreshed
token is saved only to CC Switch's copy, never to the keychain: agy keeps
refreshing its own login, and Google does not rotate the refresh token,
so both access tokens stay valid. For the account agy is using, the
keychain login is absorbed first so its newer token is used. A rejected
token triggers one forced refresh; invalid_grant marks the account as
needing sign-in again.
2026-10-21 17:04:27 +08:00
Jason 816346022b fix(pricing): price deepseek-v4.1-flash as V4.1 Flash
Third-party upstreams such as OpenCode Go, OpenRouter (deepseek/
namespace) and the Hermes presets call DeepSeek V4.1 Flash
deepseek-v4.1-flash. Pricing had no row for that id: none of the lookup
fallbacks turn it into deepseek-flash, and the prefix fallback only
matches longer ids. These requests showed "Unpriced" and were counted
at $0.

Add a deepseek-v4.1-flash row at the same official peak price as
deepseek-flash (0.3 / 1.2 / 0.006 per million). Default prices are added
again on every start, so existing installs get the row on next launch.
Requests already logged are not repriced.
2026-10-21 17:04:27 +08:00
Jason 0af8b77288 feat(agy): bind official cards to an Antigravity account
An official Antigravity card can now pick one of the Auth Center accounts
(macOS only). With an account picked, Open Terminal first switches agy's
global sign-in to it; when it is already signed in, nothing is written.
Without one, the card keeps following whatever agy is signed in with.

The binding is stored as authBinding with authProvider "agy_oauth". The
account id is the Google subject, so a card synced to another computer
works once the same account is added there; if it is missing, opening the
terminal stops with a message instead of launching under another account.
Platforms that cannot switch ignore the binding and keep it on the card.

The Open Terminal dialog says when opening will switch agy's sign-in, and
warns when agy is already running. The Auth Center counts bound cards as
users of an account, so the removal dialog lists them.
2026-10-21 17:04:27 +08:00
Jason 8627187954 feat(agy): add an Antigravity group to the Auth Center
On macOS the Auth Center now lists Antigravity accounts next to Copilot,
ChatGPT and xAI. The account agy is signed in with is tagged "In use by
agy", and "Switch agy to this account" in the row menu replaces agy's
sign-in. After switching, CC Switch checks whether agy is running and
warns that open sessions keep the old account and may write it back.

Adding an account opens Google's sign-in page in the browser. The shared
login hook treats a response without a user code as this browser flow: it
leaves the clipboard alone, polls the local result every 1.5 seconds and
cancels the backend flow so the callback port is released. The pending
block shows a "reopen sign-in page" button instead of a device code.

Removing an Antigravity account says that agy stays signed in.

The backend now records the sign-in time in seconds, which is what the
Auth Center formats.
2026-10-21 17:04:27 +08:00
Jason fdbac61c31 feat(agy): manage Antigravity official accounts in the Auth Center backend
agy keeps a single global login in the system keychain (service "gemini",
account "antigravity"). CC Switch now keeps its own copy of each account
and switches agy by writing the chosen one back into that entry.

- Sign in through the browser with agy's own OAuth client (PKCE, loopback
  callback on 127.0.0.1), requesting the same scopes agy does, so agy can
  keep refreshing the token on its own.
- Read and write the keychain through /usr/bin/security, the program the
  entry already trusts: the value goes over `security -i` stdin, `-U`
  updates in place and keeps the entry's access control, and the write is
  read back and checked.
- Before overwriting, take back the current login: refresh tokens agy
  renewed go to their account, an unknown account is added, and an
  unreadable value is stashed to agy-login-stash.json.
- Removing an account only drops CC Switch's copy; agy is never signed out.
- Exposed as the "agy_oauth" provider of the generic auth_* commands, where
  the default account is the one agy is signed in with. macOS only for now.
2026-10-21 17:04:27 +08:00
Jason 711a4127ff fix(usage): only list apps shown on the Apps page in the app filter
The usage dashboard listed every known app as a filter chip regardless of
the visibility switches on the Apps page. Filter the chips the same way the
session manager does: Claude Code stays while Claude Desktop is shown, and
the currently selected app is kept even if it has been hidden.
2026-10-21 17:04:27 +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
SaladDay ab5d4a12dd fix(ui): trim redundant provider and settings helper copy (#8633) 2026-10-21 16:37:31 +08:00
SaladDay c1fd26bde7 fix(ui): show compact mode-colored connection badge in header (#8634) 2026-10-21 15:17:42 +08:00
Thefool 1ef08d5e7d fix(windows): stop in-app updates from rebooting the machine (#8628)
The MSI now carries REBOOT=ReallySuppress, so Windows Installer never restarts the machine when a file is in use during an in-app update, including updates driven by older updaters. The updater also passes REBOOT=ReallySuppress, a leftover instance is closed on the updater path, and the release workflow fails if the built MSI lacks the property.

Fixes #8534
2026-10-21 15:08:23 +08:00
Jason c776fd0ebf feat(agy): trim the form hint and require a key on custom cards
The long paragraph above the Antigravity form explained a case that should
not exist: a non-official card without a key is just the official login
card again. Drop the paragraph and warn on save when a custom card has no
API key, as Gemini CLI already does. A key without an endpoint stays valid
and uses Google's default API.

The endpoint and model rules move into "?" tips next to their fields. The
card's terminal button now reads "Open Terminal with This Provider"; the
shorter "Open Terminal" label stays for the Claude Code card menu.
2026-10-21 11:31:01 +08:00
Jason 9a10e4f7a9 feat(agy): replace the enable button with Open Terminal
CC Switch can only reach the agy it starts itself: a third-party key
travels in that process's environment, so "enabling" a key card never
changed what a plain `agy` used. Antigravity cards now only launch.

- Every card's primary action is Open Terminal; there is no "in use"
  state, the official quota shows on official cards at all times, and
  any card can be deleted.
- Official cards start `agy --model=<display name>`, which applies to
  that session only. Key cards keep their private --gemini_dir.
- The real ~/.gemini/antigravity-cli/settings.json is never written any
  more: switching is refused, adding the first card, full syncs and
  deep links with enabled=true leave it alone. The only remaining write
  removes the modelProvider left behind by the #8268 preview.
- The terminal dialog and form hints no longer talk about switching.
2026-10-21 10:47:46 +08:00
Jason fb91155a5a fix(agy): accept the empty mcp_config.json agy creates on first run
agy writes a zero-byte ~/.gemini/config/mcp_config.json the first time it
starts. Parsing it as JSON failed, so enabling any MCP server for
Antigravity showed "Invalid Antigravity MCP JSON" and importing from it
failed too. Treat a blank file as having no servers.
2026-10-21 10:03:45 +08:00
Jason 2e22ca209b feat(agy): give Antigravity its own icon and manage the CLI on the Apps page
- Use the Antigravity logo for the app instead of reusing Gemini's.
- List Antigravity CLI on the Apps page: install with the official script,
  update with `agy update` (also for the Homebrew cask, which is
  auto_updates), read the latest version from the release manifest, and
  uninstall official-script and cask installs.
- Find install.ps1's %LOCALAPPDATA%\agy\bin on Windows.
2026-10-21 09:23:59 +08:00
Jason 941267953e fix(agy): show only the typed prompt in sessions and describe the quota check
- agy stores every prompt wrapped in <USER_REQUEST>, followed by context it
  adds itself (<ADDITIONAL_METADATA>, <USER_SETTINGS_CHANGE>). Session titles
  and user messages now show only the text inside <USER_REQUEST>; an empty
  request keeps the original content.
- The official-quota hint said CC Switch reads the CLI's OAuth credentials.
  For agy it runs agy's own /usage command instead, so the usage dialog now
  says that (and that a check takes about 10 seconds).
2026-10-21 08:54:18 +08:00
Jason 1b4cd547c4 feat(agy): show the signed-in quota on the official card
- Ask agy's own /usage command (agy -p /usage --output-format json) instead of
  reading credentials; it makes no model call and opens no conversation.
- Keep the Gemini group and the Claude/GPT group, each with its 5-hour and
  weekly window, as four tiers; unknown buckets are skipped.
- On the card each group shows only its window with the least left, since
  four tiers do not fit; the expanded view lists all four.
- A missing agy is treated as no login (nothing shown); a timeout propagates
  so the last good value is kept; other failures do not echo agy's output.
2026-10-21 07:26:26 +08:00
Jason dfe100813f feat(agy): share prompts with key profiles, resume key sessions, price usage
- Store the agy prompt in ~/.gemini/config/AGENTS.md, which agy reads as a
  standalone customization root and every private key profile links to.
- List sessions recorded under each key profile and resume them with the
  matching --gemini_dir and the card's key in a launched terminal.
- Fetch the model list for API-key cards from agy's own offline catalog in a
  throwaway profile, so the form offers display names agy actually accepts.
- Record agy session usage under priced model IDs (display name kept as the
  request model) and estimate cost from Gemini API prices.
- Treat an imported settings file with a model as the official login card.
2026-10-21 00:12:44 +08:00
Jasonandajia1206 b667b00a5c feat(agy): show the model on cards and attribute session usage to it
Ported from #8608:
- Model discovery works before agy has written a settings.json; the
  official login lives outside that file.
- Configurations imported from live are marked official: the key is never
  on disk, so an import is always agy's own login.
- Antigravity provider cards show the configured model.
- Session usage rows take their model from the `Model Selection` step agy
  injects at the start of a conversation, since responses carry no model.

Not ported: running `agy models` while importing on startup or when the form
opens. It takes several seconds on a signed-in machine and may prompt for
sign-in on one that never logged in; the Fetch Models button stays explicit.

Co-authored-by: ajia1206 <491387123@qq.com>
2026-10-20 23:58:50 +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 v4.0.17 2026-10-20 22:08:53 +08:00
Jason e172f37d88 chore(release): v4.0.17 2026-10-20 22:08:53 +08:00