Skip to content

Header Usage popup + Cursor Admin API + ADE CLI usage commands#276

Merged
arul28 merged 8 commits into
mainfrom
ade/usage-bar-93b136f0
May 10, 2026
Merged

Header Usage popup + Cursor Admin API + ADE CLI usage commands#276
arul28 merged 8 commits into
mainfrom
ade/usage-bar-93b136f0

Conversation

@arul28
Copy link
Copy Markdown
Owner

@arul28 arul28 commented May 10, 2026

Summary

Describe the change.

What Changed

Key files and behaviors.

Validation

How you tested.

Risks

Anything to watch.


Note

Medium Risk
Medium risk because it introduces new network polling/auth-key handling (Cursor Admin API) and changes the main UX entrypoint for usage/guardrails; incorrect key detection or spend polling (including single-page results) could misreport usage/budgets.

Overview
Moves usage + guardrails UI out of Settings into the header. Adds a new top-bar popup (HeaderUsageControlUsageQuotaPanel) that shows live provider quota windows, refresh, warnings, and a collapsible Automation guardrails editor (BudgetCapEditor); removes the Settings Usage tab and related command-palette/navigation copy.

Extends live usage tracking to Cursor and makes pacing provider-aware. usageTrackingService now polls Cursor team spend via the Admin API (Basic auth from CURSOR_ADMIN_API_KEY or admin-shaped keys), normalizes it into a monthly window + ExtraUsage, and computes both legacy aggregate pacing plus pacingByProvider; shared usage types add cursor, monthly, windowDurationMs, and pacingByProvider.

Adds a typed ade usage CLI surface. New usage snapshot|refresh|budget get|set|check|cumulative commands (with quota/quotas aliases) route to service actions and validate budget JSON inputs; docs and tests updated accordingly, and Cursor connection status now distinguishes runtime vs usage availability based on Admin API key shape.

Reviewed by Cursor Bugbot for commit 5248237. Configure here.

Summary by CodeRabbit

  • New Features

    • New ade usage CLI: snapshot, refresh, and budget management (get/set/check/cumulative)
    • Live usage gauge in the header with a detailed Usage panel and an Automation Guardrails budget editor
    • Per-provider pacing and monthly quota windows, including Cursor provider support
  • Improvements

    • Usage UI moved out of Settings into the header popup for quicker access
    • Updated Settings and Command Palette navigation to match the new layout

Review Change Stack

Greptile Summary

This PR adds a top-bar HeaderUsageControl / UsageQuotaPanel component that consolidates live provider quotas and automation guardrails, removes the dedicated Settings "Usage" tab, and extends usageTrackingService to poll Cursor team spend via the Admin API. It also adds ade usage CLI routes for snapshot, refresh, and budget get/set/check/cumulative.

  • Cursor Admin API polling: parseCursorSpendUsage aggregates team-member spend/limit cents into a monthly UsageWindow and optional ExtraUsage, with pacing computed in a new calculatePacingByProvider helper that produces per-provider UsagePacing alongside the existing aggregate.
  • Provider connection status refactor: usageAvailable for Cursor is now driven by isCursorAdminApiKey detection rather than runtime readiness, allowing usage-only admin keys to coexist with absent SDK keys.
  • CLI & UI wiring: buildUsagePlan correctly sequences firstPositional calls for the budget sub-command; UsageMeter now renders cumulative tick marks, fixing the prior non-cumulative position bug.

Confidence Score: 4/5

Safe to merge for most teams; Cursor spend data will be silently under-counted for teams exceeding 100 members, and the admin key detection relies on a prefix heuristic that could misfire.

The core polling, pacing, and UI wiring are well-tested and logically sound. The single-page Cursor Admin API fetch means displayed spend and pacing status are under-reported for large Cursor teams with no error surfaced. The "key_" admin-key heuristic is wide open and could misclassify keys. Both issues are contained to the new Cursor usage path and do not affect Claude or Codex behavior.

apps/desktop/src/main/services/usage/usageTrackingService.ts — Cursor spend fetch lacks pagination; apps/desktop/src/main/services/ai/utils.ts — admin key heuristic.

Important Files Changed

Filename Overview
apps/desktop/src/main/services/usage/usageTrackingService.ts Adds Cursor Admin API polling, per-provider pacing, and a refactored stageForDelta with tighter symmetric thresholds (±2% on-track, was ±4%). No pagination loop (>100 members under-counted).
apps/desktop/src/main/services/ai/providerConnectionStatus.ts Decouples Cursor usageAvailable from runtimeAvailable using isCursorAdminApiKey; blocker copy is context-sensitive for admin-only keys.
apps/desktop/src/main/services/ai/utils.ts Adds isCursorAdminApiKey helper using a startsWith("key_") heuristic; correct but fragile if Cursor reuses the prefix for non-admin keys.
apps/desktop/src/renderer/components/usage/UsageQuotaPanel.tsx New panel with per-provider cards, AuthChip, ExtraUsageCard; subscription/loading logic is sound; nowMs timer ticks every 15s to keep reset countdowns live.
apps/desktop/src/renderer/components/usage/HeaderUsageControl.tsx Gauge button with popup; correctly unsubscribes onUpdate when panel opens (panel takes over), re-subscribes on close.
apps/desktop/src/renderer/components/settings/UsageMeter.tsx Replaces stacked bar with solid fill + cumulative tick marks; toneColor prop added; ARIA progressbar attributes added.
apps/ade-cli/src/cli.ts Adds buildUsagePlan with budget sub-command routing; firstPositional mutates args in sequence correctly; quota/quotas aliases wired.
apps/desktop/src/shared/types/usage.ts Adds cursor to UsageProvider, monthly to UsageWindowType, windowDurationMs to UsageWindow, and optional pacingByProvider to UsageSnapshot; all backward-compatible.

Sequence Diagram

