Commit Graph
2798 Commits
Author SHA1 Message Date
Jason c5efe0baaa feat(providers): add a search button to the provider page header
Provider search could only be opened with Cmd/Ctrl+F, so users with many
providers did not know it existed.

- Add a search button next to "Add provider" in the page header. It
  toggles the existing search panel; the panel closes when switching apps
  or leaving the provider page.
- Match the API address as well as name, notes, and website. The address
  is read from every app's settingsConfig shape by a new shared
  extractProviderBaseUrl, which ProviderCard now also uses.
- Only filter while the panel is open. Closing it with Esc used to leave
  the list silently filtered.
- Portal the search panel to document.body. As a child of the list's
  space-y container it counted as a sibling, so opening it pushed every
  provider card down by 1rem.
- Add a "Show provider search" setting (on by default, device-local).
  Hiding the button keeps the Cmd/Ctrl+F shortcut.
2026-10-09 21:50:56 +08:00
Jason dc93c4962d fix(codex): keep official models visible in the aggregation catalog
With the official account as the aggregation default, CC Switch fetches
the official model list with the version of the `codex` on PATH. The
server trims the list by client_version, and for 0.140 or older it only
returns hidden entries (gpt-5.5, codex-auto-review). Desktop-only users
often keep an old CLI on PATH, so the catalog was written with every
official row hidden and the picker showed only the aggregated third-party
models.

- Use the newest Codex in use: the PATH CLI or the cli_version recorded
  on the 20 most recently created threads in Codex's state DB, which also
  covers the desktop app and editor extensions on every platform.
- A source with no `visibility = "list"` row is not usable. When the
  fetched list has none, fall back to the bundled list (no catalog if that
  has none either) and show a new notice asking to update Codex.

Fixes #8014
2026-10-09 21:30:23 +08:00
Jason 4629ee2f27 fix(tray): show every quota tier in the app row title
The app row title kept only the two tiers with the least quota left. With
three windows (5-hour / weekly / monthly, e.g. Volcengine Agent/Coding
Plan, Zhipu, MiniMax) the 5-hour window resets most often and usually has
the most left, so it was almost always dropped. 3.x listed every tier.

Write all tiers in their original order. The "almost out" suffix still
follows the tier with the least left. Remove the now unused pick_lines.

Closes #8011
2026-10-09 21:11:44 +08:00
Jason 8919d05cb3 fix(ui): use the action color for the apps page visibility switches
The neutral switch tone drew the checked track in dark gray next to a
medium-gray unchecked track, so on and off were nearly indistinguishable
in light mode. Drop the neutral tone (its only caller was the apps page
"Show" column) and let those switches use the same action color as every
other switch.

Closes #8010
2026-10-09 21:09:53 +08:00
Jason 033017b0be fix(skills): stop the import dialog from locking while discover refetches
The import mutation's onSettled awaited every affected refresh, including
the discover list, which downloads each repository from GitHub (up to 60s
per repo). TanStack Query only settles a mutation after onSettled resolves,
so isPending stayed true and the import dialog could not be cancelled or
closed until discover finished. The discover segment stays mounted once
opened, so this hit anyone who had visited it on a slow GitHub connection.

Only await the installed and unmanaged refreshes the dialog depends on;
repos and discover are still invalidated in the background.

Fixes #7994
2026-10-09 21:07:30 +08:00
Jason c1cb531fc9 feat(skills): update all Skills from the check button and list them before confirming
Updating meant checking, then filtering the table to "updates", then
finding "Update all" in the filter row. The confirm dialog also only gave
a count, and it stayed open until every Skill had finished downloading.

- The "Check updates" button turns into "Update all (N)" once updates are
  known; re-checking moves to the "..." menu. A check that finds updates
  opens the confirm dialog directly instead of a toast.
- Drop the duplicate "Update all" button from the filter row.
- The confirm dialog lists each Skill with a clickable source repo that
  opens the same page as the row link. V7ConfirmDialog gains a `details`
  slot because the body renders inside a <p>.
- Confirming closes the dialog at once; the toolbar button shows
  "Updating 1/2..." and the row menu spins until the batch is done.
- Remove the now unused `skills.updatesFound` string; add
  `skillsPage.confirm.updateListAria` and `skillsPage.updatingProgress`
  in all four locales.
