Repository navigation
[WRONG BRANCH] release: promote 2.74.0-preview.20260930 to preview #6318
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
a30e67f
chore(release): open dev at 2.74.0 before releasing 2.73.0 (#6267)
github-actions[bot] 11782ee
fix(release): sign the packaged macOS keyring addons before notarizat…
lidge-jun d4480b7
ci: run the Linux package E2E on pull requests only for packaging inp…
lidge-jun 1b97c6f
test: isolate server admission lifecycle and synchronize quota switch…
lidge-jun fdf4177
test: stabilize Windows catalog, picker, and log-guard fixtures (#6277)
lidge-jun 7904af5
fix(codex): support autostart shims from standalone ocx (#6284)
lidge-jun f69918c
fix(codex): retire main short lock on explicit absent primary (#6287)
lidge-jun e570586
fix: packaged macOS startup probes and desktop ownership safety (#6286)
lidge-jun db6e266
fix(kiro): display one final answer across completion retry (#6283)
lidge-jun 6538001
fix(catalog): discover new native models from the live Codex roster a…
lidge-jun 6944cc3
fix(desktop): open dashboard links in the default browser (#6303)
lidge-jun 2405624
feat(minimax): add MiniMax-M3.1-Flash-Preview with its always-on thin…
lidge-jun cda8ff4
test: keep the suite runnable from Codex-managed worktrees and beside…
lidge-jun 961a4b5
fix(oauth): report browser launch failures and harden device login UX…
lidge-jun 04731c1
fix(xai): one Grok 4.7 row; OAuth Fast uses the faster build-fast lan…
lidge-jun 26acb40
feat(codex): show Codex credits under the Week bar behind a Codex Aut…
lidge-jun 3008bae
chore(release): open dev at 2.75.0 before releasing 2.74.0 (#6317)
github-actions[bot] 592c5cf
test: budget reserve catalog lifecycle children for cold Windows runn…
lidge-jun db00c37
Merge preview into 2.74.0-preview.20260930 promotion
lidge-jun de32f1c
chore(release): 2.74.0-preview.20260930
lidge-jun File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| # 260930 desktop external links — plan | ||
|
|
||
| ## Conclusion | ||
|
|
||
| Links the loopback dashboard asks to open in a new window (OAuth "didn't open?" fallback, | ||
| device-code verification links, `window.open`) now leave the desktop app through one Rust | ||
| handler that hands http/https URLs to the OS default browser. Nothing new is granted over IPC. | ||
|
|
||
| ## Problem | ||
|
|
||
| User report: pressing a login button in the desktop app often does not open the default browser. | ||
|
|
||
| Two read-only gpt-6.1-sol lanes and direct reads of the pinned crates (tauri 2.11.6, wry 0.55.1, | ||
| tauri-plugin-opener 2.5.3) agree: | ||
|
|
||
| 1. The server-side launch (`/api/oauth/login` -> `openUrl`) is intact for browser flows, but its | ||
| result is discarded, and device-code flows (Copilot, Kimi, Nous, Meta Muse, Kiro, Codex device) | ||
| never launch server-side by design. Both depend on the GUI's `target="_blank"` link. | ||
| 2. `tauri_plugin_opener::init()` injects a click listener that `preventDefault()`s every `_blank` | ||
| click and invokes `plugin:opener|open_url`. The dashboard is the remote origin | ||
| `http://127.0.0.1:*`; its capabilities (`dashboard-titlebar.json`, `dashboard-zoom.json`) grant | ||
| no opener permission, so the IPC is denied after the click was already cancelled: nothing opens. | ||
| 3. No webview installs `on_new_window`. Without it wry drops `window.open` on WebView2 | ||
| (`SetHandled(true)`) and WebKitGTK (no `create` handler); WKWebView only reaches the browser | ||
| because its navigation policy sees the URL first. | ||
|
|
||
| ## Options considered | ||
|
|
||
| - A. Grant `opener:allow-open-url` to the remote dashboard origin. Fixes anchors only, leaves | ||
| `window.open` broken on Windows/Linux, and widens the IPC surface of a remote origin. | ||
| - B (chosen). Disable the plugin's JS interceptor (`open_js_links_on_click(false)`) and install an | ||
| `on_new_window` handler on the main window and the tray popup that opens http/https in the default | ||
| browser and returns `NewWindowResponse::Deny`. One decision point in Rust, no new grant, covers | ||
| both anchors and `window.open` on all three platforms. | ||
|
|
||
| ## Diff-level plan | ||
|
|
||
| - `desktop/src-tauri/src/window.rs`: extract `opens_in_default_browser(&Url)` (http/https only) | ||
| and `open_in_default_browser`; reuse it in `navigation_allowed`; add | ||
| `open_new_windows_in_default_browser<R>()` returning the handler; unit test for the scheme filter. | ||
| - `desktop/src-tauri/src/lib.rs`: build the opener plugin with `open_js_links_on_click(false)`; | ||
| add `.on_new_window(...)` to the main window builder. | ||
| - `desktop/src-tauri/src/popup.rs`: add `.on_new_window(...)` to the tray popup builder, and open | ||
| external http/https URLs in `popup_navigation_allowed` before refusing them. Audit round 1 (FAIL) | ||
| found that WKWebView consults this policy before it would create a window for a `_blank` link, so | ||
| a refusal without opening kept the popup's external links dead on macOS; round 2 passed. | ||
|
|
||
| Bundled pages (`desktop/ui`) contain no `_blank` anchors or opener calls, so disabling the | ||
| interceptor removes nothing they relied on. `mailto:`/`tel:` were never reachable from the | ||
| dashboard (same denied IPC) and stay out of the external-open filter. | ||
|
|
||
| ## Verification | ||
|
|
||
| Same steps as the CI `desktop` job: placeholder sidecar and resource files (gitignored), then | ||
| `cargo fmt --check`, `cargo clippy --all-targets -D warnings`, `cargo test` for | ||
| `desktop/src-tauri`. Exact-head PR CI is the merge gate. A packaged-app click test is not | ||
| available locally; the behavior claim rests on the pinned wry/opener sources cited above. | ||
|
|
||
| ## Outcome | ||
|
|
||
| Implemented as planned plus the audit fold in `popup.rs`. Local proof on macOS arm64: | ||
| `cargo fmt --check`, `cargo clippy --all-targets -D warnings` and `cargo test` (190 passed, | ||
| including `only_web_addresses_are_handed_to_the_default_browser`) exit 0; the desktop, | ||
| release-contract and repo-hygiene Bun suites (24 files, 334 pass, 2 platform skips), | ||
| `privacy:scan` and `structure:check` pass. Windows and Linux behavior is source-reviewed | ||
| against wry 0.55.1 and covered by the hosted desktop CI job, not by a packaged click test. | ||
|
|
||
| What this does not change: server-side `openUrl` still discards its launch result, and | ||
| device-code logins still do not auto-open a browser; both remain separate follow-ups. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| # 000 — Codex credits balance on Codex Set account cards | ||
|
|
||
| ## Objective | ||
|
|
||
| Show each Codex login's credits balance ("Credits remaining 62,500" on chatgpt.com Codex | ||
| usage settings) as a compact row directly under the existing Week quota row on the | ||
| Codex Set → Multi-auth main card and every pool card, behind one persisted page-wide | ||
| switch, the way the retired Codex Spark quota switch worked (#2649, bf73afee50). | ||
|
|
||
| Scope change recorded 2026-09-30: the GPT-5.5 retirement originally bundled with this | ||
| unit was removed by the owner ("5.5는 내가 나중에 패치할께 그냥 크레딧만 진행"). For | ||
| that later patch: the live `/backend-api/codex/models?client_version=0.170.0` roster still | ||
| lists `gpt-5.5` with `visibility: list` and | ||
| `upgrade: { model: "gpt-5.6-sol", retirement_at: "2026-10-14T19:00:00Z" }`. | ||
|
|
||
| ## Evidence (000-range research) | ||
|
|
||
| - `GET https://chatgpt.com/backend-api/wham/usage` (Bearer Codex access token + | ||
| `ChatGPT-Account-Id`) returns top-level keys `account_id, additional_rate_limits, | ||
| chatpass, code_review_rate_limit, credits, email, model_usage, plan_type, promo, | ||
| rate_limit, rate_limit_reached_type, rate_limit_reset_credits, spend_control, user_id`. | ||
| Probed 2026-09-30 with the main login; only key names and value types were printed. | ||
| - `credits` = `{ has_credits: boolean, unlimited: boolean, overage_limit_reached: boolean, | ||
| balance: string, approx_local_messages: [number, number], approx_cloud_messages: | ||
| [number, number] }`. `balance` is a decimal STRING and is fractional on pool accounts | ||
| (e.g. "62498.725", "62479.806261"). | ||
| - The official Codex usage page (read through Aside, chatgpt.com/codex/cloud/settings/usage) | ||
| renders "Credits remaining 62,500 — Credits extend usage beyond your plan limits." as a | ||
| plain number with no bar and no denominator. | ||
| - opencodex already fetches this exact response: main in | ||
| `src/codex/auth-api/main-account-probe.ts` (`fetchMainAccountInfoWhileOwned`, publish block | ||
| after `credentialIsCurrent()`), pool in `src/codex/auth-api/pool-quota-probe.ts` | ||
| (`publishPoolQuotaResponse`-style block that parses `WhamUsageResponse`). The response's | ||
| `credits` object is currently ignored. | ||
| - The closest analogue is `rate_limit_reset_credits.available_count`: main keeps it | ||
| memory-only and bound to the physical ChatGPT account id | ||
| (`rememberMainResetCredits` / `mainResetCreditsForCurrentIdentity`) because the | ||
| `__main__` alias can change identity while the proxy is down. | ||
|
|
||
| ## Decisions | ||
|
|
||
| - D1 Storage: new sibling module `src/codex/credits.ts` with a process-local map | ||
| keyed by opencodex account id (`__main__` or pool id) and tagged with the identity it | ||
| was read from. Never persisted, never logged, never folded into `StoredAccountQuota` | ||
| (quota participates in routing, recovery and persistence; credits are display only). | ||
| No TTL: the row shows the last observation for the same identity, like reset credits. | ||
| Explicit `credits: null` clears; an absent field keeps the previous observation. | ||
| - D2 Exposure: optional `credits` on `CodexAuthAccountDto`, emitted only when | ||
| `config.showCodexCredits === true`. `/api/provider-quotas` stays unchanged (its | ||
| projection is an allowlist). The switch controls exposure only, not probing. | ||
| - D3 Switch: `showCodexCredits?: boolean`, default off (absent = off), following the | ||
| Spark precedent and the `oauthOpenBrowser` settings chain (type, zod degrade-not-reject | ||
| schema, diagnostics, GET/PUT `/api/settings` with validate-mutate-persist-rollback). | ||
| Toggle sits in the Codex Auth page head beside Pause exhausted / Refresh quotas. | ||
| - D4 Row: same `.quota-row` grid as Week: label "Credits", reset columns reused for | ||
| "remaining", a bar, and the formatted balance in the value column. There is no | ||
| denominator, so the bar is a STATUS bar, not a percentage: full (ok tone) when a | ||
| positive balance or `unlimited`; empty when the balance is zero or | ||
| `overage_limit_reached`. Value column: locale-formatted balance (max 2 fraction | ||
| digits), "Unlimited", or balance plus "· Overage limit reached". The title tooltip | ||
| carries the approx local/cloud message ranges. No `%`, no `role=progressbar`. | ||
| Architect D5 proposed a number-only row; the owner explicitly asked for "비슷한 바" | ||
| (a bar like the Week one), so the status bar is kept and documented. | ||
|
|
||
| ## Work-phase map (dependency order) | ||
|
|
||
| | Work-phase | Doc | Delivers | | ||
| |---|---|---| | ||
| | wp0 | 000 (this), 010, 020 | Locked roadmap | | ||
| | wp2 | 010_phase1_credits_implementation.md | Parser + store + DTO + setting + GUI row + toggle + tests + docs | | ||
| | wp3 | 020_phase2_pr_ci_merge.md | PR from template with screenshot, exact-head CI, merge into `dev` | | ||
|
|
||
| ## Constraints | ||
|
|
||
| - File-size ratchet: `gui/src/styles.css` has one line of headroom → new CSS lives in a | ||
| new stylesheet. Keep additions in the large files minimal; put logic in siblings. | ||
| - New test files must be registered in `scripts/test-layout/layout.json` `explicit` and | ||
| `tests/fixtures/test-layout-expected.json`. | ||
| - i18n: every key lands in all ten locales (en, ko, ja, zh, zh-TW, de, fr, ru, tr, vi). | ||
| - Privacy: never log WHAM bodies, balances, tokens, or account ids. | ||
| - SoT sync: `structure/providers/openai-accounts.md` (credits projection) and | ||
| `structure/config.md` (new setting) if they enumerate settings/DTO fields; | ||
| `bun run structure:check` must pass. | ||
|
|
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Handle browser-launch failures.
open_urlreturns aResult, but Line 70 discards it. The pinned opener API explicitly exposes launch errors. (docs.rs)If the system browser launcher fails, the new-window handler still returns
NewWindowResponse::Deny. The popup navigation handler also rejects navigation. The requested page then opens nowhere, and this helper provides no failure indication.Handle
Errand report a fixed, URL-free diagnostic through the existing desktop logging mechanism. Do not log the authorization URL or an unchecked error string, because either can contain login parameters.Based on learnings: “In Rust, do not discard Result values with patterns like
let _ = fallible_call();.”🤖 Prompt for AI Agents
Source: Learnings