Skip to content

feat(tui): add calendar pace indicators and align sidebar rows - #6

Merged
PentSec merged 1 commit into
PentSec:mainfrom
Zorato:feat/sidebar-pace-indicator
Nov 3, 2026
Merged

PentSec merged 1 commit into
PentSec:mainfrom
Zorato:feat/sidebar-pace-indicator

Conversation

@Zorato

@Zorato Zorato commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Add pace indicators for the rolling, weekly, and monthly usage windows.

  • Show +Npp when usage is below the elapsed share.
  • Show -Npp when usage is above the elapsed share.
  • Round the absolute deviation before selecting the status. A rounded deviation of five points or less shows on pace.
  • Use exact five-hour and seven-day windows for rolling and weekly usage.
  • Derive the monthly start one UTC calendar month before resetsAt, with the day clamped to the previous month when necessary.
  • Label the monthly row 1mo instead of 30d.
  • Count all calendar time, including weekends.
  • Omit the pace label when the reset timestamp is missing or invalid.

Align labels, bars, percentages, pace indicators, and reset countdowns with fixed columns. Use a ten-cell bar and preserve its track color through an inline span.

This branch is rebased onto main after #5. It preserves setup-owned state, polling, and cleanup. Renderer tests invoke plugin cleanup before disposing views and detect leaked intervals.

This PR adds no configuration options and does not change credential resolution.

Verification

  • npm test: 43 tests pass across five files, including all refresh and lifecycle tests from fix(tui): keep usage state and polling in plugin setup #5.
  • npm run typecheck: passes for production sources.
  • Pace tests cover 28-, 29-, 30-, and 31-day months, leap years, year boundaries, end-of-month clamping, and UTC time preservation.
  • Rounding tests cover symmetric deviations of 5.4 and 5.5 points.
  • All 18 pace tests also pass with TZ=America/New_York.
  • OpenTUI renderer tests cover column alignment, track color, live pace updates, and cleanup.
  • Mutation checks detect fixed-thirty-day monthly calculations, inconsistent status rounding, and missing renderer cleanup.

Tests use synthetic responses, not live credentials or API requests.

@Zorato

Zorato commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

This is how it looks like on my OpenCode setup:
image
For myself I have excluded weekends (Saturday & Sunday). Let me know if you want to add config for that or exclude them by default.

@PentSec

PentSec commented Nov 3, 2026

Copy link
Copy Markdown
Owner

Thanks, the pace math and the renderer tests are solid, and the alignment reads well in the screenshot.

Two things before this can merge:

  1. tui.tsx conflicts with fix(tui): keep usage state and polling in plugin setup #5. fix(tui): keep usage state and polling in plugin setup #5 moves the state and polling into setup; this branch rewrites the same file from main, so resolving the conflict by taking this version brings back the remount reset that fix(tui): keep usage state and polling in plugin setup #5 fixes. This needs a rebase on main once fix(tui): keep usage state and polling in plugin setup #5 lands, plus cleanup?.() in the test teardown, otherwise each test leaves a refresher running.

  2. The monthly window is not 30 days. Real payload: monthly.resetsAt is 2026-11-15T18:12:24Z, the subscription anniversary, so the window is a calendar month of 28 to 31 days. Using 30 days shifts the expected share by up to about 3 points, which is enough to cross your 5 point band and flip on pace. Subtracting one calendar month from resetsAt for the monthly row would be exact. Weekly (Monday 00:00 UTC) and rolling (5h) are exact as written.

Minor: a delta of 5.4 renders as -5pp, which per your own table means "on pace". Pick the bucket with the rounded value, or ceil the magnitude.

On weekends: calendar time as the default is fine with me. If we add an option later, it goes behind config, not in this PR.

Compare usage with elapsed calendar time for each window. Show reserve, deficit, or on pace within five percentage points.

Use fixed columns and a ten-cell bar with an inline track span. Add pace, format, and renderer tests.
@Zorato
Zorato force-pushed the feat/sidebar-pace-indicator branch from 54f864f to b5fb1d7 Compare November 3, 2026 20:04
@Zorato

Zorato commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review. Addressed in b5fb1d7:

  • Rebased onto main after fix(tui): keep usage state and polling in plugin setup #5 and preserved setup-owned state and polling.
  • Added plugin cleanup to renderer test teardown, plus a check for leaked intervals.
  • Changed monthly pace to subtract one UTC calendar month from resetsAt, with end-of-month clamping. Renamed the row to 1mo.
  • Rounded the absolute deviation before selecting the status: ±5.4 stays on pace, while ±5.5 displays ±6pp.

Calendar time remains the default, with no weekend option in this PR.

All 43 tests pass, including the lifecycle tests from #5. Production typecheck passes. The 18 pace tests also pass with TZ=America/New_York.

@PentSec
PentSec merged commit d886f7b into PentSec:main Nov 3, 2026
2 checks passed
@Zorato
Zorato deleted the feat/sidebar-pace-indicator branch November 4, 2026 07:25
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.

2 participants