2026-10-09 20:41:37 +08:00
Jason ae934663b5 fix(codex): build third-party catalog entries from the bundled classic tool template
ProxyChat and Copilot catalogs cloned the gpt-5.5 entry from Codex's own
models_cache.json (falling back to `codex debug models --bundled`, then the
bundled copy). The template only supplies the tool contract — slug, name,
context window and visibility are all overwritten — but every change
OpenAI made to that cached entry leaked into third-party models: the
hidden flag behind #7924/#7954, and newer entries carry
`tool_mode: code_mode_only`, v2 sub-agents and experimental tools the
Chat converter was never built for. The cache also announces GPT-5.5's
retirement on 2026-10-14, after which every switch would fall through to
spawning the Codex CLI.

- Always use the bundled template for ProxyChat / Copilot; drop the cache
  and CLI lookups and the per-process template cache.
- Refresh the bundled template to match Codex 0.162's own gpt-5.5 entry:
  `shell_type: unified_exec`, and include the skills / plugin usage
  instructions (both default to false in codex-rs when absent).
- Rename the loader to `load_codex_classic_tool_template` and document
  why it stays on the classic gpt-5.5 shape.
- Tests lock the classic tool contract and that a hostile
  models_cache.json no longer affects generated entries.

Existing ProxyChat sessions lose the cached `comp_hash` and get compacted
once on resume.
2026-10-09 17:21:20 +08:00
Jason 1beb8fa881 feat(ui): make the CC Switch update dot green and open About from it
The sidebar used the same neutral dot for two different things: tool
updates on "Apps" and a new CC Switch release on "Settings". The dot was
barely darker than the icon, and clicking "Settings" landed on General,
so the update button was still two steps away.

- The CC Switch update dot on "Settings" and on the About row is now the
  success green. Tool updates on "Apps" keep the neutral dot.
- Clicking "Settings" in the sidebar while an update is available opens
  About directly. Cmd+, still opens General.
2026-10-09 16:56:59 +08:00
Jason 449c7e78af docs: add aggregation mode guide and update user manuals
- Add the Chinese aggregation guide with the final cover, client screenshots, and request-routing diagram
- Update Chinese, English, and Japanese manuals to distinguish model fetching, models.dev metadata completion, and manual entry
- Clarify official subscription support, default models, and client restart requirements; add README links
- Validate 90 local documentation links, five images, and Git diff formatting
2026-10-09 16:51:08 +08:00
Jason 4aeaccf125 fix(codex): unbind providers when a managed account is removed
Deleting a managed ChatGPT account (or logging out of all of them) left
every Codex provider bound to that account pointing at a dead local ID.
#7395 made such cards recoverable by hand (switch away, pick another
account); this removes the dangling bindings where they are created.

- Remove/logout detach the affected Codex providers in one SQLite
  transaction: drop the binding, store an empty auth like a manual
  unbind, backfill category=official for legacy cards, keep unknown
  meta keys. The card then follows the native Codex login.
- Only this device's account IDs are unbound. Provider rows sync across
  devices, so a row bound to another device's account stays bound.
- The command reports "account removed but unbinding failed" separately.
  Any row still left dangling (failed unbinding, older versions, synced
  rows) keeps going through the #7395 recovery path, whose tests now
  create such rows directly.
- Frontend invalidates the Codex provider list after remove/logout,
  including on partial failure.

Thanks @SaladDay for the report and the first fix in #7060.

Fixes #7055
Refs #6969
2026-10-09 16:51:08 +08:00
Jason c37a26259e fix(proxy): explain unreadable sub-agent tasks instead of emptying them
A v2 sub-agent's task arrives as the trailing agent_message whose
payload only the main agent's backend can decrypt. The opaque-state
rectifier used to replace that payload with a placeholder like any
other foreign ciphertext, so a retry sent the sub-agent an empty task.
The upstream also often rejects it inside a 200 stream, which bypassed
the rectifier entirely and left Codex retrying the same failure.

- Keep the current task untouched when rectifying; earlier agent
  messages and other foreign state are still cleared.
- For native Responses passthrough requests ending in an encrypted task,
  hold the stream until the first non-lifecycle event under one fixed
  deadline (first-byte timeout, at most 10s), so heartbeats cannot extend
  it. A self-identified rejection before output joins the normal
  rectifier path; anything else replays byte for byte.
