design.md 4.4 KB

Context

The existing renderer builds a fixed three-row table for the quota windows (5-hour / 7-day / month) inside RenderAccount. Each row includes a progress bar, percentage, and used-vs-max columns. For the monthly row, used_* fields are synthesized as placeholders and the percentage prints as n/a because the API does not return them — only max_flows and max_value_usd. This makes the monthly row visually inconsistent with its peers and implies data is missing when in fact the API is behaving as documented.

The user's ask is to move the monthly values out of the progress-bar block into a simpler one-line summary below the existing "Tokens consumed" line.

Goals / Non-Goals

Goals:

  • Remove visual noise: no more empty bar or n/a / placeholders.
  • Keep monthly limits visible — users still want to see "34560 flows / $1134.33 per month" for context.
  • Preserve per-account layout (header → quota rows → summary lines) so multi-account output still reads top-to-bottom naturally.
  • Touch the minimum number of files: renderer + tests + README.

Non-Goals:

  • Change JSON output shape. The raw API response is unchanged; piped consumers keep getting quota_monthly verbatim.
  • Hide the monthly cap entirely. The user explicitly asked to display it, just in a simpler location.
  • Restyle the existing two bars, header, or reset line.

Decisions

1. Placement of the monthly cap line

Decision: Emit it immediately after the "Tokens consumed (estimated USD value): $X.XX" line and before the "Next reset" line. Format:

  Tokens consumed (estimated USD value): $13.66
  Monthly cap: 34560 flows · $1134.33
  Next reset: 5h → 2026-04-22 14:05  ·  7d → 2026-04-28 00:00

Why: The three summary lines now read as a tight stack: what you used (usage value), what your cap is (cap), and when the windows reset. All three are "read-only facts about this account" and belong together. Alternatives considered:

  • Put it on the plan/header line (e.g. Ultra plan ($200/mo) · healthy · $0.03283/flow · 34560 flows/mo cap). Rejected — the header is already the busiest line; adding another ·-joined field pushes it past terminal width on small monitors.
  • Put it below "Next reset". Rejected — feels like a footer afterthought.
  • Drop it entirely. Rejected — user explicitly asked to keep it visible.

2. Formatting convention

Decision: Monthly cap: <fmtFlow(max_flows)> flows · $<%.2f>(max_value_usd). Use the existing fmtFlow and fmtUSD helpers from render.go so integers stay integers (34560 not 34560.00) and the dollar figure always has two decimals. Why: Consistent with how the other rows format flows and USD.

3. Renderer code change

Decision: Delete the third entry ("month") from the rows slice inside RenderAccount. The monthly-branch (r.monthly) code paths in the same function then become dead and can be removed. After the token-consumed line, add one Fprintf using d.QuotaMonthly.MaxFlows and d.QuotaMonthly.MaxValueUSD. Why: Keeps the existing two-row column-alignment logic intact; we're only removing a row, not rewriting the layout algorithm. Alternatives considered: Parameterize the rows by a showMonthly bool. Rejected — overkill for a change that's removing the concept entirely.

4. Tests

Decision: Adjust the existing TestRenderAccount_Snapshot assertions — drop the three checks that reference the monthly row (" n/a", "— / 34560 flows", "— / $1134.33"), add one that matches "Monthly cap: 34560 flows · $1134.33". The TestRenderAll_MultiAccountWithError and color-band tests are unaffected.

Risks / Trade-offs

  • Users who read the monthly row as a "progress indicator" → they'll no longer see an empty bar. Mitigation: the cap line is labeled explicitly; anyone who wants a progress view of monthly usage can look at the 7-day window, which is the closest proxy the API provides.
  • Column-width regressions → removing a row shortens the widest flows/dollars column, possibly changing alignment for the remaining two rows. Mitigation: existing code computes max width across the rows slice, so it naturally re-aligns; no special handling needed.
  • README drift → the ASCII sample in README.md also renders the old three-row layout. Mitigation: update it in the same change.

Migration Plan

N/A — runtime behavior change only. No config migration, no flag change, no exit-code change.