feat: add Cursor account and resizable floating quota support - #139
Open
QinShushu1 wants to merge 1 commit into
Open
feat: add Cursor account and resizable floating quota support#139QinShushu1 wants to merge 1 commit into
QinShushu1 wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
🔵 Needs a closer look
It introduces a new provider auth/session integration plus UI/window behavior changes that warrant careful human review (and there are a few reliability/perf issues to address).
Pull request overview
Adds an unofficial Cursor provider integration alongside Codex accounts, and extends the existing tray popup into a draggable, natively resizable “floating panel” controlled by persisted app settings.
Changes:
- Introduces Cursor desktop account detection + quota fetching (read-only local session DB + Cursor endpoints).
- Adds floating panel settings (pin behavior, visible account filtering, optional reset-time display) and wires them into the main UI + tray UI.
- Makes the tray window resizable and keeps it visible on blur when “floating” is enabled.
File summaries
| File | Description |
|---|---|
| src/types/index.ts | Adds shared frontend types for Cursor account info and persisted app settings. |
| src/TrayMenu.tsx | Displays Cursor as an additional “account”, supports floating panel filtering and reset-time display, adds drag region. |
| src/components/AddAccountModal.tsx | Adds a Cursor Login tab and supports cancel/complete flows for Cursor sign-in detection. |
| src/App.tsx | Adds Floating Panel settings UI and hooks for Cursor login + settings persistence. |
| src-tauri/src/web.rs | Exposes Cursor commands + app settings getter for the web invoke router. |
| src-tauri/src/types.rs | Extends settings with floating panel options; adds CursorAccountInfo type. |
| src-tauri/src/tray.rs | Makes tray window resizable and changes blur/toggle behavior based on floating setting. |
| src-tauri/src/lib.rs | Registers new Cursor + settings-related Tauri commands. |
| src-tauri/src/commands/window.rs | Implements get_app_settings and set_floating_panel_settings commands. |
| src-tauri/src/commands/mod.rs | Adds the new cursor command module export. |
| src-tauri/src/commands/cursor.rs | Implements Cursor session reading, login wait/cancel, and usage fetching/mapping. |
| src-tauri/src/auth/mod.rs | Formatting-only change to the auth lock declaration. |
| src-tauri/Cargo.toml | Adds rusqlite dependency (bundled SQLite) for Cursor session DB reads. |
| src-tauri/Cargo.lock | Locks new rusqlite-related transitive dependencies. |
| README.md | Documents the unofficial Cursor integration and AI-assisted development disclosure. |
Review details
Suppressed comments (1)
src/TrayMenu.tsx:285
- Same as initial load: a failure in
get_app_settingscurrently aborts manual refresh and leaves the tray in an error state even if accounts/usage are otherwise available. Make settings load non-fatal during refresh as well.
const [list, cursor, settings] = await Promise.all([
invokeBackend<AccountInfo[]>("list_accounts"),
invokeBackend<CursorAccountInfo | null>("cursor_account").catch(() => null),
invokeBackend<AppSettings>("get_app_settings"),
]);
- Files reviewed: 14/15 changed files
- Comments generated: 6
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+276
to
+283
| const loadProviderSettings = useCallback(async () => { | ||
| const [settings, cursor] = await Promise.all([ | ||
| invokeBackend<AppSettings>("get_app_settings"), | ||
| invokeBackend<CursorAccountInfo | null>("cursor_account").catch(() => null), | ||
| ]); | ||
| setFloatingSettings(settings); | ||
| setCursorAccount(cursor); | ||
| }, []); |
Comment on lines
+1586
to
+1602
| <button | ||
| onClick={() => { | ||
| setIsNavMenuOpen(false); | ||
| setIsTimedWarmupOpen(false); | ||
| setIsFloatingSettingsOpen((prev) => !prev); | ||
| }} | ||
| className="flex w-full items-center justify-between gap-2 rounded-lg px-3 py-2 text-left text-sm transition-colors hover:bg-gray-100 dark:text-white dark:hover:bg-neutral-900" | ||
| > | ||
| <span>Floating Panel</span> | ||
| <span className={`rounded-md px-1.5 py-0.5 text-[11px] font-medium ${ | ||
| floatingSettings?.floating_panel_enabled | ||
| ? "bg-emerald-50 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-300" | ||
| : "bg-gray-100 text-gray-500 dark:bg-gray-800 dark:text-gray-400" | ||
| }`}> | ||
| {floatingSettings?.floating_panel_enabled ? "On" : "Off"} | ||
| </span> | ||
| </button> |
Comment on lines
+237
to
+241
| const [list, cursor, settings] = await Promise.all([ | ||
| invokeBackend<AccountInfo[]>("list_accounts"), | ||
| invokeBackend<CursorAccountInfo | null>("cursor_account").catch(() => null), | ||
| invokeBackend<AppSettings>("get_app_settings"), | ||
| ]); |
Comment on lines
126
to
+130
| window.on_window_event(move |event| { | ||
| if let WindowEvent::Focused(false) = event { | ||
| if let Some(window) = app_handle.get_webview_window(TRAY_WINDOW) { | ||
| let _ = window.hide(); | ||
| let pinned = crate::auth::load_app_settings() | ||
| .map(|settings| settings.floating_panel_enabled) | ||
| .unwrap_or(false); |
Comment on lines
+44
to
+46
| if let Ok(account) = fetch_cursor_account().await { | ||
| return Ok(account); | ||
| } |
Comment on lines
+378
to
380
| const handleSwitch = useCallback(async (account: TrayAccount) => { | ||
| if (account.provider === "cursor") return; | ||
| if (account.is_active) { |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Disclaimer
This is an unofficial community contribution. It is not affiliated with, endorsed by, or supported by the original Codex Switcher maintainers, OpenAI, or Cursor. The Cursor integration is intended only for accounts owned by the user and must be used in accordance with each provider's terms. It opens the official Cursor application for sign-in, reads Cursor's local session database in read-only mode, sends the short-lived session only to Cursor-owned endpoints, and does not persist Cursor passwords or access tokens.
The upstream repository currently declares no software license. This fork and pull request are provided only for upstream review through GitHub's fork and pull-request workflow. They do not claim or grant independent permission to redistribute the upstream source or compiled binaries. No binary release has been published from this fork.
AI-Assisted Development Disclosure
The Cursor integration in this fork was primarily implemented by OpenAI's GPT-5.6 SOL. Human maintainers provide the product requirements, scope decisions, review, and final acceptance.
Summary
apiPercentUsedto Third-party models andautoPercentUsedto First-party modelsPrivacy Review
Verification
cargo fmt --check: passedgit diff --check: passedThe local Windows installers are unsigned and were used only for verification; they have not been attached to this PR or published as a release.