sequenceDiagram
    participant R as Renderer (UsageQuotaPanel)
    participant B as IPC Bridge
    participant S as usageTrackingService (main)
    participant CA as Claude API
    participant CO as Codex API
    participant CU as Cursor Admin API

    R->>B: getSnapshot()
    B->>S: getSnapshot()
    S-->>B: UsageSnapshot (cached)
    B-->>R: UsageSnapshot

    R->>B: refresh()
    B->>S: forceRefresh()
    S->>CA: GET /api/oauth/usage (OAuth token)
    S->>CO: GET /wham/usage (JWT)
    S->>CU: "POST /teams/spend (Basic key_*)"
    CA-->>S: windows[]
    CO-->>S: windows[]
    CU-->>S: teamMemberSpend[]
    S->>S: parseCursorSpendUsage() / calculatePacingByProvider()
    S-->>B: updated UsageSnapshot
    B-->>R: UsageSnapshot
    B->>R: onUpdate(snapshot) [push]
Loading

Comments Outside Diff (1)

  1. apps/desktop/src/main/services/usage/usageTrackingService.ts, line 784-822 (link)

    P1 No pagination loop in Cursor team spend fetch

    pollCursorUsage sends a single POST with { pageSize: 100 } and stops there. If the Cursor team has more than 100 members, the response contains only the first page, so totalSpendCents and totalLimitCents are each under-counted by all remaining members. The resulting percentUsed, pacing status, and ExtraUsage dollar figures will be systematically lower than the real values, and the UI will silently show the wrong numbers with no error or warning.

    A pagination loop is needed: keep fetching additional pages (passing the returned cursor/offset token) until all members have been included, or at minimum expose a hard upper bound and emit an error/warning when it's hit.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/desktop/src/main/services/usage/usageTrackingService.ts
    Line: 784-822
    
    Comment:
    **No pagination loop in Cursor team spend fetch**
    
    `pollCursorUsage` sends a single POST with `{ pageSize: 100 }` and stops there. If the Cursor team has more than 100 members, the response contains only the first page, so `totalSpendCents` and `totalLimitCents` are each under-counted by all remaining members. The resulting `percentUsed`, pacing status, and `ExtraUsage` dollar figures will be systematically lower than the real values, and the UI will silently show the wrong numbers with no error or warning.
    
    A pagination loop is needed: keep fetching additional pages (passing the returned cursor/offset token) until all members have been included, or at minimum expose a hard upper bound and emit an error/warning when it's hit.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Fix in Claude Code

Fix All in Claude Code

Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 3
apps/desktop/src/main/services/ai/utils.ts:16-18
The `"key_"` prefix is a broad heuristic shared by many API key providers. If Cursor ever issues SDK keys with the same prefix (or if users paste a third-party key starting with `"key_"`), the key is silently classified as a Cursor Admin key, triggering the Admin API path in `getCursorApiKey` and affecting `usageAvailable` in connection status. Consider anchoring to a more specific prefix (e.g. `"key_cursor"`) or documenting the exact format expected, so the intent is clear and can be updated when Cursor changes their key schema.

```suggestion
// Cursor Admin API keys use the "key_" prefix per the Cursor dashboard docs.
// If Cursor ever changes this scheme, update the prefix here and in tests.
export function isCursorAdminApiKey(value: string | null | undefined): boolean {
  return Boolean(value?.trim().startsWith("key_"));
}
```

### Issue 2 of 3
apps/desktop/src/main/services/usage/usageTrackingService.ts:904-916
**Pacing on-track band silently narrowed from ±4 % to ±2 %**

The old thresholds were `|delta| ≤ 4 % → on-track`; the new `stageForDelta` tightens that to `|delta| ≤ 2 %`. Any consumer that branches on `status === "on-track"` (automation guardrail checks, badge rendering) will now fire "slightly-ahead/behind" at deltas of 2–4 % that previously showed "on-track". The tests were updated to match, so this is likely intentional — but it's worth confirming the guardrail budget-enforcement code was audited for the new sensitivity.

### Issue 3 of 3
apps/desktop/src/main/services/usage/usageTrackingService.ts:328-343
**`resetsAt` is empty string when `subscriptionCycleStart` is absent, but the usage window is still emitted**

When the Cursor API omits `subscriptionCycleStart`, `resetsAt` is `""` and `resetsInMs` resolves to `0`. The window is still pushed to `windows[]` (provided `utilization != null`). In the renderer, `displayPercent` short-circuits to `0` whenever `resetsInMs <= 0`, so the progress bar shows 0% even though `percentUsed` could be 15–80 %. The `ExtraUsageCard` is unaffected (it uses raw USD values), but the `UsageMeter` in `ProviderUsageCard` would silently display no progress.

Reviews (7): Last reviewed commit: "ship: iteration 6 preserve cursor usage ..." | Re-trigger Greptile

@vercel
Copy link
Copy Markdown

vercel Bot commented May 10, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
ade Ignored Ignored Preview May 10, 2026 4:26pm

@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented May 10, 2026

@cursor review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 10, 2026

📝 Walkthrough

Walkthrough

Adds Cursor provider usage polling and monthly windows, refactors pacing into a window-based per-provider engine, moves usage UI from Settings into a header gauge and modal UsageQuotaPanel with budget editing, updates Cursor credential detection, and adds an ade usage CLI surface with tests and README examples.

Changes

Cursor Usage Tracking and Header UI Migration

