134 Commits
Author SHA1 Message Date
Jason c9e059a4d9 chore(release): v4.0.20 2026-10-24 23:11:53 +08:00
dsdbb520andJason 309c9c5154 fix(agy): recover subagent usage models from native generations (#8693)
Antigravity responses without a model field or a Model Selection event (subagents, ACP sessions) were imported as unknown. Recover the model from the native conversations/<id>.db: prefer the tiered model ID (field 21, matching Model Selection and pricing) and fall back to the base model name (field 19). The database is opened read-only, never waits on a writer, and keeps already recovered names when it cannot be read.

Co-authored-by: Jason <farion1231@gmail.com>
2026-10-24 22:42:59 +08:00
Jason a043b1f863 chore(release): v4.0.19 2026-10-23 20:13:26 +08:00
Jason 4aec1aecaa chore(release): v4.0.18 2026-10-21 23:57:09 +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 e172f37d88 chore(release): v4.0.17 2026-10-20 22:08:53 +08:00
Jason 855a2eb8b1 chore(release): v4.0.16 2026-10-19 18:26:47 +08:00
Owlbayandfunkpopo 77c6dc793d feat(tray): replace the tray menu with a glass panel (#8432)
On macOS and Windows, clicking the tray icon opens a panel with a Configuration tab (apps, in-use providers, modes, quota) and a Usage tab. Every row reuses the native menu's event id and goes through handle_tray_menu_event. Linux keeps the native menu and adds an "Open quick panel" item.

macOS uses native glass under each card. Windows keeps a fixed canvas per popup and clips it with a window region, with opaque cards.

Co-authored-by: funkpopo <funkpopoisme@gmail.com>
2026-10-18 10:51:38 +08:00
Jason 8e42cb75d1 chore(release): v4.0.15 2026-10-17 23:20:46 +08:00
Jason d858ab4cf8 chore(release): v4.0.14 2026-10-16 20:16:22 +08:00
Jason 894cce82cc chore(release): v4.0.13 2026-10-15 22:12:24 +08:00
Jason edf3220432 chore(release): v4.0.12 2026-10-14 18:36:57 +08:00
Jason 3b3c3f0b32 chore(release): v4.0.11 2026-10-13 23:14:19 +08:00
Jason db29caefb7 chore(release): v4.0.10 2026-10-13 00:19:45 +08:00
Jason bee47fdf48 feat(deeplink): let provider links bring their own icon via iconUrl
A provider link can now carry `iconUrl`, an https address of the site's
own logo. The confirmation dialog downloads it as soon as it opens and
shows it at the top; importing stores it as the card's custom icon. No
extra confirmation step. Any failure is silent: the card falls back to
the built-in `icon` name, or to the name's initials.

The image goes through the same path as a local upload: the backend
returns a data URI, the frontend redraws it on a canvas into a 96x96 PNG,
and the provider save validation checks it again. The address itself is
never stored or rendered, and the import command never downloads.

The download (`deeplink/icon_fetch.rs`):
- Parsing drops addresses that are not https, use an IP or a non-default
  port, carry credentials or exceed 2048 characters; the rest of the link
  still imports.
- Every resolved address must be public, and the connection is pinned to
  them so a second DNS answer cannot point it elsewhere. Redirects are
  followed by hand, up to 3, and each hop is checked again.
- No system proxy, no cookies, no Referer, 5 s overall timeout, body read
  as a stream and capped at 256 KB.
- Content-Type must be PNG, JPEG, WebP or SVG and match the file's magic
  bytes; bitmap dimensions are read from the header and capped at 4096.
- 198.18.0.0/15 is allowed on purpose: Clash and Surge fake-ip mode
  resolve every domain into it. The trade-off is written next to
  `is_public_ipv4`.
- Errors are logged without the URL, which may carry query tokens.

Closes #8117
2026-10-12 23:26:43 +08:00
Jason 21203803ed feat(providers): upload a custom provider icon
The icon picker gets an "Upload Image" button (PNG, JPG, WebP or SVG, up
to 2 MB and 4096 px). The image is redrawn on a canvas into a 96x96 PNG
and stored as a data URI in the existing `icon` column, so it travels
with the row through cloud sync, duplication and profiles. No new column,
no files on disk, nothing keyed by provider id (ids are shared across
apps). Opaque square images fill the icon box; anything else is padded to
the size of a built-in transparent logo. Uploading only changes the form;
nothing is written until Save.

The original file never reaches the database: SVG is loaded through
<img> (no scripts, no external requests) and rasterized, and re-encoding
drops EXIF. Custom icons are only ever rendered with <img>; remote URLs
are never loaded as icons.

Validation at every way in:
- Saving a provider or a universal provider, and syncing a universal
  provider to its apps, fully decodes the PNG with the `png` crate
  (already in the tree via `image`) under a 1 MiB decode limit and caps
  it at 64 KiB and 256x256. Other strings still pass as icon names so old
  rows stay editable.
- SQL import and cloud sync bypass saving, so the staging database drops
  invalid custom icons from both `providers` and the universal provider
  JSON before it replaces the main one. The rest of the backup imports
  normally.
- Rendering checks the length and reads the PNG signature, IHDR length
  and dimensions from the header before showing an image, and falls back
  to initials if it fails to decode. Browsers sniff image formats, so
  without the signature check a disguised GIF could slip past the size
  limit.

Also:
- Uploads still being processed are dropped once the user removes the
  icon, picks a built-in one, uploads again or closes the picker.
- Aggregation mode no longer derives model key prefixes from a custom
  icon; it falls back to the provider name.
- The deep-link `icon` parameter only accepts built-in icon names; other
  values are dropped instead of failing the link, so links cannot put a
  data URI straight into the database.

Refs #8117
2026-10-12 23:26:43 +08:00
Jason 5e57b1ecf1 chore(release): v4.0.9 2026-10-11 23:26:46 +08:00
Jason ed15cd0141 chore(release): v4.0.8 2026-10-10 23:32:26 +08:00
Jason fda103e9b1 chore(release): v4.0.7 2026-10-10 16:53:17 +08:00
Jason 0fc67c3b35 fix(codex): warn about stale Codex clients on Windows without a process table
The stale-client check reads the process table, which Windows does not
have, so neither the model list notice nor the cached-account notice
ever appeared there, and the restart button always reported that the
daemon was not running.

On Windows the managed daemon is now found through its own daemon.pid:
the process is opened by pid and counts as running only while it is
still active and its creation time matches the recorded one, so a
reused pid is not mistaken for it. Restart is only offered for a daemon
known to be running, since Codex's restart command starts one otherwise.

The desktop app and editor plugins cannot be seen there, so the notice
falls back to "changed since you last dismissed it": the model list and
login fingerprints are recorded in codex-client-ack.json when the user
closes the notice, through the new acknowledge_codex_stale_clients
command, and a later change shows it again with wording that says
CC Switch cannot tell whether those clients are open. Without a record
the current state is taken as acknowledged, so upgrading does not show
it, and the first login seen becomes the baseline, so signing in is not
reported as an account switch.

Closing the notice used to hide it until the app, mode or provider
changed, so changing the model list again on the same provider stayed
silent on every platform. The stack view now carries a revision derived
from the same fingerprints, and the notice reappears once it changes.
2026-10-10 16:36:44 +08:00
Jason 314968b65d chore(release): v4.0.6 2026-10-09 22:15:02 +08:00
Jason cf02f670ff chore(release): v4.0.5 2026-10-08 23:00:52 +08:00
Railgun 36c8b87e60 fix(linux): restore Wayland title-bar controls on first show and tray re-show (#7947)
Tao 0.34 wraps the Wayland HeaderBar in an EventBox with above_child=true, so its input window can stack above the minimize/maximize/close buttons after the first map or a hide/show round-trip. Clear above_child on the GTK main thread whenever the main window is shown. This becomes a no-op once Tauri ships tao 0.36+ (tauri-apps/tao#1218).

Also bump the existing input-region nudge by one logical pixel instead of one physical pixel (a no-op on HiDPI), skip it for maximized windows, and run concurrent nudges one at a time so a bumped size is always restored.

Fixes #7405
Fixes #2736
Fixes #7499
2026-10-08 21:52:49 +08:00
Jason c2282a1073 chore(release): v4.0.4 2026-10-07 18:34:16 +08:00
Jason 014a33a42b chore(release): v4.0.3 2026-10-06 21:20:09 +08:00
Jason 08f789a8c4 chore(release): v4.0.2 2026-10-06 00:07:54 +08:00
Jason d36bb7a938 chore(release): v4.0.1 2026-10-05 12:22:32 +08:00
Jason c62eab2ba1 build(release): compile with 16 codegen units
With codegen-units = 1, LLVM optimizes the large main crate on a single
thread, and that dominates release build time. 16 units make the main
crate compile about 64% faster for a binary about 17% larger, measured
locally. Applies to every release target; thin LTO and opt-level "s"
are unchanged.
2026-10-05 12:17:24 +08:00
Jason 412579f9ad chore(release): v4.0.0 2026-10-04 17:06:16 +08:00
Jason 84efe1fb5b chore(release): v3.20.4 2026-09-22 22:17:05 +08:00
Jason 1a7250162c chore(release): v3.20.3 2026-09-11 23:23:51 +08:00
Jason b6254432a9 chore(release): v3.20.2 2026-09-07 21:54:01 +08:00
Jason 9485cf2f3d chore(release): v3.20.1 2026-08-28 08:19:45 +08:00
Jason 18ca2da0b5 chore(release): v3.20.0 2026-08-18 16:48:02 +08:00
Jason 425e932b7f chore(release): v3.19.2 2026-08-06 12:21:00 +08:00
Allen Xu 92ca95ffcd feat(opencode): load OMO models from runtime opencode models (#5522)
* feat(opencode): load OMO models from runtime opencode models

Surface OAuth/Zen free models in OMO/OMO Slim pickers by running the
installed OpenCode CLI, with a 20s timeout and a toast when discovery fails.

* style: fix rustfmt and prettier for OMO runtime models

* fix(opencode): pass OPENCODE_CONFIG_DIR for runtime model discovery

Honor the configured OpenCode config directory when running
`opencode models`, including WSL UNC path translation. Also drop the
unused run_detected_tool_command wrapper that failed clippy.

* fix(opencode): satisfy Windows Clippy

* fix(opencode): bound runtime model discovery

* fix(opencode): address runtime model review feedback

* fix(ci): parenthesize unsafe kill expression
2026-08-04 09:43:20 +08:00
Jason b3a20e58b0 chore(release): v3.19.1 2026-07-31 22:30:28 +08:00
Jason 6b13d01825 chore(release): v3.19.0 2026-07-30 09:29:54 +08:00
56fb46c093 perf(codex): cache parent rollout timelines across fork cutoffs (#5626)
* perf(codex): cache parent rollout timelines

* fix(codex): harden parent timeline cache

* fix(codex): tighten replay cache invalidation

---------

Co-authored-by: Ayanami <ay@nami.ltd>
Co-authored-by: SaladDay <92240037+SaladDay@users.noreply.github.com>
2026-07-29 23:49:46 +08:00
Jason df1751a893 chore(release): v3.18.0 2026-07-21 22:23:17 +08:00
997be22bfa fix(tray): detect system locale for first-run language instead of hardcoding zh (#4355)
The tray menu used a hardcoded zh (Simplified Chinese) fallback whenever
settings.language was unset (i.e. first install). On systems whose UI language
resolves to Traditional Chinese / Japanese / English via the frontend's
navigator-based detection, the tray therefore showed Simplified Chinese until
the user manually switched language once.

Detect the OS locale via the sys-locale crate and map it to a supported tray
language, mirroring the frontend getInitialLanguage precedence
(zh-TW/HK/MO/Hant -> zh-TW, other zh -> zh, ja -> ja, en -> en, otherwise zh).
This keeps the tray consistent with the UI from the first launch with no timing
window. An explicitly stored settings.language still takes precedence, so user
choices are never overridden. Adds unit tests for the locale mapping.

Co-authored-by: LaiYueTing <LaiYueTing@users.noreply.github.com>
Co-authored-by: Jason <farion1231@gmail.com>
2026-07-17 21:35:10 +08:00
Jason c154d30b7a chore(release): v3.17.0 2026-07-13 21:24:58 +08:00
Jason 8d1b3306d0 chore(release): v3.16.5 2026-07-01 23:55:55 +08:00
Jason f9547da930 chore(release): bump version to 3.16.4 2026-06-27 10:52:21 +08:00
1a0e8c7a44 fix: decompress body before forward and support zstd (#3817)
* fix(proxy): decompress Codex request body before forward, support zstd

Codex Desktop sends zstd-compressed request bodies when authenticated
against the Codex backend, which broke local proxy routing because the
handlers parsed the raw bytes with serde_json directly.

Reworked on top of current main so it preserves the response_processor
behavior that landed after this PR was first opened:

- Extract content-encoding helpers into a shared proxy::content_encoding
  module. decompress_body keeps returning Option<Vec<u8>> so unknown
  encodings stay pass-through with their content-encoding header intact,
  and keeps the deflate zlib-then-raw fallback (RFC 9110).
- Add zstd/zst support (zstd 0.13) and disable reqwest's auto zstd
  decompression via .no_zstd() for parity with gzip/br/deflate.
- Decompress the request body before JSON parsing in the three Codex
  handlers (chat_completions / responses / responses_compact) and strip
  the stale content-encoding / content-length / transfer-encoding headers
  so the forwarder regenerates them.
- Support stacked codings (e.g. "gzip, zstd") by decoding in reverse
  order and merge repeated Content-Encoding headers via get_all.

Fixes #3764
Fixes #3696

Co-authored-by: chenx-dust <16610294+chenx-dust@users.noreply.github.com>

* fix(proxy): decompress upstream error bodies before reading them

The forwarder error branch consumes non-2xx responses via String::from_utf8
directly, bypassing read_decoded_body. reqwest has no auto-decompression
feature enabled, so a compressed error body (gzip/br/deflate/zstd) arrives
as raw bytes, fails from_utf8, and gets dropped, hiding upstream rate-limit
and auth details from the client.

Decode the error body with the shared proxy::content_encoding helper,
mirroring the success path. Falls back to the raw bytes when the encoding is
unsupported or decoding fails.

Co-authored-by: chenx-dust <16610294+chenx-dust@users.noreply.github.com>

---------

Co-authored-by: Jason <farion1231@gmail.com>
Co-authored-by: chenx-dust <16610294+chenx-dust@users.noreply.github.com>
2026-06-26 08:50:59 +08:00
MoonDreamStarsandMoonDreamStars 2db3163cf2 ci: add Windows ARM64 release support (#3950)
* ci: add Windows ARM64 release artifacts

* ci: keep release matrix jobs independent

* ci: fix pnpm cache path on Windows runners

* ci: setup pnpm with corepack on Windows ARM64

* ci: fix Windows ARM64 release build

* ci: retry transient release bundler downloads

* ci: remove non-minimal release workflow changes

* ci: keep release matrix jobs independent

macOS signing fails in forks without Apple secrets and, with default
matrix fail-fast, cancels the sibling jobs (including Windows ARM64)
before they finish. Disable fail-fast so each platform runs to completion.

---------

Co-authored-by: MoonDreamStars <moondreamstar1@gmail.com>
2026-06-23 17:30:41 +08:00
Jason 21e695f68a chore(release): prepare v3.16.3
- Bump version to 3.16.3 (package.json, tauri.conf.json, Cargo.toml, Cargo.lock)
- Add CHANGELOG entry for v3.16.3 (59 commits since v3.16.2)
- Add trilingual release notes (zh / en / ja) under docs/release-notes/
2026-06-15 00:08:21 +08:00
Jason f1118d370f chore(release): prepare v3.16.2
Add the v3.16.2 CHANGELOG entry covering the 41 commits since v3.16.1,
bump the version across package.json, tauri.conf.json, Cargo.toml, and
Cargo.lock, and add trilingual (zh/en/ja) release notes.
2026-06-08 12:39:50 +08:00
阿南 8e7d167ace 修复任务栏图标 (#3457) 2026-06-04 23:32:32 +08:00
2a24da517f feat: 新增 S3 兼容云存储同步 (#1351)
* Add S3 Cloud Sync design document

Design for adding AWS S3 as a new Cloud Sync backend alongside WebDAV.
Hybrid approach: extract shared sync protocol, add independent S3 transport.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add S3 cloud sync implementation design (reqwest + Sig V4)

Updated design based on 2026-03-06 draft: switches from rust-s3 crate
to hand-rolled AWS Sig V4 on existing reqwest for broader S3-compatible
service support (AWS, MinIO, R2, Alibaba OSS, Tencent COS, Huawei OBS).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add S3 cloud sync implementation plan (11 tasks, TDD)

Detailed step-by-step plan covering: sync_protocol extraction, S3 Sig V4
transport, settings, sync/auto-sync modules, Tauri commands, frontend
presets/dynamic form, and i18n.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* deps: add hmac crate for S3 Sig V4 signing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: extract sync_protocol.rs from webdav_sync.rs for shared use

Move transport-agnostic sync protocol logic (constants, types, snapshot
building, manifest validation, artifact verification, snapshot application,
utilities) into a new shared sync_protocol module so both WebDAV and the
upcoming S3 transport can reuse it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: use transport-neutral error keys in sync_protocol

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add S3 transport layer with AWS Sig V4 signing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add S3SyncSettings to AppSettings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add S3 sync module with upload/download/fetch

Implements the S3 sync protocol layer (s3_sync.rs) that combines the
shared sync_protocol with the S3 transport. Mirrors the WebDAV sync
module structure with independent sync mutex, connection check,
upload, download, fetch_remote_info, and sync status persistence.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add S3 auto sync worker with debounce

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add S3 sync Tauri commands and auto sync worker startup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add S3 sync TypeScript types and API layer

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add S3 sync i18n translations (en/zh/ja)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add S3 sync presets and dynamic form to sync settings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: preserve HTTP scheme for S3 custom endpoints (MinIO support)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: add live S3 integration tests (env-var driven, --ignored)

Run with: S3_TEST_AK=... S3_TEST_SK=... S3_TEST_BUCKET=... cargo test --lib services::s3::integration_tests -- --ignored

Verifies test_connection, put_object, get_object, head_object, and 404
handling against a real S3 bucket using the project's own Sig V4 signing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: remove internal design docs before PR

* fix: wire S3 auto-sync to DB hook & sync UI state on async load

- P1: Add s3_auto_sync::notify_db_changed call in SQLite update_hook
  so S3 auto-sync worker receives DB change signals (was only wired
  for WebDAV, leaving S3 worker idle)

- P2: Add useEffect to update syncType selector when s3Config loads
  asynchronously, preventing stale "webdav" default for S3 users

* fix: satisfy clippy for s3 sync

* fix: address s3 sync review feedback

---------

Co-authored-by: Keith (via OpenClaw) <keithyt06@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Jason <farion1231@gmail.com>
2026-06-04 22:18:51 +08:00