- When nothing else is left to clear, or the retry is still rejected,
  return a neutral 400 unreadable_encrypted_agent_task that names the
  classic sub-agent toggle, instead of letting Codex retry.
2026-10-09 16:51:08 +08:00
Jason 6760cfbbe1 feat(codex): add an opt-in classic sub-agent tools toggle for aggregation
Codex multi-agent v2 has the main agent's backend encrypt the task it
hands to a sub-agent, so in aggregation mode a sub-agent on a different
provider cannot read its task. Codex picks the tool version from each
catalog row's multi_agent_version, which the aggregated catalog copies
from the official catalog (v2 for Sol and Terra).

Add a device-level setting, off by default, that stamps
multi_agent_version = "v1" on every row of the aggregated catalog
(official rows included: ciphertext minted by OpenAI is just as
unreadable elsewhere). Classic tools pass the task as plain text at the
cost of v2-only tools such as followup_task and interrupt_agent. With
the setting off the catalog is unchanged.

Changing the setting rewrites the catalog right away when Codex is in
aggregation mode and rolls the setting back if the write fails. When
config.toml forces [features] multi_agent_v2, which Codex applies before
catalog rows, the settings row says the toggle has no effect.
2026-10-09 16:51:08 +08:00
Jason 18bdea7c73 chore(icons): update DMXAPI logo 2026-10-09 16:51:08 +08:00
Jason 0be33a8442 fix(quota): bring back colored quota numbers and warn below 20%
The all-gray quota text made it hard to tell a healthy limit from one
that is running low. Restore the v3 green / orange / red, but color only
the number ("88%", "¥82.10", "$2500", the reset count) so tier names and
"left" stay gray. Lines with no number (used up, expired, query failed)
are still colored as a whole.

- Warn once a tier has less than 20% left (was 10%), in the card and in
  the tray's "almost out".
- The "used $X" line has no total, so it stays uncolored.
- The expanded bars and the auth center keep neutral numbers while
  normal, since the bar already carries the color.