Layer / File(s) Summary
Type Contracts
apps/desktop/src/shared/types/usage.ts, apps/desktop/src/shared/types/config.ts
Extend UsageProvider with cursor; add monthly window type and windowDurationMs?; add UsagePacingByProvider and pacingByProvider to UsageSnapshot; add cursor-admin-env credential source.
CLI Usage Surface
apps/ade-cli/src/cli.ts, apps/ade-cli/src/cli.test.ts, apps/ade-cli/README.md
Add ade usage (aliases quota/quotas) with snapshot/refresh and nested budget subcommands; parse/validate JSON for budget set/update; add help text and tests; document examples in README.
Provider Connection Status
apps/desktop/src/main/services/ai/providerConnectionStatus.ts, apps/desktop/src/main/services/ai/utils.ts, tests
Detect Cursor admin-style API keys separately from SDK/runtime keys; derive cursorUsageAuth independently; add cursorCredsSource; refine blocker messages; add isCursorAdminApiKey helper and tests.
Fetch & Cursor Polling
apps/desktop/src/main/services/usage/usageTrackingService.ts
Generalize fetchJson support; add Cursor spend endpoint and pollCursorUsage that selects API key (admin/env/store), POSTs spend request, parses team spend into monthly UsageWindow and optional extraUsage, and returns errors.
Pacing Engine
apps/desktop/src/main/services/usage/usageTrackingService.ts
Refactor pacing into a window-based engine (select window, per-window projection/ETA/reset), add calculatePacingForWindow, and calculatePacingByProvider while preserving legacy calculatePacing.
Service Integration
apps/desktop/src/main/services/usage/usageTrackingService.ts
Expose optional pollCursorUsage dependency, include Cursor in concurrent polling aggregation, merge Cursor windows/errors/extraUsage into the UsageSnapshot, initialize emptyPacing and compute pacingByProvider.
Backend Tests
apps/desktop/src/main/services/usage/usageTrackingService.test.ts
Add unit tests for Cursor spend parsing and pollCursorUsage, extend _testing exports, and add integration tests validating per-provider pacing.
HeaderUsageControl
apps/desktop/src/renderer/components/usage/HeaderUsageControl.tsx
New header gauge control displaying usage percent and warning dot; polls snapshot and subscribes to updates; lazy-loads budget config on open; exposes saveBudget with saving/error state and opens UsageQuotaPanel modal.
UsageQuotaPanel
apps/desktop/src/renderer/components/usage/UsageQuotaPanel.tsx
New panel: displays per-provider quota windows with reset countdowns, pacing badges, AuthChip status, extra-usage cards, error banners, manual refresh, and a 15s timer.
UsageQuotaPanel Tests
apps/desktop/src/renderer/components/usage/UsageQuotaPanel.test.tsx
Migrate tests from Settings-based component; add richer mock snapshot and tests for percent display, refresh behavior, Cursor auth-only labeling, extra-usage handling, and auth-error UI.
UsageMeter Refactor
apps/desktop/src/renderer/components/settings/UsageMeter.tsx
Add optional toneColor prop; remove StackedBar; render a single filled bar with per-model tick overlays; update legend swatches and MODEL_COLORS.
Remove Old Usage Settings
apps/desktop/src/renderer/components/settings/SettingsUsageSection.tsx, apps/desktop/src/renderer/components/settings/UsageGuardrailsSection.tsx
Delete previous Settings-mounted usage UI modules and associated tests; functionality moved to header control and UsageQuotaPanel.
TopBar, Settings & Command Palette
apps/desktop/src/renderer/components/app/TopBar.tsx, apps/desktop/src/renderer/components/app/SettingsPage.tsx, apps/desktop/src/renderer/components/app/CommandPalette.tsx, apps/desktop/src/renderer/components/automations/components/RuleEditorPanel.tsx, apps/desktop/src/renderer/components/missions/MissionHeader.tsx
Render HeaderUsageControl in TopBar; remove usage tab from Settings sidebar and map legacy ?tab=usage to general; update CommandPalette entries and rule editor help text to reference header Usage popup → Automation guardrails; extend mission header meter to show Cursor monthly windows.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • arul28/ADE#118: Adds/modifies Cursor provider support across desktop (types, provider connection, usage tracking), directly related.
  • arul28/ADE#85: Overlaps providerConnectionStatus changes and runtime/auth override behavior.
  • arul28/ADE#229: Modifies Cursor provider connection and credential-source handling, overlapping with providerConnectionStatus changes.

Suggested labels

desktop

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the three major features added in this PR: the Header Usage popup, Cursor Admin API integration, and ADE CLI usage commands.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ade/usage-bar-93b136f0

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@capy-ai
Copy link
Copy Markdown

capy-ai Bot commented May 10, 2026

Capy auto-review is paused for this organization because the monthly auto-review limit has been reached. Increase the limit or turn it off in billing settings to resume automatic reviews.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
apps/desktop/src/renderer/components/app/SettingsPage.tsx (1)

31-45: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Preserve old ?tab=usage deep links.

Removing the section without an alias means existing /settings?tab=usage links now fall back to general, which is a confusing regression for bookmarks and stale in-app links. Add a usage alias to the closest surviving destination or a dedicated “moved to header usage popup” landing state.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/renderer/components/app/SettingsPage.tsx` around lines 31 -
45, The TAB_ALIASES mapping no longer preserves old ?tab=usage deep links;
update the TAB_ALIASES constant (used to map legacy query tabs to SectionId) to
include a "usage" key mapped to the closest surviving section (e.g., add
"usage": "general") so legacy /settings?tab=usage URLs continue to route
correctly; modify the TAB_ALIASES object to include this alias and ensure any
code that reads TAB_ALIASES (referencing TAB_ALIASES and SectionId) will pick up
the new mapping.
apps/desktop/src/main/services/ai/providerConnectionStatus.ts (2)

176-192: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use the same Cursor key validation here as the usage poller.

cursorEnvAuth and cursorStoredAuth currently accept any non-empty value, but pollCursorUsage() only treats SDK/store keys as usable when they match the key_ format. That lets this status surface report authAvailable/usageAvailable=true while the usage poller silently skips Cursor. Reuse one shared helper so status and polling agree.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/main/services/ai/providerConnectionStatus.ts` around lines
176 - 192, Replace the loose non-empty checks for Cursor keys in
providerConnectionStatus (cursorEnvAuth, cursorStoredAuth and the derived
cursorSdkAuth/cursorUsageAuth logic) with the same key-format validation used by
pollCursorUsage; import or extract the poller’s helper (e.g., isCursorKeyValid
or whatever validation function exists in pollCursorUsage) and use it to
validate process.env.CURSOR_API_KEY, getAllApiKeys().cursor, and
process.env.CURSOR_ADMIN_API_KEY before setting
cursorEnvAuth/cursorStoredAuth/cursorAdminEnvAuth and cursorCredsSource so the
status reporter and poller agree on which keys are actually usable.

215-238: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don't let runtime health disable admin-key usage polling.

