Commit Graph
8 Commits
Author SHA1 Message Date
SaladDay 0bbbb534fc fix(hermes): prefill MiniMax provider keys that don't collide with Hermes built-ins (#8538)
Hermes routes model.provider `minimax` to its built-in provider and ignores a
same-named custom_provider, so no request is sent. The MiniMax presets now
prefill cc-switch-minimax / cc-switch-minimax-en, and MiniMax-M3.1-Flash
declares supports_vision so images go to the main request.
2026-10-19 18:01:30 +08:00
SaladDay 734c4831dd feat(minimax): add MiniMax-M3.1-Flash to the official MiniMax presets (#8518)
Make MiniMax-M3.1-Flash the default model on the official MiniMax / MiniMax en presets across Claude Code, Claude Desktop, Codex, Hermes, OpenCode, OpenClaw and Pi, keeping MiniMax-M3 selectable, and seed its pricing.

Claude Code keeps M3 in the Opus slot so it stays selectable through the local route. Hermes pins the background title model to M3 (M3.1 cannot turn thinking off) only when the user has not chosen their own title model or route, and releases the pin when no active card declares it.
2026-10-19 16:42:20 +08:00
SaladDayandJason 492245dcb9 feat(codex-oauth): show per-account usage in Auth Center (#4887)
* feat(codex-oauth): show per-account usage in Auth Center

Each ChatGPT (Codex OAuth) account under Settings → 认证 now displays its
own subscription usage — reset countdowns and per-window progress bars —
directly in the account list, instead of usage only being visible on the
active provider card.

- Add useCodexOauthQuotaByAccountId(accountId) and refactor
  useCodexOauthQuota to delegate to it (shared query key → cache reuse)
- Add CodexOauthAccountQuota, a thin per-account wrapper that reuses the
  existing SubscriptionQuotaView expanded layout (same look and 5-state
  handling as provider cards), with a light spinner on first load
- Render it under each account row in CodexOAuthSection; fetch once when
  the Auth Center opens, manual refresh available (no polling)

Copilot is intentionally left out — same as before, this is Codex-only.

* refactor(codex-oauth): stable async loading placeholder for account usage

The account header (login + badges + actions) already renders independently
of the usage query — the quota is fetched async via Tauri invoke + React
Query, so the account never waits on it. Make that visually obvious and
jump-free: while the usage loads, show a spinner inside a placeholder shaped
like the final quota card (same rounded-xl / border / bg-card), so the card
morphs smoothly into the data instead of popping in from an empty gap.

* fix(codex-oauth): scope account quota to auth center

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-08-03 21:47:49 +08:00
SaladDay 4317bd9981 refactor: remove redundant proxy query paths (#5928) 2026-07-31 08:52:22 +08:00
SaladDay 3c1154bed9 refactor: remove superseded dead code (#5916) 2026-07-30 22:32:10 +08:00
SaladDay 7a7d41c873 fix(subscription): display Codex free-plan 30-day quota window (#3651) (#4886)
* fix(subscription): display Codex free-plan 30-day quota window (#3651)

Codex free accounts are metered on a rolling 30-day secondary window
(limit_window_seconds = 2,592,000) instead of the weekly window used by
paid plans. The backend already maps this correctly to the tier name
"30_day", but the frontend TIER_I18N_KEYS whitelist had no entry for it,
so SubscriptionQuotaView filtered the tier out. When that was the only
surviving tier (as happens for free accounts), the whole quota footer
rendered nothing — free accounts showed no remaining quota or reset time
while paid accounts worked.

- Add "30_day" -> subscription.thirtyDay to TIER_I18N_KEYS
- Add the thirtyDay label to all four locales (zh/en/ja/zh-TW)
- Add a unit test locking in window_seconds_to_tier_name mappings,
  including the 30-day case

Fixes #3651

* fix(tray): render Codex free-plan 30-day window in tray menu

The tray keeps its own tier-name whitelist (TIER_LABEL_GROUPS) independent
of the frontend TIER_I18N_KEYS. Its month group only listed "monthly", so a
free Codex account whose only tier is "30_day" produced empty labeled parts
→ format_subscription_summary returned None → the tray showed no quota, even
though the footer now does. That breaks the invariant the existing
gemini_summary_lite_only_still_renders test guards: any tier visible in the
footer must not leave the tray blank.

- Add TIER_THIRTY_DAY ("30_day") constant so the string is single-sourced
  across backend mapping, tray grouping, and the frontend whitelist
- Map 2_592_000s explicitly to it in window_seconds_to_tier_name
- Add TIER_THIRTY_DAY to the tray month ("m") group
- Add codex_summary_thirty_day_only_still_renders regression test

Follow-up to the review on #3651 / PR for the 30-day footer fix.
2026-07-05 22:54:20 +08:00
SaladDay 586fb46b10 fix(usage): keep date-range picker calendar on-screen in narrow popovers (#4860)
The custom date-range picker switched to its two-column layout (date
fields | calendar) based on the viewport width via Tailwind `sm:`
(640px). But the popover is clamped to `100vw - 2rem` and anchored to
its trigger with `align="end"`, so its actual available width is not the
viewport width. On narrow windows the wide two-column layout could
activate while the popover only had room for one column, pushing the
calendar column off the right edge of the window where it was clipped
and unusable (month header and 4 of 7 weekday columns cut off).

Gate the two-column layout on the popover's own inline size via a CSS
container query instead of the viewport, and let the popover width
shrink to fit the viewport. When the popover is genuinely wide it shows
two columns; when it is clamped narrow it stacks vertically so the
calendar stays fully visible. The base stacked layout is the safe
fallback for engines without container-query support.

Closes #4669
2026-07-01 16:33:07 +08:00
SaladDay edeee25fae feat(db): in-app recovery screen with upgrade button when DB version is too new (#4575)
* feat(db): in-app recovery screen with upgrade button when DB version is too new

When the SQLite user_version is newer than the app supports (SCHEMA_VERSION),
Database::init() fails and previously dead-ended in a native Retry/Exit dialog
(Retry just fails again). The app now boots a dedicated recovery screen instead.

- Detect the recoverable "version too new" case and surface it via init_status
  (kind="db_version_too_new" + db_version/supported_version); force-show the main
  window and skip normal AppState boot (recovery commands need only AppHandle).
- The recovery screen first checks for an available update:
  - update available  -> "Upgrade app" runs the updater (download + install +
    restart) with a download progress bar.
  - no update (already latest) -> warns that the DB is too new even for the latest
    build (likely a third-party client), so upgrading cannot help.
- install_update_and_restart now emits `update-download-progress` events; new
  `check_app_update_available` command.
- i18n: en / ja / zh / zh-TW.

Verified: pnpm typecheck + format:check + test:unit (351) green; cross-model
review of Rust correctness and recovery-mode safety (no AppState panic).

* fix(db): pre-check too-new DB before schema writes; exit on close in recovery mode

Addresses review feedback on the too-new-DB recovery flow.

- P1: stored_user_version_exceeds_supported() is now checked BEFORE
  Database::init(), so create_tables()'s DDL (incl. the unconditional
  DROP INDEX/DROP TABLE IF EXISTS failover_queue) never runs against a
  database whose user_version we cannot understand. The earlier
  post-init-failure recovery branch is removed; the pre-check is the
  single authoritative guard, so "don't write to a DB we can't read"
  now holds from the very first DB access.

- P2: the window CloseRequested handler now detects recovery mode
  (init_error kind = db_version_too_new) and exits the app instead of
  honoring minimize_to_tray_on_close. Recovery mode returns before the
  tray is created, so hiding the window would leave the app running with
  no tray to bring it back; native-close now quits cleanly.

Verified: cargo fmt --check clean; cross-model Rust review of both fixes
(compile-correctness + no normal-startup/close regression).
2026-06-24 15:07:42 +08:00