Part 1 (src): expose two add-only, optional aggregations on the menubar
payload's `current`, computed on the unscoped all-provider path from the
surviving-session parse (carried history cannot contribute, as expected).
- current.pullRequests: aggregateByPr rows (top 20 by cost) plus the
multi-link-safe distinctCost/distinctSessions. Rows are by-reference, so
they are never summed.
- current.byBranch: new aggregateByBranch, per-branch spend (top 15 by cost)
that carries each session's last-seen git branch forward across its turns.
The cache stores a turn's branch only when it changes, so the parser now
resolves the branch at reconstruction (before the date slice) and records
SessionSummary.everHadBranch from the full transcript. That lets the report
keep a branch-bearing session's pre-branch spend in an explicit null row
even when the range clipped the anchor turn, while a provider that never
captures a branch still contributes nothing.
Part 2 (app): new "Pull requests" sidebar entry between Sessions and Spend
(shortcuts reflow to number 8 for Plans). It renders the pullRequests rows as
a refined table with the PR label linking out via openExternal, cost,
sessions, calls and an active-date span, plus a footnote stating the distinct
total and the by-reference attribution. A quiet explanatory line shows when no
PR links exist, never a fake table.
Tests: aggregateByBranch unit tests (carry-forward, null bucket, clipped
anchor, by-reference session counts) and the Pull requests component tests
(table, external link, footnote, both empty states). Nav-reflow assertions in
Sidebar and App tests updated.
Co-authored-by: reviewer <review@local>
The owner supplied the final flame render; the hand-retrace is retired.
Checkerboard keyed out to real alpha, composited to the Big Sur squircle
(824/1024, r185, charcoal #231613) as app/build/icon.png (the
electron-builder master, verified legible at 16px), and the flame-only
alpha PNG becomes the in-app mark: FlameMark now renders the raster so
splash, sidebar, About and dock are pixel-identical. Flicker applies to
the whole mark (raster has no separable core). Stale icon.svg removed.
Flame suites green in isolation; full suite re-verified before the
in-flight quota batch commits.
- FlameMark: hand-traced inline SVG of the brand flame (~1.1KB, warm
3-stop gradients, useId-scoped), used at splash and sidebar sizes
- Splash: full-window first-load overlay echoing the menubar's
BurnLoadingOverlay ignite moment; 600ms floor so warm cache never
blinks, 250ms crossfade on first data, instant yield on error or
reduced motion, done-latch so it never reappears
- Sidebar logo replaced with the live FlameMark: 1-2% inner-tongue
flicker, 4.5s period, random phase; static under reduced motion
250/250, build green (+2.4KB JS, +1.8KB CSS).
Sessions: provider-grouped list of every session in range (project,
models, turns, cost, tokens) with a lightweight real detail — no
fabricated titles, no unbacked context-window widget.
Compare: two-model picker (defaults to top two by cost) across
Performance, Efficiency, Category head-to-head, Working style, and a
derived Context panel, all mapped straight from `compare --format json`.
Nav reordered to match the design: Overview, Sessions, Spend, Optimize,
Models, Compare, Plans, Settings (⌘1-7).
Ports the wireframe window shell into React with exact markup/classes:
- Shared components: Window, Sidebar (traffic lights, gradient mark, six
nav items with ⌘ keycaps + active `on` rail, status line), TopBar
(title, scope, period SegTabs Today/7D/30D/Month/6M/Custom, ProviderPop),
Panel, Stat, SegTabs, ProviderPop, Hint.
- usePolled(fetcher, deps): generic 30s poll + loading/error state,
errors normalized to CliError.
- App.tsx: local section state switches the content outlet; the Overview
placeholder round-trips getOverview('30days','all') and renders the raw
current.cost, with an honest first-run "locate CLI" state when the
codeburn binary isn't found (never a crash).
- Sidebar.test.tsx: six nav items, click routes onNavigate, active `on`.