usageAvailable is correctly derived from cursorUsageAuth, but the unconditional applyRuntimeHealth(cursor, cursorRuntimeHealth) call can still zero it out when the Cursor runtime is broken or missing an SDK key. That regresses the admin-key-only path this PR adds: usage polling works, but the UI will still say Cursor usage is unavailable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/main/services/ai/providerConnectionStatus.ts` around lines
215 - 238, The runtime-health decorator applyRuntimeHealth currently runs after
building cursor and can overwrite usageAvailable (breaking the admin-key-only
path); move or reassign usageAvailable so the final cursor.usageAvailable
reflects cursorUsageAuth regardless of runtime health — e.g., call
applyRuntimeHealth(cursor, cursorRuntimeHealth) first (or leave it as is) but
then set cursor.usageAvailable = cursorUsageAuth afterwards (or patch
applyRuntimeHealth to never modify usageAvailable). Update the code that
constructs cursor (symbols: cursor, usageAvailable, cursorUsageAuth,
applyRuntimeHealth, cursorRuntimeHealth, createUnavailableStatus) so
usageAvailable is preserved for the admin-key path.
🧹 Nitpick comments (3)
apps/ade-cli/README.md (1)

90-91: 💤 Low value

Consider documenting command aliases for discoverability.

The test file verifies that quota/quotas are aliases for usage snapshot and poll is an alias for usage refresh, but these aliases aren't mentioned in the README examples. Documenting them would improve discoverability for users.

📝 Example documentation enhancement
 ade usage snapshot --text
+ade quota snapshot --text  # alias
 ade usage refresh --text
+ade usage poll --text  # alias
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/ade-cli/README.md` around lines 90 - 91, Add documentation for the CLI
command aliases missing from the README: mention that the commands "quota" and
"quotas" are aliases for "ade usage snapshot" and that "poll" is an alias for
"ade usage refresh". Update the usage examples section (where "ade usage
snapshot --text" and "ade usage refresh --text" are shown) to include the
equivalent alias forms and a short note explaining these aliases for
discoverability, referencing the exact command names "usage snapshot", "usage
refresh", "quota"/"quotas", and "poll" so readers can find them easily.
apps/desktop/src/renderer/components/settings/UsageMeter.tsx (2)

102-102: Consider refactoring MODEL_COLORS to avoid redundancy with toneColor.

The first entry in MODEL_COLORS ("#A78BFA") duplicates the default toneColor. When breakdown rendering uses i === 0 ? toneColor : MODEL_COLORS[i % MODEL_COLORS.length], MODEL_COLORS[0] is only accessed when i = 4, 8, 12... due to modulo wrapping, creating subtle redundancy that can confuse maintainers.

♻️ Proposed refactor for clarity

Option 1: Remove the first color and start the palette from index 1:

-const MODEL_COLORS = ["#A78BFA", "#7C3AED", "#C4B5FD", "#6D28D9"];
+const MODEL_COLORS = ["#7C3AED", "#C4B5FD", "#6D28D9"];

Then adjust the cycling logic to use MODEL_COLORS[(i - 1) % MODEL_COLORS.length] for i > 0.

Option 2: Document the intentional duplication with a comment explaining that MODEL_COLORS[0] is used for the 5th+ model while toneColor is used for the 1st.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/renderer/components/settings/UsageMeter.tsx` at line 102,
MODEL_COLORS currently duplicates toneColor which is confusing; remove the first
entry ("#A78BFA") from MODEL_COLORS and update the color selection logic (the
ternary that currently reads i === 0 ? toneColor : MODEL_COLORS[i %
MODEL_COLORS.length]) to use MODEL_COLORS[(i - 1) % MODEL_COLORS.length] for i >
0 so the first color is always toneColor and subsequent models cycle the compact
palette; alternatively, if you prefer to keep the array as-is, add a clear
comment next to MODEL_COLORS explaining that MODEL_COLORS[0] intentionally
duplicates toneColor and is only used for the 5th+ model.

52-56: ⚡ Quick win

Consider using transform: scaleX() instead of animating width.

Animating the width property triggers layout reflow. Using transform: scaleX() with transform-origin: left would provide smoother animation performance, especially on lower-end devices.

⚡ Proposed performance optimization
 <div
-  className="absolute inset-y-0 left-0 transition-all duration-500 ease-out"
+  className="absolute inset-y-0 left-0 w-full origin-left transition-transform duration-500 ease-out"
   style={{
-    width: `${clamped}%`,
+    transform: `scaleX(${clamped / 100})`,
     background: fillColor,
   }}
 />
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/renderer/components/settings/UsageMeter.tsx` around lines 52
- 56, The progress bar currently animates width (the element with className
"absolute inset-y-0 left-0 ..." in UsageMeter.tsx); change it to keep a fixed
width (e.g., width: "100%") and animate using CSS transform: set style.transform
= `scaleX(${clamped / 100})` and style.transformOrigin = "left"; update the
transition to animate transform (e.g., transition: "transform 500ms ease-out")
and consider adding willChange: "transform" to improve performance on low-end
devices.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/ade-cli/README.md`:
- Line 95: Add a positive test in cli.test.ts that runs the CLI command string
"ade usage budget cumulative --scope global --text" (same form as in README) and
asserts it routes to the cumulative backend action; mock the CLI runner/backend
client used in existing usage tests (reuse the same test scaffolding as other
"ade usage" tests) and verify the mocked backend method for the cumulative
budget action is invoked with expected parameters and output formatting, rather
than only checking the error message path currently referenced in the test
suite.

In `@apps/ade-cli/src/cli.test.ts`:
- Around line 2726-2727: Add a positive unit test in
apps/ade-cli/src/cli.test.ts that mirrors the existing "get" and "check" tests
to verify the "usage budget cumulative" routing works: call buildCliPlan with
["usage","budget","cumulative"] and assert the returned plan matches the
expected handler/shape (the same kind of assertion used for the "get" and
"check" tests) so the CLI recognizes "cumulative" as a valid subcommand; locate
tests around other usage budget assertions near buildCliPlan to copy the
pattern.

In `@apps/ade-cli/src/cli.ts`:
- Line 4294: Add the "quota" and "quotas" aliases to the CLI help alias
resolution so "ade quota --help" / "ade help quota" resolve to the same handler
as "usage": update the help alias map (the structure where other aliases are
defined, e.g., HELP_ALIASES or helpAliases) to map "quota" and "quotas" to
"usage", and ensure the existing runtime check that uses the primary variable
and calls buildUsagePlan(...) already covers those values (or add them there if
missing).
- Around line 3675-3688: The current logic treats an empty/whitespace text
payload as absent and falls back to collectGenericObjectArgs, allowing an
implicit {} to be sent to budget.updateConfig; change the hasInlineBody handling
in the read/parse block so that if readFileTextInput(args) returns a non-null
value but text.trim().length === 0 you throw a CliUsageError (e.g., "Empty
budget config provided") instead of falling back, otherwise proceed to
JSON.parse(text) as before; update the branch around
readFileTextInput/hasInlineBody/JSON.parse and ensure budget.updateConfig
(actionStep("result","budget","updateConfig", ...)) only receives a parsed
non-empty JSON object.

In `@apps/desktop/src/main/services/cto/ctoStateService.ts`:
- Around line 194-195: The two-line help text is inconsistent: the first line
says usage/guardrails moved to the header usage popup but the second line still
instructs configuring automations in /settings; update the second string (the
automation guidance entry in the same array or constant in ctoStateService.ts)
to remove the `/settings` reference and instead direct users to the header usage
popup or to return a navigation suggestion when an action should open in ADE
(match the existing phrasing "When an action should be opened in ADE, return a
navigation suggestion. Never silently switch tabs."); ensure both strings
consistently mention the header usage popup and the navigation-suggestion
behavior.

In `@apps/desktop/src/main/services/usage/usageTrackingService.ts`:
- Around line 314-324: The comment incorrectly calls monthlyLimitDollars
"team-wide" while it's actually a per-member field on CursorSpendMember; update
the comment above memberLimitCents to describe monthlyLimitDollars as a
per-member default monthly limit (a per-member fallback used when
hardLimitOverrideDollars is not set) so it's clear each member's
monthlyLimitDollars is summed into totalLimitCents; reference memberLimitCents
and CursorSpendMember when updating the comment.

In `@apps/desktop/src/renderer/components/settings/UsageMeter.tsx`:
- Line 69: The background color selection causes collisions because the first
slice uses toneColor while others use MODEL_COLORS[i % MODEL_COLORS.length], so
when i >= MODEL_COLORS.length the colors repeat; update the logic in UsageMeter
(the background assignments that reference toneColor and MODEL_COLORS) to avoid
collisions by either using MODEL_COLORS[(i + 1) % MODEL_COLORS.length] for
non-zero i (skip the first MODEL_COLORS entry) or by always using MODEL_COLORS[i
% MODEL_COLORS.length] and synchronizing MODEL_COLORS[0] with toneColor, and
apply the same change to both places where background is set (the occurrences
around the current toneColor and the second usage at the other background
assignment).
- Around line 47-57: Wrap the visual meter with proper ARIA attributes so screen
readers can interpret it: in the UsageMeter component add a semantic progress
role and values to the element representing the filled bar (the div that uses
clamped and fillColor) — set role="progressbar", aria-valuemin={0},
aria-valuemax={100}, aria-valuenow={clamped} and include either
aria-label="Usage" or aria-valuetext={`${clamped}% used`} (ensure clamped is a
numeric value) so assistive tech reads the percent; keep the visual styling
(fillColor, width: `${clamped}%`) unchanged.

---

Outside diff comments:
In `@apps/desktop/src/main/services/ai/providerConnectionStatus.ts`:
- Around line 176-192: Replace the loose non-empty checks for Cursor keys in
providerConnectionStatus (cursorEnvAuth, cursorStoredAuth and the derived
cursorSdkAuth/cursorUsageAuth logic) with the same key-format validation used by
pollCursorUsage; import or extract the poller’s helper (e.g., isCursorKeyValid
or whatever validation function exists in pollCursorUsage) and use it to
validate process.env.CURSOR_API_KEY, getAllApiKeys().cursor, and
process.env.CURSOR_ADMIN_API_KEY before setting
cursorEnvAuth/cursorStoredAuth/cursorAdminEnvAuth and cursorCredsSource so the
status reporter and poller agree on which keys are actually usable.
- Around line 215-238: The runtime-health decorator applyRuntimeHealth currently
runs after building cursor and can overwrite usageAvailable (breaking the
admin-key-only path); move or reassign usageAvailable so the final
cursor.usageAvailable reflects cursorUsageAuth regardless of runtime health —
e.g., call applyRuntimeHealth(cursor, cursorRuntimeHealth) first (or leave it as
is) but then set cursor.usageAvailable = cursorUsageAuth afterwards (or patch
applyRuntimeHealth to never modify usageAvailable). Update the code that
constructs cursor (symbols: cursor, usageAvailable, cursorUsageAuth,
applyRuntimeHealth, cursorRuntimeHealth, createUnavailableStatus) so
usageAvailable is preserved for the admin-key path.

In `@apps/desktop/src/renderer/components/app/SettingsPage.tsx`:
- Around line 31-45: The TAB_ALIASES mapping no longer preserves old ?tab=usage
deep links; update the TAB_ALIASES constant (used to map legacy query tabs to
SectionId) to include a "usage" key mapped to the closest surviving section
(e.g., add "usage": "general") so legacy /settings?tab=usage URLs continue to
route correctly; modify the TAB_ALIASES object to include this alias and ensure
any code that reads TAB_ALIASES (referencing TAB_ALIASES and SectionId) will
pick up the new mapping.

---

Nitpick comments:
In `@apps/ade-cli/README.md`:
- Around line 90-91: Add documentation for the CLI command aliases missing from
the README: mention that the commands "quota" and "quotas" are aliases for "ade
usage snapshot" and that "poll" is an alias for "ade usage refresh". Update the
usage examples section (where "ade usage snapshot --text" and "ade usage refresh
--text" are shown) to include the equivalent alias forms and a short note
explaining these aliases for discoverability, referencing the exact command
names "usage snapshot", "usage refresh", "quota"/"quotas", and "poll" so readers
can find them easily.

In `@apps/desktop/src/renderer/components/settings/UsageMeter.tsx`:
- Line 102: MODEL_COLORS currently duplicates toneColor which is confusing;
remove the first entry ("#A78BFA") from MODEL_COLORS and update the color
selection logic (the ternary that currently reads i === 0 ? toneColor :
MODEL_COLORS[i % MODEL_COLORS.length]) to use MODEL_COLORS[(i - 1) %
MODEL_COLORS.length] for i > 0 so the first color is always toneColor and
subsequent models cycle the compact palette; alternatively, if you prefer to
keep the array as-is, add a clear comment next to MODEL_COLORS explaining that
MODEL_COLORS[0] intentionally duplicates toneColor and is only used for the 5th+
model.
- Around line 52-56: The progress bar currently animates width (the element with
className "absolute inset-y-0 left-0 ..." in UsageMeter.tsx); change it to keep
a fixed width (e.g., width: "100%") and animate using CSS transform: set
style.transform = `scaleX(${clamped / 100})` and style.transformOrigin = "left";
update the transition to animate transform (e.g., transition: "transform 500ms
ease-out") and consider adding willChange: "transform" to improve performance on
low-end devices.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: db773104-1aef-4750-9d93-a1b29b65fef4

📥 Commits

Reviewing files that changed from the base of the PR and between ed40569 and b7bd3eb.

⛔ Files ignored due to path filters (4)
  • docs/ARCHITECTURE.md is excluded by !docs/**
  • docs/features/automations/README.md is excluded by !docs/**
  • docs/features/automations/guardrails.md is excluded by !docs/**
  • docs/features/onboarding-and-settings/README.md is excluded by !docs/**
📒 Files selected for processing (20)
  • apps/ade-cli/README.md
  • apps/ade-cli/src/cli.test.ts
  • apps/ade-cli/src/cli.ts
  • apps/desktop/src/main/services/ai/providerConnectionStatus.ts
  • apps/desktop/src/main/services/cto/ctoStateService.ts
  • apps/desktop/src/main/services/usage/usageTrackingService.test.ts
  • apps/desktop/src/main/services/usage/usageTrackingService.ts
  • apps/desktop/src/renderer/components/app/CommandPalette.tsx
  • apps/desktop/src/renderer/components/app/SettingsPage.tsx
  • apps/desktop/src/renderer/components/app/TopBar.tsx
  • apps/desktop/src/renderer/components/automations/components/RuleEditorPanel.tsx
  • apps/desktop/src/renderer/components/missions/MissionHeader.tsx
  • apps/desktop/src/renderer/components/settings/SettingsUsageSection.tsx
  • apps/desktop/src/renderer/components/settings/UsageGuardrailsSection.tsx
  • apps/desktop/src/renderer/components/settings/UsageMeter.tsx
  • apps/desktop/src/renderer/components/usage/HeaderUsageControl.tsx
  • apps/desktop/src/renderer/components/usage/UsageQuotaPanel.test.tsx
  • apps/desktop/src/renderer/components/usage/UsageQuotaPanel.tsx
  • apps/desktop/src/shared/types/config.ts
  • apps/desktop/src/shared/types/usage.ts
💤 Files with no reviewable changes (3)
  • apps/desktop/src/renderer/components/app/CommandPalette.tsx
  • apps/desktop/src/renderer/components/settings/SettingsUsageSection.tsx
  • apps/desktop/src/renderer/components/settings/UsageGuardrailsSection.tsx

Comment thread apps/ade-cli/README.md
Comment thread apps/ade-cli/src/cli.test.ts
Comment thread apps/ade-cli/src/cli.ts
Comment thread apps/ade-cli/src/cli.ts
Comment thread apps/desktop/src/main/services/cto/ctoStateService.ts
Comment thread apps/desktop/src/main/services/usage/usageTrackingService.ts
Comment thread apps/desktop/src/renderer/components/settings/UsageMeter.tsx
Comment thread apps/desktop/src/renderer/components/settings/UsageMeter.tsx Outdated
arul28 added 2 commits May 10, 2026 09:26
- Cursor: prefer overallSpendCents (total) over spendCents (on-demand only)
  and fall back to monthlyLimitDollars when no per-user override is set.
- HeaderUsageControl: per-provider tooltip, glow + pulse on critical/error
  states, accurate aria-label, runtime tone reflects warnings only when no
  active percentage takes priority.
- UsageMeter: replace the stacked sub-quota bar (sub-quotas were independent
  percentages, not contributions) with a single fill plus per-model ticks.
- Move automation guardrails into the header Usage popup as a collapsible
  section; remove Settings → Usage tab, SettingsUsageSection,
  UsageGuardrailsSection, and stale references in CommandPalette,
  RuleEditorPanel, ctoStateService, and the feature docs.
- ade-cli: add `ade usage snapshot|refresh|budget` plan plus help entry.
- Tests cover the new Cursor parsing fallbacks; typecheck and affected
  vitest suites pass.
- automate: extend ade-cli/cli.test.ts with 5 cases for the new
  `ade usage snapshot|refresh|budget` plan (123 → 123 incl. usage paths).
- automate: refresh docs/ARCHITECTURE.md telemetry pointer to the
  header Usage popup (HeaderUsageControl + UsageQuotaPanel).
- finalize/simplify: extract `finiteOrZero` for the Cursor spend
  reducers, flatten the cursorBlocker ternary into an if/else cascade,
  collapse the inline budget-set try block, drop unnecessary useMemo
  + try/catch on the ipc unsubscribe callbacks, replace nested
  ternaries in ExtraUsageCard / AuthChip / fillColor with explicit
  branches.
- finalize/cli-parity: add `ade usage` examples to apps/ade-cli/README
  CLI surface inventory.

Local gate: typecheck (desktop/ade-cli/web), eslint, vitest shards 1-8,
and ade-cli tests all green.
@arul28 arul28 force-pushed the ade/usage-bar-93b136f0 branch from b7bd3eb to 6766502 Compare May 10, 2026 14:26
@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented May 10, 2026

@cursor review

{ id: "integrations", label: "Integrations", icon: Plugs },
{ id: "memory", label: "Memory", icon: Database },
{ id: "lane-templates", label: "Lane Templates", icon: Stack },
{ id: "usage", label: "Usage", icon: Lightning },
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing alias for removed "usage" settings tab

Medium Severity

The usage section was removed from SECTIONS and the command palette entry navigating to /settings?tab=usage was deleted, but no entry was added to TAB_ALIASES to redirect stale deep links. Any existing bookmark, external link, or automation that navigates to /settings?tab=usage will land on the Settings page with no active tab and an empty content area, since "usage" is no longer a valid SectionId and has no alias mapping.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b7bd3eb. Configure here.

Comment thread apps/desktop/src/main/services/usage/usageTrackingService.ts Outdated
Comment thread apps/desktop/src/main/services/usage/usageTrackingService.ts
Comment thread apps/desktop/src/renderer/components/settings/UsageMeter.tsx
Comment thread apps/desktop/src/renderer/components/usage/UsageQuotaPanel.tsx
@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented May 10, 2026

@cursor review

Comment thread apps/desktop/src/main/services/usage/usageTrackingService.ts Outdated
@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented May 10, 2026

@cursor review

Comment thread apps/desktop/src/renderer/components/usage/UsageQuotaPanel.tsx
Comment thread apps/desktop/src/renderer/components/usage/UsageQuotaPanel.tsx
Comment thread apps/desktop/src/main/services/usage/usageTrackingService.ts
@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented May 10, 2026

@cursor review

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/desktop/src/renderer/components/usage/UsageQuotaPanel.test.tsx`:
- Around line 61-79: The tests currently cast incomplete IPC mock objects to any
(e.g., the globalThis.window.ade mock and its ai.getStatus) which bypasses
TypeScript checks; create a properly typed fixture for the preload contract (or
replace the cast with an object declared to satisfy AiSettingsStatus) and use it
for globalThis.window.ade.ai.getStatus and other mocks referenced in
UsageQuotaPanel.test.tsx so all required fields (mode, availableProviders,
models, features, etc.) are present; alternatively declare the mock with
"satisfies AiSettingsStatus" to enforce the full contract and update the other
mocks (usage.getSnapshot, refresh, getBudgetConfig, saveBudgetConfig, onUpdate)
to match their respective interfaces instead of using "as any".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: dc73f463-331f-4d2d-a19a-0d3721a4e9da

📥 Commits

Reviewing files that changed from the base of the PR and between b7bd3eb and 87b772e.

⛔ Files ignored due to path filters (4)
  • docs/ARCHITECTURE.md is excluded by !docs/**
  • docs/features/automations/README.md is excluded by !docs/**
  • docs/features/automations/guardrails.md is excluded by !docs/**
  • docs/features/onboarding-and-settings/README.md is excluded by !docs/**
📒 Files selected for processing (23)
  • apps/ade-cli/README.md
  • apps/ade-cli/src/cli.test.ts
  • apps/ade-cli/src/cli.ts
  • apps/desktop/src/main/services/ai/providerConnectionStatus.test.ts
  • apps/desktop/src/main/services/ai/providerConnectionStatus.ts
  • apps/desktop/src/main/services/ai/utils.ts
  • apps/desktop/src/main/services/cto/ctoStateService.ts
  • apps/desktop/src/main/services/usage/usageTrackingService.test.ts
  • apps/desktop/src/main/services/usage/usageTrackingService.ts
  • apps/desktop/src/renderer/components/app/CommandPalette.tsx
  • apps/desktop/src/renderer/components/app/SettingsPage.tsx
  • apps/desktop/src/renderer/components/app/TopBar.tsx
  • apps/desktop/src/renderer/components/automations/components/RuleEditorPanel.tsx
  • apps/desktop/src/renderer/components/missions/MissionHeader.tsx
  • apps/desktop/src/renderer/components/settings/SettingsUsageSection.tsx
  • apps/desktop/src/renderer/components/settings/UsageGuardrailsSection.test.tsx
  • apps/desktop/src/renderer/components/settings/UsageGuardrailsSection.tsx
  • apps/desktop/src/renderer/components/settings/UsageMeter.tsx
  • apps/desktop/src/renderer/components/usage/HeaderUsageControl.tsx
  • apps/desktop/src/renderer/components/usage/UsageQuotaPanel.test.tsx
  • apps/desktop/src/renderer/components/usage/UsageQuotaPanel.tsx
  • apps/desktop/src/shared/types/config.ts
  • apps/desktop/src/shared/types/usage.ts
💤 Files with no reviewable changes (4)
  • apps/desktop/src/renderer/components/settings/SettingsUsageSection.tsx
  • apps/desktop/src/renderer/components/settings/UsageGuardrailsSection.test.tsx
  • apps/desktop/src/renderer/components/settings/UsageGuardrailsSection.tsx
  • apps/desktop/src/renderer/components/app/CommandPalette.tsx
✅ Files skipped from review due to trivial changes (3)
  • apps/desktop/src/main/services/ai/utils.ts
  • apps/desktop/src/main/services/cto/ctoStateService.ts
  • apps/desktop/src/renderer/components/automations/components/RuleEditorPanel.tsx
🚧 Files skipped from review as they are similar to previous changes (13)
  • apps/desktop/src/shared/types/config.ts
  • apps/ade-cli/README.md
  • apps/desktop/src/renderer/components/app/SettingsPage.tsx
  • apps/desktop/src/main/services/usage/usageTrackingService.test.ts
  • apps/desktop/src/renderer/components/settings/UsageMeter.tsx
  • apps/desktop/src/main/services/ai/providerConnectionStatus.ts
  • apps/desktop/src/renderer/components/usage/HeaderUsageControl.tsx
  • apps/desktop/src/main/services/usage/usageTrackingService.ts
  • apps/desktop/src/renderer/components/missions/MissionHeader.tsx
  • apps/ade-cli/src/cli.ts
  • apps/desktop/src/shared/types/usage.ts
  • apps/desktop/src/renderer/components/app/TopBar.tsx
  • apps/desktop/src/renderer/components/usage/UsageQuotaPanel.tsx

Comment thread apps/desktop/src/renderer/components/usage/UsageQuotaPanel.test.tsx Outdated
Comment thread apps/desktop/src/renderer/components/usage/HeaderUsageControl.tsx
Comment thread apps/desktop/src/renderer/components/usage/UsageQuotaPanel.tsx
@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented May 10, 2026

@cursor review

Comment thread apps/desktop/src/main/services/usage/usageTrackingService.ts
@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented May 10, 2026

@cursor review

Comment thread apps/ade-cli/src/cli.ts
Comment thread apps/desktop/src/main/services/ai/providerConnectionStatus.ts
@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented May 10, 2026

@cursor review

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/desktop/src/main/services/ai/providerConnectionStatus.test.ts (1)

232-260: ⚡ Quick win

Deduplicate env var setup/restore across Cursor tests.

The repeated CURSOR_API_KEY / CURSOR_ADMIN_API_KEY save+restore blocks are easy to drift. A tiny helper would reduce maintenance risk.

♻️ Suggested refactor
+async function withCursorEnv(
+  env: { cursorApiKey?: string; cursorAdminApiKey?: string },
+  run: () => Promise<void>,
+): Promise<void> {
+  const prevKey = process.env.CURSOR_API_KEY;
+  const prevAdminKey = process.env.CURSOR_ADMIN_API_KEY;
+  if (env.cursorApiKey === undefined) delete process.env.CURSOR_API_KEY;
+  else process.env.CURSOR_API_KEY = env.cursorApiKey;
+  if (env.cursorAdminApiKey === undefined) delete process.env.CURSOR_ADMIN_API_KEY;
+  else process.env.CURSOR_ADMIN_API_KEY = env.cursorAdminApiKey;
+  try {
+    await run();
+  } finally {
+    if (prevKey === undefined) delete process.env.CURSOR_API_KEY;
+    else process.env.CURSOR_API_KEY = prevKey;
+    if (prevAdminKey === undefined) delete process.env.CURSOR_ADMIN_API_KEY;
+    else process.env.CURSOR_ADMIN_API_KEY = prevAdminKey;
+  }
+}

Then each test becomes a concise wrapper around withCursorEnv(...).

Also applies to: 263-278, 281-308, 311-338

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/main/services/ai/providerConnectionStatus.test.ts` around
lines 232 - 260, Multiple Cursor tests repeat the same save/restore logic for
CURSOR_API_KEY and CURSOR_ADMIN_API_KEY; create a small helper (e.g.,
withCursorEnv) that accepts the desired env values and a callback, saves
previous values, sets process.env.CURSOR_API_KEY and
process.env.CURSOR_ADMIN_API_KEY, runs the callback (which will call
buildProviderConnections / mergeCliStatuses in the tests), and finally restores
the originals; then refactor tests like the "marks Cursor runtime available
through the SDK when an env API key is set" test to call
withCursorEnv({CURSOR_API_KEY: 'test-key', CURSOR_ADMIN_API_KEY: undefined},
async () => { ...expect(...)... }); reference functions buildProviderConnections
and mergeCliStatuses to ensure the helper is used around the exact test logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apps/desktop/src/main/services/ai/providerConnectionStatus.test.ts`:
- Around line 232-260: Multiple Cursor tests repeat the same save/restore logic
for CURSOR_API_KEY and CURSOR_ADMIN_API_KEY; create a small helper (e.g.,
withCursorEnv) that accepts the desired env values and a callback, saves
previous values, sets process.env.CURSOR_API_KEY and
process.env.CURSOR_ADMIN_API_KEY, runs the callback (which will call
buildProviderConnections / mergeCliStatuses in the tests), and finally restores
the originals; then refactor tests like the "marks Cursor runtime available
through the SDK when an env API key is set" test to call
withCursorEnv({CURSOR_API_KEY: 'test-key', CURSOR_ADMIN_API_KEY: undefined},
async () => { ...expect(...)... }); reference functions buildProviderConnections
and mergeCliStatuses to ensure the helper is used around the exact test logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 424fcb89-e4f9-4d8b-84cc-e95b1c2db595

📥 Commits

Reviewing files that changed from the base of the PR and between 87b772e and 5248237.

📒 Files selected for processing (8)
  • apps/ade-cli/src/cli.test.ts
  • apps/ade-cli/src/cli.ts
  • apps/desktop/src/main/services/ai/providerConnectionStatus.test.ts
  • apps/desktop/src/main/services/ai/providerConnectionStatus.ts
  • apps/desktop/src/main/services/usage/usageTrackingService.ts
  • apps/desktop/src/renderer/components/usage/HeaderUsageControl.tsx
  • apps/desktop/src/renderer/components/usage/UsageQuotaPanel.test.tsx
  • apps/desktop/src/renderer/components/usage/UsageQuotaPanel.tsx
🚧 Files skipped from review as they are similar to previous changes (7)
  • apps/desktop/src/renderer/components/usage/HeaderUsageControl.tsx
  • apps/desktop/src/main/services/ai/providerConnectionStatus.ts
  • apps/ade-cli/src/cli.test.ts
  • apps/ade-cli/src/cli.ts
  • apps/desktop/src/main/services/usage/usageTrackingService.ts
  • apps/desktop/src/renderer/components/usage/UsageQuotaPanel.tsx
  • apps/desktop/src/renderer/components/usage/UsageQuotaPanel.test.tsx

@arul28 arul28 merged commit d3d0dcb into main May 10, 2026
24 checks passed
@arul28 arul28 deleted the ade/usage-bar-93b136f0 branch May 10, 2026 16:33
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

There are 3 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5248237. Configure here.

if (absDelta <= 6) return deltaPercent >= 0 ? "slightly-ahead" : "slightly-behind";
if (absDelta <= 12) return deltaPercent >= 0 ? "ahead" : "behind";
return deltaPercent >= 0 ? "far-ahead" : "far-behind";
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pacing thresholds silently narrowed, breaking existing consumers

Medium Severity

stageForDelta narrows pacing thresholds from ±4/±10/±20 to ±2/±6/±12 compared to the old inline logic in calculatePacing. The legacy calculatePacing function now delegates to calculatePacingForWindowstageForDelta, so the same delta values produce more aggressive statuses — e.g., a delta of 5% was "on-track" and is now "slightly-ahead", a delta of 13% was "ahead" and is now "far-ahead". Existing calculatePacing tests (lines ~112–161, not shown in the diff and therefore not updated) likely assert the old status labels and will break.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5248237. Configure here.


function extractError(err: unknown): string {
return err instanceof Error ? err.message : String(err);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicated extractError utility across new components

Low Severity

The identical extractError helper is copy-pasted into both HeaderUsageControl.tsx and UsageQuotaPanel.tsx. A shared getErrorMessage already exists in the main-process utils (../shared/utils). Consolidating into a single renderer-accessible utility avoids drift and reduces maintenance burden.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5248237. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant