Skip to content

feat(usage): add hide-when-zero state to usage widgets and reset timers - #599

Open
tough-griff wants to merge 6 commits into
sirmalloc:mainfrom
tough-griff:feat/usage-hide-when-zero
Open

tough-griff wants to merge 6 commits into
sirmalloc:mainfrom
tough-griff:feat/usage-hide-when-zero

Conversation

@tough-griff

@tough-griff tough-griff commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Closes #598

Adds an opt-in zero hideable state (via the existing (h)ide… checklist) to the usage widgets and reset timers.

Changes

  • Session / Weekly / Weekly Sonnet / Weekly Opus / Weekly Fable Usage: hide when the raw usage is 0%, regardless of the used/remaining toggle. Implemented once in renderUsagePercentWidgetValue.
  • Block Reset Timer / Weekly Reset Timer: hide when the period's usage is 0% and no reset time was reported. The reset-time guard matters because a null API bucket pins usage to 0% even when limits[] still supplies a live window (Weekly session usage not updating after fable-only usage added #503), so without it the option would hide a valid countdown on migrated accounts.
  • Extra Usage Used / Utilization: hide at $0 spent / 0%. Extra Usage Remaining is deliberately left out.
  • Migrations: the v3 → v4 hide-flag rule for Extra Usage Used/Utilization now lists zero, so a hand-written hide list keeps it.
  • Docs: docs/USAGE.md hide-state list updated.

Testing

  • New cases in the shared usage-percent suite (covers all five usage widgets), both timer tests (including the reset-time guard), and both Extra Usage tests
  • bun test and bun run lint pass
  • Manually verified against an Enterprise account (every window null) and the example payload

Enterprise account, same line as in #598. Before (config in #598: Session Usage, Weekly Usage and both reset timers on hide: no-data; the Extra Usage widgets on disabled,no-data):

$XYZ ▓▓▓▓▓▓▓▓▓░ 85.1% | 0% 2h5m | 0%

After (zero added to every widget; the Extra Usage widgets stay visible because spend is non-zero):

$XYZ ▓▓▓▓▓▓▓▓▓░ 85.4%
Widget config for the after line
[
  {
    "id": "fb09dd02-a41b-4172-bfdf-4dd7e329b8a7",
    "type": "extra-usage-used",
    "color": "ansi256:11",
    "numberFormat": {
      "style": "compact"
    },
    "rawValue": true,
    "metadata": {
      "hide": "disabled,no-data,zero"
    }
  },
  {
    "id": "9fdb44e0-25bf-44ac-b943-a34f1b377d18",
    "type": "separator",
    "character": " "
  },
  {
    "id": "351546ed-1c7c-4663-8c2a-cf7ca36443b7",
    "type": "extra-usage-utilization",
    "color": "ansi256:11",
    "numberFormat": {
      "style": "compact"
    },
    "rawValue": true,
    "metadata": {
      "display": "slider",
      "invert": "false",
      "hide": "disabled,no-data,zero"
    }
  },
  {
    "id": "7b2987cb-1c37-4f4c-bce6-4adb6d482626",
    "type": "separator",
    "color": "ansi256:7",
    "dim": true
  },
  {
    "id": "b125133a-d2da-4254-955e-ad9bfa5a3487",
    "type": "session-usage",
    "color": "ansi256:80",
    "numberFormat": {
      "style": "compact"
    },
    "rawValue": true,
    "metadata": {
      "invert": "false",
      "display": "time",
      "hide": "no-data,zero"
    }
  },
  {
    "id": "52245476-8615-43c9-8db5-7fd37c45139c",
    "type": "separator",
    "character": " "
  },
  {
    "id": "6fa9558a-8a03-442c-bfef-dfb5854cba65",
    "type": "reset-timer",
    "color": "ansi256:80",
    "dim": true,
    "numberFormat": {
      "style": "compact"
    },
    "rawValue": true,
    "metadata": {
      "display": "time",
      "compact": "true",
      "absolute": "false",
      "hide": "no-data,zero"
    }
  },
  {
    "id": "d7a551fb-4953-44bd-8448-ecaecacf9668",
    "type": "separator",
    "color": "ansi256:7",
    "dim": true
  },
  {
    "id": "a73d2332-9fbb-48f9-abc5-02d4561157ca",
    "type": "weekly-usage",
    "color": "ansi256:81",
    "numberFormat": {
      "style": "compact"
    },
    "rawValue": true,
    "metadata": {
      "display": "time",
      "invert": "false",
      "hide": "no-data,zero"
    }
  },
  {
    "id": "1df9ff5e-64a3-41ad-8f97-d45367ba35ee",
    "type": "separator",
    "character": " "
  },
  {
    "id": "1a69f9af-0275-40f5-8521-af07f0e8940b",
    "type": "weekly-reset-timer",
    "color": "ansi256:81",
    "dim": true,
    "numberFormat": {
      "style": "compact"
    },
    "rawValue": true,
    "metadata": {
      "display": "time",
      "compact": "true",
      "hours": "false",
      "hide": "no-data,zero"
    }
  }
]

🤖 Generated with Claude Code

@eric-engberg

Copy link
Copy Markdown
Contributor

Most of the conflicts here come from my PRs merged on Oct 9: #668 (Extra Usage Utilization shows 0% when nothing's spent) and #670. If it helps, I'm happy to resolve them, or put up a branch with main merged in that you can pull.

@tough-griff
tough-griff force-pushed the feat/usage-hide-when-zero branch from 1142c48 to 170df0e Compare October 12, 2026 17:23
tough-griff and others added 5 commits November 2, 2026 13:59
Session, Weekly, Weekly Sonnet, Weekly Opus and Weekly Fable usage widgets,
plus the Block and Weekly reset timers, gain an opt-in `zero` hideable state.
Usage widgets hide when their raw usage is 0 (independent of invert); reset
timers hide when their period's usage (session/weekly) is 0.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
…tion

Both widgets gain the opt-in `zero` hideable state: Used hides at $0 spent,
Utilization hides at 0% (independent of invert). Extra Usage Remaining is
left alone, since hiding it would hide either the full budget or the $0-left
warning. The v3 -> v4 hide migration rule for the two widgets now lists
`zero` so a hand-written hide list keeps it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
List the new `zero` state for the usage-percent widgets, the reset timers,
and Extra Usage Used/Utilization (noting Remaining has none). The shared
suite's "zero state off" case now asserts the exact 0.0% output instead of
just non-null.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
… time

A null API bucket pins session/weekly usage to 0% even when limits[] still
reports a live window (sirmalloc#503), so hide-when-zero was hiding reset timers that
had a valid countdown. The timers now hide on zero only when no reset time
was reported for that period, which still covers unused windows and
Enterprise accounts with no rate-limit windows (sirmalloc#343).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@tough-griff
tough-griff force-pushed the feat/usage-hide-when-zero branch from 170df0e to be3ea73 Compare November 2, 2026 19:18
…r window

The zero state compared raw values to exactly 0, so 0.04% still rendered
`0.0%` and sub-cent spend rendered `$0.00`. It now follows the widget's
number format, using the used value even when showing remaining.

The reset timers checked for a reset-time string before resolving the
window, which hid them when local block metrics supplied a window and kept
them visible when the reset time had passed. They now hide only at zero
usage with no active window, under a label that says so.

Spend Limit Usage declares the zero state its shared renderer already
honored, so the TUI offers it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Sm19URqZ4HjS5MEWkyz3nF
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.

Usage widgets permanently show 0% on Enterprise accounts; add an option to hide them when usage is zero

2 participants