2026-10-09 16:51:08 +08:00
Jie LiuandJay Liu b4a079430c fix(codex): stop storing representative apiFormat for Copilot (#7972)
* fix(codex): stop storing representative apiFormat for Copilot

* test(codex): simplify Copilot form regression tests

* fix(codex): remove unnecessary Copilot form refactor

---------

Co-authored-by: Jay Liu <jieliu1@microsoft.com>
2026-10-09 16:44:34 +08:00
Railgun f025ee053d docs(faq): update window controls setting path for v4 in zh/en/ja manuals (#7983) 2026-10-09 16:44:28 +08:00
Lingbou 42d479560c ci(release): fail fast when linux deb or rpm package is missing (#7985)
Signed-off-by: Xingqiu Xu <hilbertanjou83@gmail.com>
2026-10-09 16:44:22 +08:00
小七 ffffd43c54 fix(codex): keep tools in third-party compaction summary turns (#7991)
聚合模式下原生 Responses 第三方上游的远程压缩摘要回合会删掉 `tools`
定义,但历史里回放的 `web_search_call`、`function_call` 等条目仍然
引用这些定义。部分上游对"有调用历史、无工具定义"的请求直接拒绝,
整个压缩回合以 502 失败(#7976)。

改为保留 `tools`,并强制 `tool_choice: "none"` 保证摘要回合不发起新
的工具调用(原请求没有 `tool_choice` 时也补上);请求本身没有 tools
时维持原行为,清掉陈旧的调用相关字段。结构化输出(`text.format`)
照旧移除,压缩响应包装不变。

Fixes #7976

Generated-by: GLM-5.3-Flash (ZCode)
2026-10-09 16:44:16 +08:00
Sailing LoongandSailingLoong 8642171835 fix(proxy): close open content blocks before terminal events in Anthropic SSE (#7986)
The OpenAI chat -> Anthropic streaming conversion only closed content
blocks on type switches and on the finish_reason path. The terminal
boundaries ([DONE] and natural stream end) flushed inline-think remnants
and emitted message_delta/message_stop without closing blocks that were
still open, so upstreams that omit finish_reason (or emit trailing
content after it) left the last text or tool block unclosed and clients
dropped its content.

Close the open non-tool block and any open tool blocks right before the
terminal events. The no-finish truncation path keeps its existing
behavior of emitting no terminal events.

Fixes #7984

Co-authored-by: SailingLoong <309827397+SailingLoong@users.noreply.github.com>
2026-10-09 16:44:10 +08:00
Komi 66144d589f fix(codex): expose cached-account restart notice outside Stack mode (#8006) 2026-10-09 15:55:32 +08:00
CaciniePandJason 889b797d8a fix(claude): allow npm scripts in the primary update path (#7099)
npm 12 blocks install scripts by default and still exits 0, so an npm-installed
Claude's `claude update` reported success while leaving a broken placeholder
binary, and the sibling-npm fallback never ran.

Prefix the primary `claude update` with npm_config_allow_scripts,
npm_config_ignore_scripts=false and npm_config_include=optional whenever the
real target lives in the @anthropic-ai/claude-code npm package. The settings
are scoped to that process tree; the fallback keeps the CLI flags from #7929.
Gating on the real path also covers npm prefixes classified as system (Intel
Homebrew node, nodejs.org pkg, ~/.npm-global, distro node), which have no
fallback at all.

Windows anchored updates and the WSL static path are not covered here.

Co-authored-by: Jason <farion1231@gmail.com>
2026-10-09 10:33:49 +08:00
Jason 2db86e94da docs(release): add v4.0.5 release notes v4.0.5 2026-10-08 23:00:52 +08:00
Jason cf02f670ff chore(release): v4.0.5 2026-10-08 23:00:52 +08:00
Jason 5d24fdf9a6 feat(usage): show all history in the all-time heatmap
The all-time heatmap only covered the last 53 weeks, so older usage was
cut off. It now keeps the last 53 weeks as the default view and adds a
"Show more" toggle that lists earlier history in contiguous 53-week
spans, back to the first recorded day. Each span is titled with its
exact date range and totals, and shading is bucketed across all spans
so they stay comparable.

A new get_usage_first_date command returns the earliest local day across
request logs and daily rollups, honoring the dashboard's app, provider
and model filters, so the heatmap knows how many spans to fetch in one
trends query.
2026-10-08 22:48:02 +08:00
Sailing LoongandSailingLoong 02759c67a1 fix(proxy): mark converted function tools as non-strict for Responses (#7717)
Anthropic tool schemas treat `required` as an arbitrary subset of
`properties`, but the Responses backend strictifies a function tool when
`strict` is omitted: optional attributes land in `required` and the model
is forced to emit fields the client deliberately left optional (#7713 -
Claude Code Agent always emitting the optional `isolation` and losing
non-worktree teammates).

Set `strict: false` explicitly on the converted function tool in
anthropic_to_responses. The hosted web-search branch is untouched, and
`parameters` still passes through clean_schema unchanged, so the
client-side optionality semantics are preserved end to end. This branch
serves both plain Responses providers and the Codex OAuth backend.

Validation: with the production hunk reverted, the new test asserting
strict=false fails (field absent); restored, the transform_responses
suite and the full --lib run are green.

Co-authored-by: SailingLoong <309827397+SailingLoong@users.noreply.github.com>
2026-10-08 22:40:50 +08:00
mr-chenguang 3af55c3973 fix(codex): give the MoArk preset a model catalog and native Responses format (#7940)
* fix(codex): give the MoArk preset a model catalog and native Responses format

模力方舟的 Codex 预设没有声明 modelCatalog,Codex 因此退回通用元数据,
/model 只列出默认模型 deepseek-v4-flash-0731,其余四个模型不可见。

同时补上 apiFormat:这条路径是原生 Responses 直连,但 moark.com 不在
codex.rs 的 CODEX_NATIVE_RESPONSES_HOSTS 兜底名单里,缺省会让
resolve_codex_catalog_tool_profile 落成 ProxyChat 档案——即克隆 Codex
的 gpt-5.5 模板,给聚合平台下发 GPT-5 harness 与自由格式 apply_patch。
该档案的前提是"代理接管并改写 custom→function",而这条路径没有代理。
实测 MoArk 接受 type=="custom" 工具,但按 codex_config.rs 对聚合平台
给出的安全方向(中性模板,degraded but working)仍走 NativeResponses。

reasoningLevels 取自实测:MoArk 在 400 明文里给出自己声明的枚举,平台
不校验该字段的模型退回模型厂商官方档位,两者皆无则不写
(qwen3-coder-plus 实测 effort 完全不生效,写档位只会给出不起作用的
选择器)。

* fix(codex): declare a single none level for MoArk's Qwen3 Coder Plus

评审指出:留空 reasoningLevels 并不表示"没有档位"。后端把未填写理解为
沿用原生模板的 none/high 两档与默认 high,所以 Codex 仍会给出一个不改变
任何行为的"关闭/开启思考"选择器——正是本 PR 声称要避免的东西。改为显式
声明单档 none:apply_codex_reasoning_level_override 生成单档,模板默认
high 不在列表内,默认值随之回落 none。(空数组同样走保留模板的早退分支,
解决不了。)

同时在 codex_config.rs 的
native_responses_catalog_honors_per_model_reasoning_levels 里补两条断言:
单档 none 产出 ["none"] 且默认 none;完全不声明则沿用模板的
["none","high"] 与默认 high。

顺带按评审意见收窄 apiFormat 的归因:表单本就会在预设缺少 apiFormat 时用
codexApiFormatFromWireApi 从 wire_api = "responses" 推出 openai_responses
并写进供应商 meta,所以经表单新增的配置此前并未被错误判定为 ProxyChat,
只有缺少格式信息的存量记录才会。该字段保留,但只是让预设自身信息完整。
2026-10-08 22:39:33 +08:00
Lingbou b1752e1c89 ci(release): require deb and rpm signatures in latest.json check (#7943)
Signed-off-by: Xingqiu Xu <hilbertanjou83@gmail.com>
2026-10-08 22:31:48 +08:00
CL e40ebb6e0a fix(codex): list explicitly configured models from hidden templates (#7925)
Generated catalog entries clone the cached gpt-5.5 template, so a template the official backend marked visibility "hide" hid every explicitly configured provider model (e.g. GLM) from the Codex picker while aggregation still counted them. Pin visibility to "list" for these entries, matching the official mirror path; native official rows keep their own visibility.

Fixes #7924
2026-10-08 22:31:23 +08:00
Betsy 3c9e430f34 fix(installer): drop ProductIcon reference from MSI shortcuts (#5952)
The desktop and Start Menu shortcuts pointed their icon at ProductIcon, which
Windows Installer extracts to %APPDATA%\Microsoft\Installer\{ProductCode}\.
Every build gets a new ProductCode and a major upgrade uninstalls the old
product first, deleting that cache directory. Taskbar pins are copies the MSI
does not manage, so they kept the dead path and showed a blank document icon
once Explorer rebuilt its icon cache (usually after a reboot).

Without an explicit icon, Explorer reads it from the target exe, whose path is
stable across versions. The Icon table and ARPPRODUCTICON stay, so the
Programs and Features icon is unchanged. Pins created before this fix still
carry the dead path and need to be unpinned and pinned again once.

Fixes #5949
2026-10-08 22:27:46 +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 5ae6ad3888 ci(wsl): retry flaky lib tests in the WSL2 nightly
The 9P share sometimes aborts a write mid-test with os error 995
(ERROR_OPERATION_ABORTED): a Claude Desktop config test passed in 1.3s
on one run and failed after 17s on the next with no code change.

Retry up to twice in the nightly only. The ci profile used by PRs keeps
failing on the first error, and nextest still lists retried passes as
FLAKY so repeat offenders stay visible.
2026-10-08 11:25:51 +08:00
Jason 7d8004c408 test(wsl): skip three lib tests the 9P share cannot host
The WSL2 nightly now reaches the lib suite: 3299 of 3302 pass. The rest
are limits of \\wsl.localhost, not product bugs:

- Windows cannot create symlinks on the share ("Incorrect function"),
  so the catalog escape and grokbuild symlink-cycle tests cannot build
  their fixtures. Skip when the link fails under a WSL temp dir and
  keep failing anywhere else.
- Extracting 13,248 files takes over the 180s per-test timeout on 9P.
  Production extracts to the system temp dir, so skip the entry-limit
  test when TEMP is a WSL share.
2026-10-08 11:11:24 +08:00
Jason faae0e4d7e ci(wsl): run the WSL2 nightly from a nextest archive
The nightly has failed since 10-05 with LNK1327: the contract step
re-invoked cargo with TEMP on \\wsl.localhost, cargo re-linked the lib
tests, and mt.exe cannot create its manifest temp file on a UNC path.

Build the lib tests once into a nextest archive with the native TEMP,
and run both the contract test and the lib suite from that archive, so
nothing is built while TEMP points at the WSL share. The archive is
extracted to the runner temp, and --no-tests fail replaces the manual
check that the contract test was discovered.

Supersedes #6856.
2026-10-08 10:43:48 +08:00
Lingbou d90de1ba0e fix(updater): support Linux package auto-updates (#7620)
Align the Tauri frontend packages with the Rust crates, include deb/rpm updater signatures in Linux releases, and publish package-specific entries in latest.json.

Fixes #4060

Signed-off-by: Xingqiu Xu <hilbertanjou83@gmail.com>
2026-10-08 10:10:57 +08:00
funkpopo c5233fe7ef fix(apps): enable native setup for Claude Code npm installs (#7929)
npm 12 blocks Claude Code's postinstall by default and still exits 0, leaving the 500-byte placeholder at bin/claude.exe (Windows reports it as incompatible). Pass --ignore-scripts=false --include=optional --allow-scripts=@anthropic-ai/claude-code to every Claude npm install and update fallback, including the copyable install commands on the Apps page.
2026-10-08 09:51:52 +08:00
f9db9f7056 feat(codex): support GitHub Copilot managed accounts with Responses/Chat routing (#7157)
Add a GitHub Copilot preset for Codex that uses a managed GitHub account.
The local route resolves each request's model against the account's live
Copilot /models catalogue and picks the upstream protocol the model
advertises (native Responses first, Chat Completions as fallback in auto
mode), with an optional explicit protocol override.

- Response handling, the opaque-state rectifier and Stack web_search
  stripping follow the transport actually used for each request rather
  than the stored apiFormat.
- Fetching models fills the catalogue from the account's live prompt
  limit, parallel tool calls and reasoning levels; presets keep
  conservative fallbacks.
- Codex only treats a card as managed Copilot by its provider type, so
  self-hosted relays keep their own key and endpoint.
- Copilot request identity headers are shared between the Claude and
  Codex paths.

Co-authored-by: yuwk <52391318+ump45nose@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Jason <farion1231@gmail.com>
2026-10-08 00:10:45 +08:00
Jason efd236a474 docs(manual): update the user manual for v4.0
Bring the zh, en and ja user manuals up to the v4.0.4 interface: the
sidebar layout, the six Settings groups, the Direct / Routing /
Aggregation connection modes, Accounts, and the Apps page. Old
Settings paths (Advanced, Routing, Auth) and takeover wording are gone.

- Add 4.6 Aggregation Mode in all three languages and list it in the
  manual indexes.
- Rewrite 1.3 Interface Overview and 1.5 Settings around the new
  layout; refresh provider, extension, routing, usage and FAQ pages.
- Use the v4.0 release screenshots where they fit and leave
  TODO(v4 screenshot) markers elsewhere.
- Update the version section of each manual index to v4.0.4.
- Remove the 40 v3 screenshots that are no longer referenced.
2026-10-07 20:42:08 +08:00
Jason a40adef3f7 fix(usage): import Grok Build session usage after 60s instead of 10min
The settle window that delays Grok Build session imports reused the
±10-minute takeover guard window, so a finished turn in Direct mode took
10-11 minutes to show up in usage stats. The settle window only needs to
cover the few seconds between turn_completed being written and the proxy
rows for that turn landing in the database, so cut it to 60 seconds and
keep the guard window unchanged.

A compile-time assertion keeps the settle window below the guard window,
and two tests cover a 90-second-old turn importing and a proxy row that
lands a few seconds after the event still blocking the import.
2026-10-07 20:16:35 +08:00
Jason a7f66764e3 chore(github): list all ten apps in issue templates
Add Claude Desktop, Grok Build, Hermes, Pi and MiniMax Code to the app
dropdowns, bump the version examples to 4.0.4, and point to
Settings → About for the version number.
2026-10-07 20:02:36 +08:00
Jason 5dd824c730 docs(readme): update all four READMEs for v4.0
- Replace the v3.8 screenshots with six v4.0 screenshots (main, apps,
  aggregation, Codex aggregated models, session reader, usage)
- Rewrite Quick Start around the sidebar and the Direct / Routing /
  Aggregation tabs, add the Apps page and Accounts, and note that the
  project switcher is now hidden by default
- Add an Aggregation column and section; tray switching now covers
  Claude Desktop and Pi now supports MCP
- Replace v3 settings paths in the FAQ with the v4 locations and add an
  entry on restarting Codex after the aggregated model list changes
- Point the release notes link at v4.0.4
2026-10-07 20:02:36 +08:00
Jason 01ee685da8 docs(release): lead with usage stats in the v4.0.4 notes 2026-10-07 19:09:33 +08:00
Jason a29a4f3868 docs(release): add v4.0.4 release notes v4.0.4 2026-10-07 18:34:16 +08:00
Jason c2282a1073 chore(release): v4.0.4 2026-10-07 18:34:16 +08:00
Jason 5b10d1996c fix(usage): keep the speed column visible in a narrow window
At the minimum window width (900) with the sidebar expanded, the request
log table area is only 644px wide, but the table had min-w-[700px]. The
rightmost speed column was pushed into the table's horizontal scroll,
whose scrollbar sits below the last row and is usually off-screen, so
users saw the column as missing.

Lower the minimum to 620px, matching the provider, model and pricing
tables. The provider and model columns already truncate (max-w-0), so
they absorb the squeeze.
2026-10-07 12:37:37 +08:00
Jason e0b36500dc feat(profiles): hide the project switcher by default
The project switcher showed on the providers page header and in the tray
for every new install, even though most users never create a project.
Flip the default so it stays out of the way until turned on in Settings.

- Use plain #[serde(default)] for show_profile_switcher and drop the
  default_show_profile_switcher() helper; AppSettings::default() now
  sets it to false
- Change the frontend fallbacks in App.tsx and GeneralSection from
  ?? true to ?? false so the header does not flash the switcher before
  settings load

Existing users keep their current behavior: the field has been
persisted to settings.json since v3.17.0, so anyone who has saved
settings already has an explicit true.
2026-10-07 12:31:44 +08:00
Jason e09fdf046c feat(settings): give the About card's star prompt its own dismissible strip
The star prompt sat at the end of the link row with ms-auto, so it
wrapped onto a line of its own and read like a stray underlined caption.

- Move it into a tinted strip at the bottom of the card with a slowly
  spinning star (stops under prefers-reduced-motion) and a "Star on
  GitHub" button that opens the repo
- Drop the separate GitHub button while the strip is shown, since the
  star button goes to the same place
- Add a close button; dismissal is remembered per device in
  localStorage, and the plain GitHub button returns to the link row
- Add settings.starOnGithub to all four locales
2026-10-07 09:16:14 +08:00
Jason f61dc5f520 fix(macos): relaunch via LaunchServices so the window comes to the front after restart
tauri::process::restart spawns the binary directly. Since macOS 14 app
activation is cooperative, so the new process's activation request is
denied and its window stays behind other apps after an in-app update or
a config-dir restart.

restart_process now launches the bundle with `open -n` on macOS, letting
the still-frontmost old instance hand activation to the new one, and
falls back to tauri::process::restart if that fails. restart_app uses
restart_process instead of app.restart() so both restart paths behave
the same.
2026-10-06 23:52:59 +08:00
Jason d35726e286 test(hermes): batch the scan-limit fixture inserts in one transaction
first_user_messages_is_scoped_to_listed_sessions inserts 1002 rows, each
in its own autocommit. On the Windows runner every commit flushes to disk,
so the test took 150-180s and intermittently hit nextest's 180s timeout
(2.5s on Linux). Wrap the fixture inserts in a single transaction.
2026-10-06 22:14:45 +08:00
Jason 8596a233b2 docs(release): add v4.0.3 release notes v4.0.3 2026-10-06 21:20:09 +08:00
Jason 014a33a42b chore(release): v4.0.3 2026-10-06 21:20:09 +08:00