Skip to content

feat(colors): optional pace-based bar colors - #332

Open
leinardi wants to merge 3 commits into
slkiser:v6from
leinardi:pace-level-colors
Open

leinardi wants to merge 3 commits into
slkiser:v6from
leinardi:pace-level-colors

Conversation

@leinardi

@leinardi leinardi commented Oct 16, 2026 •

Copy link
Copy Markdown

Summary

An opt-in setting, colors.levelBy, that lets the level colors (bars, and the percents and other roles set to bar) follow each limit's pace instead of the share left. This is a draft to show what I had in mind in #327. Happy to change the name, the defaults or the approach.

With colors.levelBy: "pace", it uses the pace paceOf() already computes for "runs out in" and the even-use mark:

  • good: at or under even use. An untouched limit at the start of its window is green, not yellow: even use still leaves about 100% there, so it reads as on track.
  • warning: up to 5 points faster than even use (the on-track band, on the faster side).
  • Fast within the first tenth of the window (MIN_ELAPSED_SHARE): too early for pace to mean much, so the row follows the share left, and a nearly used-up limit is still low.
  • low: more than 5 points faster than even use.
  • A row without a pace (no reset time, no known window length) keeps the share-left thresholds (colors.warningBelow / colors.lowBelow).

What it does not change:

  • "left" stays the default, so nothing changes unless you turn it on.
  • The toast after a reply (toast.afterReply: "low") still goes by the share left; with pace it would fire far more often.
  • The pace words stay as they are.

How: rowFacts() already computes the pace, so it adds paceLevel to the facts; withPaceLevel() puts it on the segments that carry a percent; levelColor() / roleColor() / segmentColor() use it when display.levelBy is "pace". Every TUI surface colors through those, so the sidebar, collapsed sidebar, status line, toasts and the Limits tab all follow. The setting is on the Colors tab as Bar colors follow and in docs/readme/configuration.md.

Linked Issue

Refs #327

OpenCode Validation

  • Current production released OpenCode version tested: 2.0.29
  • Why this version is relevant to the fix: the version I run v6.0.0-beta.1 on; the change is TUI rendering only.

Before-and-after evidence

The screenshots use made-up demo data (a local-only patch, not part of this PR), so no real accounts show. Same configuration, model, theme and window size; the only difference is colors.levelBy.

Note

The screenshots were taken before 70d096e, which changed the first tenth of a window to follow the share left. The one row it affects is Z.ai 5h (85% left, 12 minutes in): it now shows green under pace, not yellow.

Row Left left (before) pace (after)
OpenAI personal 5h, untouched, 2 min in 100% green green
OpenAI personal 7d, 9h to the reset 35% yellow green
OpenAI work 5h, 26m to the reset 15% red green
OpenAI work 7d, 5 of 7 days to come 62% green red
Claude 5h, a little faster than even 50% green yellow
Claude 7d, at even use 30% yellow green
Z.ai 5h, fast but 12 min in 85% green yellow
Z.ai 30d, no reset time 8% red red

On the Limits tab, "on track" can be green or yellow: green at or above the ┃ even-use mark, yellow a little below it.

Before (colors.levelBy: "left", today's behavior):

image image

After (colors.levelBy: "pace"):

image image

Surface checks:

  • TUI sidebar (open): changes with the setting, screenshots above.
  • Status line below the message input: changes with the setting, screenshots above.
  • /quota Limits tab: changes with the setting, screenshots above.
  • TUI sidebar (collapsed) and toasts: same color path (segmentColor), not captured; the toast colors are covered by tests/tui.toast-colors.test.ts. I can add screenshots if you want them.
  • /quota Usage, Plugin and Settings tabs: unchanged, apart from the new Bar colors follow line on Colors.
  • Web and Desktop text commands, CLI show/status: Not applicable, no colors.

Quality Checklist

  • I ran pnpm verify
  • This change is focused and avoids unrelated behavior changes
  • I updated or added tests when behavior changed
  • I updated docs when user-facing workflow, command, or config behavior changed
  • For provider changes, I followed Provider Changes, or this does not apply

…velBy "pace", off by default: plenty to spare is good, on track is warning, faster than it refills is low, and a row without a pace keeps the share left; the toast after a reply still goes by the share left
…use is good, so an untouched limit at the start of its window is no longer a warning
@leinardi
leinardi marked this pull request as ready for review October 16, 2026 10:52
… first tenth follows the share left, so a nearly used-up limit is still red early in its window
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