mirror of
https://github.com/Routstr/routstrd.git
synced 2026-10-30 07:37:40 +00:00
Rename the second usage-monitor tab from Today to History and draw usage over time as a bar chart instead of the text lists and horizontal hourly bars. - daemon: add a zero-filled `timeline` series to the windowed summary, bucketed per window (hours for 24h, days for 7d/30d, months for all). Months are folded from daily aggregates since the SDK has no month grouping. - tui: renderHistory draws a vertical spend chart with a y-axis, x labels and an independently scaled token sparkline plus legend; the [W] selector now drives the tab (it was hidden on it before). - renderBox truncates overlong lines so a large number can't push the right border out. - docs: SKILL.md wording + docs/plans/tui-history-charts.md. Tests: daemon timeline buckets; chart axis/labels/sparkline/legend, empty state, and full-width alignment.
2.8 KiB
2.8 KiB
TUI "History" tab with adaptive bar charts
Status: implemented. Branch
feat/tui-history-charts(worktree.worktrees/tui-history-charts, based onmain@5069b2d).
Goal
Replace the old Today tab (a totals box + a text "Recent Days" list + a
horizontal hourly bar list) with a History tab that draws usage over time
as bar charts, with the bucketing driven by the existing [W] time-window
selector.
[W] window |
Bucket | Bars |
|---|---|---|
24h |
hour | 24 |
7d |
day | 7 |
30d |
day | 30 |
All |
month | one per calendar month since first usage |
Y-axis is total spend; a token sparkline shares the x-axis (scaled independently to peak tokens, with both totals in the legend). This also makes the tab window-aware: the selector was previously hidden on it.
Backend — src/daemon/http/usage-summary.ts
- New
TimelineBucket(hour|day|month),TimelinePointandTimelinetypes;WindowedStatsgains a requiredtimeline: Timeline. buildTimeline(driver, baseFilter, window, now, tzOffsetMinutes):today(24h) →aggregate({ groupBy: "hour" })over the last 24 local-aligned hours. The SDK'shourkey isHHwith no date, so the window is aligned to whole hours (each hour-of-day appears at most once).7d/30d→aggregate({ groupBy: "day" })over the last N days.all→aggregate({ groupBy: "day" })with noafter, folded intoYYYY-MMmonths. The SDK has nomonthgrouping, hence the fold.- Every series is zero-filled so the x-axis is evenly spaced.
buildTimelineis called once per summary build (afterbuildAggregates) and attached to both the all-time and windowed blocks. The zero-data short-circuit returns an empty timeline.
TUI
types.ts—TabId"today"→"history"; re-export the timeline types.constants.ts— tab renamed toHistory;tabSupportsWindownow excludes only Overview and Recent.render.ts—renderTodayreplaced byrenderHistory+renderTimelineChart(vertical bars, y-axis gutter, x labels, token sparkline, legend). Long series are merged to fit narrow terminals.data.ts— the old-daemon fallbackwindowFromAllTimesupplies an empty timeline.
Tests
src/daemon/http/usage-summary.test.ts— hourly / 7-day / 30-day / month-folded timelines, including zero-fill and window totals.src/tui/usage/render.test.ts— axis, labels, sparkline, legend, empty state, and full-width alignment of every rendered line.
Notes / limits
- Daemons too old to return
timelinestill render: the History tab falls back to an empty chart rather than erroring. - The 24h window is hour-aligned rather than a rolling
now - 24h, so each hour-of-day appears once and theHHkeys stay unambiguous.