Skip to content

Concrete depletion ETA in Calm pace + dashboard (SOU-274) - #64

Merged
tsouth89 merged 2 commits into
mainfrom
feat/sou-274-concrete-eta
Jul 19, 2026
Merged

Concrete depletion ETA in Calm pace + dashboard (SOU-274)#64
tsouth89 merged 2 commits into
mainfrom
feat/sou-274-concrete-eta

Conversation

@tsouth89

@tsouth89 tsouth89 commented Jul 19, 2026

Copy link
Copy Markdown
Owner

Closes SOU-274.

Ceiling already computes PaceSnapshot.etaSeconds but only showed a qualitative "Running low." This surfaces the concrete time left, since the value is already there.

Changes

  • capacityPresentation.ts: formatShortDuration (compact: "42m", "1h 30m", "2d 3h"). calmPaceState now returns ~42m left (tone watch) instead of "Running low" when the pace won't last to reset. "On pace" is unchanged and already carries the reset-aware meaning (the pace lasts to the window reset). FloatBar renders pace.label/tone unchanged, so no float-bar UI change.
  • ProviderDetailView: the pace section adds "At this pace, about ~42m left before this window runs out." when running low, tone-colored on risk.

Tests

  • formatShortDuration across ranges + negative guard.
  • calmPresentation asserts the concrete ~1h left / ~42m left labels.
  • Dashboard render asserts the ETA line.

Frontend 262 green, tsc clean. Frontend-only. First of the round-2 gap items (the cheapest / highest-signal: pure surfacing of a value already computed).

Summary by CodeRabbit

  • New Features

    • Added clear “At this pace…” estimates showing how long provider capacity is expected to last.
    • Added compact time formatting for minutes, hours, and days.
    • Added risk-focused styling for depletion estimates.
  • Bug Fixes

    • Replaced the generic “Running low” message with a specific time-left estimate when available.
    • Prevented invalid or negative estimates from appearing in the interface.

Ceiling already computes PaceSnapshot.etaSeconds but only showed a vague
"Running low". Surface the actual time left, since the number is already there.

- capacityPresentation: new formatShortDuration ("42m", "1h 30m", "2d 3h").
  calmPaceState now returns "~42m left" (tone watch) instead of "Running low"
  when the pace won't last to reset; "On pace" still carries the reset-aware
  meaning (lasts to the window reset). FloatBar renders the label unchanged.
- ProviderDetailView pace section adds "At this pace, about ~42m left before
  this window runs out." when running low, tone-colored on risk.

Tests: formatShortDuration across ranges + negative guard; calmPresentation
asserts the concrete label; dashboard render asserts the ETA line. Frontend
262 green, tsc clean.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
ceiling f612eb8 Commit Preview URL

Branch Preview URL
Jul 19 2026, 03:31 AM

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 3 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 15d74249-694b-4a26-8519-0aed44c5f90c

📥 Commits

Reviewing files that changed from the base of the PR and between 45a9595 and f612eb8.

📒 Files selected for processing (3)
  • apps/desktop-tauri/src/lib/capacityPresentation.test.ts
  • apps/desktop-tauri/src/lib/capacityPresentation.ts
  • apps/desktop-tauri/src/surfaces/ProviderDetailView.tsx
📝 Walkthrough

Walkthrough

Changes

The capacity presentation layer now formats finite depletion ETAs into compact duration labels. Provider detail views conditionally display the ETA when usage will not last to reset, with dedicated default and risk-tone styling and updated unit/UI tests.

Provider Pace ETA

