Prepare Ceiling 1.5.23 - #204
Conversation
Carries the two feature requests merged since v1.5.22 (#202 for #191, #203 for #190), plus two cleanups made while verifying them. - Remove the Cursor "Promotional" lane. Its percentage was `plan.used - breakdown.included`, and the included lane is its own closed set, so the subtraction was identically zero and the meter read 0% permanently. The badge it fed claimed the bonus expired at the billing cycle end, while Cursor credits expire on their own schedule. `breakdown.bonus` is bonus *consumed*; the grant it would be metered against is nowhere in the payload, so there is nothing honest to show. - Stop mutating process environment in cost-scanner tests. Setting `CODEX_HOME`, `CLAUDE_CONFIG_DIR`, or `GROK_HOME` while another thread reads them is undefined behaviour, and nine modules read those constantly, so unrelated scans intermittently resolved the wrong home. One such failure poisoned the shared mutex and cascaded into three more, disguising a single fault as four. `CostScanner` now takes an injected ambient home; the mutex and its dead helper are gone with it. The suite went from failing about one run in five to 12 clean runs.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
ceiling | 015712b | Commit Preview URL Branch Preview URL |
Aug 05 2026, 02:48 AM |
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 23 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (9)
Comment |
There was a problem hiding this comment.
Pull request overview
Prepares the Ceiling 1.5.23 release by bumping versions across the Rust crate + Tauri shell, updating changelog/release notes, and landing two related cleanups: removing Cursor’s non-functional “Promotional” lane and eliminating test flakiness caused by mutating process environment in cost-scanner tests.
Changes:
- Bump app/package versions to 1.5.23 (including build number) across Rust + Tauri + JS packaging metadata.
- Remove Cursor “Promotional” usage lane/badge wiring and adjust Cursor provider tests accordingly.
- Refactor
CostScannerto allow injecting an ambient home in tests instead ofenv::set_var, reducing cross-test interference.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
version.env |
Bumps marketing version and build number for the 1.5.23 release. |
rust/src/providers/cursor/api.rs |
Removes the Cursor “Promotional” lane logic and updates provider tests. |
rust/src/cost_scanner.rs |
Adds ambient_home_override injection for tests to avoid process env mutation. |
rust/Cargo.toml |
Updates codexbar crate version to 1.5.23. |
CHANGELOG.md |
Adds 1.5.23 release notes entry. |
Cargo.lock |
Updates locked package versions for 1.5.23. |
apps/desktop-tauri/src-tauri/tauri.conf.json |
Bumps Tauri app version to 1.5.23. |
apps/desktop-tauri/src-tauri/Cargo.toml |
Updates codexbar-desktop-tauri crate version to 1.5.23. |
apps/desktop-tauri/package.json |
Updates desktop shell package version to 1.5.23. |
.github/release-notes-1.5.23.md |
Adds GitHub release notes markdown for 1.5.23. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Removing the redundant promotional test used an index-based slice that over-cut and silently deleted four unrelated tests. The suite still passed, so nothing flagged it. Restored from main: - test_cursor_build_result_cents_only - test_cursor_build_result_missing_plan - test_cursor_on_demand_as_named_extra_and_cost - test_cursor_unlimited_without_monthly_meter The first of those is the one covering `plan_monthly_percent`'s used/limit fallback, which is exactly the coverage gap review flagged. Added a further test for the `breakdown.total` limit fallback, which was never covered even before this branch. Also: - `ambient_home_override` docs now name all three env homes it stands in for, including `GROK_HOME`. - Fixed a rustdoc link to the deleted `with_account_homes`. - Reworded the pace bar description in the changelog and release notes; "whose tick marks where usage should be" garden-paths on "tick marks".
|
Fixed in 015712b — and one of these caught a real mistake of mine. Test coverage (thank you). I initially checked this and thought the finding was wrong, because
The suite stayed green throughout, so nothing surfaced it. All four are restored from Docs. Grammar. "whose tick marks where usage should be" is technically valid ("tick" noun, "marks" verb) but garden-paths on "tick marks" as a compound noun, which is worse in user-facing release notes. Reworded to "with a tick showing where usage should be" in both files. 801 rust / 474 tauri / 364 vitest, clippy clean. |
…#205) Follow-up to #203 and #202, prepared as **1.5.24**. ## Why this exists #203 put a pace verdict in `MenuCard`. `<MenuCard` renders in exactly one place — `TrayPanel.tsx:466`. The main app window is `PopOutPanel`, which renders `ProviderDetailView`, a component that change never touched. So the pace answer, and the Cursor on-demand dollars from #202, never appeared in the window most people use. ## The marker Every weekly and monthly bar in the Overview and in a provider's detail view now shows where usage *should* be. One rule everywhere: **the marker is where the bar's edge should be right now.** Overspending fills the span between edge and marker with a striped band, so it reads as a distance rather than as a line you have to decode. Bars showing remaining capacity mirror the marker, and `ahead` is computed from usage rather than bar geometry so it means the same thing in both modes — pinned by a test asserting both modes agree on the same window. Derived from `elapsed / duration`, not from `PaceSnapshot`. That means no provider support is needed and it applies to every long window, rather than the single window pace is computed for. Windows under 12h are skipped: a 5-hour session is not spent evenly, so a marker there would sweep across the bar and mean nothing. ## Cursor on-demand `ProviderDetailView` filtered it out by name: ```ts .filter((metric) => !/promotional|on-demand/i.test(metric.label)) ``` So #202's plumbing was landing correctly and being discarded at the last step. Filter removed; the **On-demand** row now shows with its spend beside it. (`promotional` no longer exists at all after #204.) ## Two bugs only running the app could find 1. **`.usage-bar` collided with an existing component** at `styles.css:1831`, which sets `display: flex`. My bar became a flex item, collapsed to zero width, and vanished — while the absolutely-positioned marker kept rendering, leaving markers floating with no bars. Renamed to `.pace-overlay*`. 2. **Red on red was invisible.** On an exhausted bar the fill is already red, so a red marker and band disappeared into it. Both now use the text colour. Neither was reachable from unit tests or a static mock. ## Verification Run against live provider accounts and screenshotted, plus 801 rust / 375 vitest, clippy clean, tsc clean, and `local-check.ps1 -All -Version 1.5.24` green. One stale test updated: `ProviderDetailView.test.tsx` asserted the filtered lane was absent. Its fixture now carries an on-demand window with money and asserts it renders. --------- Co-authored-by: tsouth89 <tsouth89@users.noreply.github.com>
Prepares Ceiling 1.5.23, carrying the two feature requests merged since v1.5.22 plus two cleanups found while verifying them.
Also in this PR
Removed the Cursor "Promotional" lane
The percentage was
plan.used - breakdown.included, clamped to the bonus. The included lane is its own closed set —plan.used == breakdown.included == plan.limiton every real payload — so the subtraction was identically zero and the meter read 0% permanently. Confirmed against a live account:Promotional 0.00%.The
PromoSignalbadge it fed took its expiry from the billing cycle end, while Cursor credits expire on their own schedule (the dashboard shows a 2027 date on my account). So it was telling users their bonus expired about a year early.Neither number is recoverable:
breakdown.bonusis bonus consumed, and the grant it would be metered against is not in the payload. Removed rather than guessed at.Stopped mutating process environment in cost-scanner tests
unsafe { env::set_var(...) }onCODEX_HOME,CLAUDE_CONFIG_DIR, andGROK_HOMEis undefined behaviour while any other thread reads those variables, and nine modules read them constantly. Unrelated scans intermittently resolved the wrong home.The failure was also disguised: one panicking test poisoned the shared mutex, and the three tests that then failed on
.expect()made a single fault look like four.CostScannernow takes an injectedambient_home_override, so no test touches process env. The mutex and its now-dead helper constructor are gone. Measured before/after: ~1 failing run in 5 → 12 consecutive clean runs.Not included
A sweep of ~36 providers turned up three more meters that may rest on inferred denominators (
commandcode,minimax,manus). None could be verified without accounts on those services, and guessing at field semantics is what produced the bug this PR removes. Left alone deliberately; worth a follow-up issue for someone who can check them.Verification
796 rust / 474 tauri / 364 vitest, clippy clean, tsc clean.