Layer / File(s) Summary
Pace ETA formatting and state output
apps/desktop-tauri/src/lib/capacityPresentation.ts, apps/desktop-tauri/src/lib/capacityPresentation.test.ts
Adds formatShortDuration and uses it to produce watch-state labels such as ~1h left; tests cover minute, hour, day, and invalid-duration cases.
Provider detail ETA rendering
apps/desktop-tauri/src/surfaces/ProviderDetailView.tsx, apps/desktop-tauri/src/surfaces/ProviderDetailView.test.tsx, apps/desktop-tauri/src/styles.css
Renders the depletion message for finite risky ETAs, verifies the one-hour message, and adds ETA and risk-tone styles.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ProviderDetailView
  participant PaceSection
  participant capacityPresentation
  participant styles_css
  ProviderDetailView->>PaceSection: pass pace state and etaSeconds
  PaceSection->>capacityPresentation: formatShortDuration(etaSeconds)
  capacityPresentation-->>PaceSection: compact duration
  PaceSection->>styles_css: render pace ETA element
  styles_css-->>ProviderDetailView: apply default or risk styling
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: showing concrete depletion ETA in Calm pace and the dashboard.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/sou-274-concrete-eta

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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-tauri/src/lib/capacityPresentation.ts`:
- Around line 248-268: Update calmPaceState so the ETA label does not prepend
"~" when formatShortDuration returns the "under 1m" sentinel; retain the
approximation prefix for other durations. Apply the same conditional formatting
in ProviderDetailView’s ETA label so it renders “under 1m left” rather than
“about under 1m left”.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 81fe39c5-dd0a-4744-a01d-412eee20c3ab

📥 Commits

Reviewing files that changed from the base of the PR and between 8a98e43 and 45a9595.

⛔ Files ignored due to path filters (3)
  • design/x-header.png is excluded by !**/*.png
  • design/x-profile.png is excluded by !**/*.png
  • docs/images/ceiling-cahrts.png is excluded by !**/*.png
📒 Files selected for processing (5)
  • apps/desktop-tauri/src/lib/capacityPresentation.test.ts
  • apps/desktop-tauri/src/lib/capacityPresentation.ts
  • apps/desktop-tauri/src/styles.css
  • apps/desktop-tauri/src/surfaces/ProviderDetailView.test.tsx
  • apps/desktop-tauri/src/surfaces/ProviderDetailView.tsx

Comment on lines +248 to +268
/**
* Trustworthy pace state for Calm mode, or null when there isn't enough signal.
* Never invents an "on pace" state (SOU-178): it only speaks when the provider
* actually reports usable pace data.
* actually reports usable pace data. When the current pace will NOT last to the
* reset, surface the concrete time left ("~42m left") instead of a vague
* "Running low", since the number is already computed (SOU-274). "On pace"
* already carries the reset-aware meaning: the pace lasts until the window
* resets.
*/
function calmPaceState(pace: PaceSnapshot | null): CalmPaceState | null {
if (!pace) return null;
// Data-backed and reassuring: the current pace lasts to the reset.
if (pace.willLastToReset) return { label: "On pace", tone: "steady" };
// Only warn when there is a real, finite estimate of running out; otherwise
// stay silent rather than fabricate a state.
// stay silent rather than fabricate a state. Show the concrete ETA.
if (
typeof pace.etaSeconds === "number" &&
Number.isFinite(pace.etaSeconds) &&
pace.etaSeconds > 0
) {
return { label: "Running low", tone: "watch" };
return { label: `~${formatShortDuration(pace.etaSeconds)} left`, tone: "watch" };

Copy link
Copy Markdown

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

Avoid malformed sub-minute ETA labels.

When formatShortDuration returns "under 1m", this branch renders ~under 1m left; ProviderDetailView.tsx Lines [194]-[195] similarly renders about under 1m left. Make the approximation prefix conditional for this sentinel.

🤖 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-tauri/src/lib/capacityPresentation.ts` around lines 248 - 268,
Update calmPaceState so the ETA label does not prepend "~" when
formatShortDuration returns the "under 1m" sentinel; retain the approximation
prefix for other durations. Apply the same conditional formatting in
ProviderDetailView’s ETA label so it renders “under 1m left” rather than “about
under 1m left”.

formatShortDuration returns "under 1m" for <60s, so "~${d} left" and
"about ${d}" read "~under 1m left" / "about under 1m left". Drop the
approximation prefix for the sub-minute case: "under 1m left" in the Calm
pill and "under a minute" in the dashboard sentence. Adds a sub-minute test.
@tsouth89
tsouth89 merged commit 9dc6732 into main Jul 19, 2026
10 of 11 checks passed
@tsouth89
tsouth89 deleted the feat/sou-274-concrete-eta branch July 19, 2026 03:34
@tsouth89 tsouth89 mentioned this pull request Jul 19, 2026
tsouth89 added a commit that referenced this pull request Jul 19, 2026
Version bump to **1.2.0** across manifests + `version.env`, with the
1.2.0 changelog entry. No code changes beyond version strings; all
feature work already merged and green on main.

### Since 1.1.0
- **Depletion ETA** — Calm mode and the dashboard show "about ~42m left"
instead of just flagging a running-low window (SOU-274, #64)
- **`statusline` command** — cache-only, prints remaining capacity for
editor status bars without waking the app or hitting the network
(SOU-271, #65)
- **Per-project cost** — 30-day spend split by project alongside
model/effort (SOU-272, #66)
- **CSV export** — export a provider's 30-day spend to Downloads from
the charts view (SOU-273, #67)
- **Cursor activity card** — activity-by-model share from local request
logs (#61)

Release doctor passes. Tag `v1.2.0` will be pushed after merge to
trigger the signed Windows build.

Co-authored-by: tsouth89 <tsouth89@users.noreply.github.com>
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