Commit graph

10 commits

Author SHA1 Message Date
iamtoruk
300e949951 feat(app): refresh cadence, instant switching, cache coherence, telemetry v1
Performance and coherence:
- Settings > General 'Refresh every' (Manual/30s/1m/3m/5m/10m), live via
  RefreshCadenceContext; Manual polls only on demand
- usePolled memoKey LRU: provider/period switches paint the last-good
  result instantly with a switching hairline while refreshing quietly
- quota TTL 5min + honest rate-limited copy on 429 backoff
- version-suffixed cache files (session-cache.v5.json, daily-cache.v12,
  auto-minted on future bumps); legacy files never written or deleted,
  adopted once when versions match: old and new binaries coexist
  without clobbering (field-observed menubar-vs-desktop ping-pong)
- advisory hydration lock: concurrent cold starts share one scan
  (wait-then-read-warm), stale/dead locks self-heal, never a
  correctness gate

Telemetry v1 + onboarding (desktop only, per owner decisions):
- first-launch onboarding (3 feature screens + consent); region-split
  default (EU/EEA/UK/CH off, elsewhere on, unknown off); nothing sends
  before consent completion or while off; dev builds never send
- anonymous install UUID, rotated on opt-out; day-granularity events,
  cost buckets only; whitelisted names; 200-event queue, 5min flush
- Settings > Privacy live toggle replaces the static claim

Zero computed-number changes. App 316/316, root 1805.

Wire contract targets api.codeburn.app/v1/telemetry (Worker follows).
2026-07-16 11:47:05 -07:00
iamtoruk
015a1a069a polish(app): shared empty states, type ladder, AA contrast, honest affordances, a11y semantics
D1 one shared EmptyNote (7 copies removed); CliErrorPanel on canonical
   tokens; dead code deleted (CapsuleChart, stale SERIES_HEX palette,
   Stat tone API, unused rail/doc-chrome CSS)
D2 type ladder tokens (--fs-*/--fw-*); panel titles unified 13/600/ink;
   high-visibility sizes/weights snapped to rungs
D3 contrast: --mut2 5.00:1 light / 5.74:1 dark (was 2.37/3.11); new
   --accent-text 5.07:1 + persistent underline on text links; last
   prose em-dash removed
D4 'See all' and 'Most expensive sessions' navigate to Sessions; 'add
   alias' jumps to Settings/Aliases; chevrons only on clickable rows;
   inline confirm replaces window.confirm; default-period setting
   honored at boot; Sankey caption no longer promises a click; Optimize
   'improving' trend badges; cursor + Space-key fixes
D5 aria-current on nav, SegTabs as real tablist, aria-pressed toggles,
   ProviderPop rebuilt on Dropdown (one tab stop, arrow keys, focus ring)

191/191, typecheck + build green. Contrast ratios independently
recomputed. Net -93 lines.
2026-07-16 02:27:41 -07:00
iamtoruk
8a3fa69fe9 fix(app): real currency conversion, provider ids in picker, yield provider scoping
- formatUsd applies the payload currency {code,symbol,rate} once at
  display; formatConverted (symbol only) for CLI-preconverted plan
  values so nothing converts twice
- provider picker built from providerDetails: label shown, internal id
  sent as --provider (fixes filters for providers whose display name
  differs, e.g. Grok Build); falls back to map keys on older CLIs
- getYield threads the active provider through preload/main/sections

App suite 170/170, root 1615/1615.
2026-07-16 01:36:59 -07:00
iamtoruk
cbddd3a9d7 fix(app): accuracy batch A — provider scoping, honest chart axes, range threading, stale-error banner
- Provider filter: Models-this-period sources current.topModels (history
  days carry empty topModels per provider); StackedBars falls back to a
  cost-proportional single segment like the Swift menubar
- Chart windows align to the CLI (week -7, 30days -30, all = 6 months)
  and zero-fill a contiguous calendar window; history.daily is sparse and
  both sides key local YYYY-MM-DD, so lookups are safe (verified on real
  CLI output)
- Custom range threads into Overview panels (chart, models table) and
  suppresses MTD/projected and vs-last-week comparisons; Compare states
  that custom dates fall back to the period
- usePolled clears errors per attempt and sections show a StaleBanner
  instead of silently rendering last-good data after a failed refresh
- Cache-hit denominator matches the CLI; hero savings relabeled 'Saved by
  applied fixes' + new 'Saved via local models' line; formatCompact
  everywhere; Optimize 'Fixes' count matches the rendered list

App suite 163/163 (was 147), root 1613/1613.
2026-07-16 01:14:41 -07:00
iamtoruk
905d94253a feat(app): actionable Optimize — wire the CLI's rich findings + copy-paste fixes
- new getOptimizeReport bridge (main + preload + renderer types) running
  `codeburn optimize --format json` (needs a full relaunch)
- restore the Waste / Reverts / Abandoned / Fixes tabs
- Waste findings expand inline to show the explanation (why you're losing
  tokens) + a copy-paste fix block with a Copy button, like the TUI
- summary header: findings count / potential savings / health score

typecheck clean; 133/133 tests pass.
2026-07-12 16:28:47 -07:00
iamtoruk
0bab74c18d feat(app): flatten Optimize to one page (no tabs)
Drop the Waste/Reverts/Abandoned/Fixes tabs. One scrolling page: findings
(count + potential in the header), then Reverted and Abandoned session sections;
empty sections hidden. The redundant Fixes tab folds into the findings header.

typecheck clean; 126/126 tests pass (removed 2 now-moot tab-isolation tests;
impact-badge + section coverage preserved).
2026-07-12 15:34:16 -07:00
iamtoruk
76a5db4f55 feat(app): Optimize organization + gear icon, more logos, drop relative-cost column
- Optimize: colored impact badges (High/Medium/Low) + fixed-column layout;
  fix the dead "Fixes" tab; findings no longer look falsely clickable
- Optimize nav icon: gear + magnifying glass (was a lightning bolt)
- remove the "Relative cost" bar column from the Overview models table
- provider logos: Goose / Pi / Warp + Cursor Agent (own logo) from repo assets

typecheck clean; 128/128 tests pass.
2026-07-12 13:56:07 -07:00
iamtoruk
f362195946 fix(app): final-review nits — app menu (⌘R refresh), honest model labels, yield retain, hint cleanup
Install an app menu without the CmdOrCtrl+R reload accelerator so ⌘R reaches the renderer for
in-place refresh (keeps Edit/Window roles + dev DevTools). Model labels are now family-level
("Opus"/"Sonnet"/"Haiku"/"GPT / Codex") and the Sankey shows the real model id instead of the
wireframe's sample version names. Optimize retains last-good yield across 30s revalidation (no
flicker to "—"). Removed hints for unimplemented ⌘K/⌘E/esc; fixed stale TopBar comment.

Implemented by Codex gpt-5.5 (high); committed by Fable (git blocked in Codex sandbox).
2026-07-10 19:54:09 -07:00
iamtoruk
87f5a9bac1 fix(app): Optimize — honest em-dash on yield failure, +Abandoned/Fixes tab tests, cost semantics
Reverts/Abandoned totals + bodies show "—" while yield is loading/errored instead of a fake
$0.00; adds positive-path Abandoned and Fixes-tab tests (guards category filtering); reverted/
abandoned costs use plain .val (mint reserved for savings); simplified FixesRows copy.

Implemented by Codex gpt-5.5 (high); committed by Fable (git blocked in Codex sandbox).
2026-07-10 18:42:52 -07:00
iamtoruk
39d2f79ef3 feat(app): Optimize section — Waste/Reverts/Abandoned/Fixes tabs with dollar totals
Segment tabs carry their totals (Waste=optimize.savingsUSD, Reverts/Abandoned from
getYield summary, Fixes=findingCount). Waste findings from optimize.topFindings; reverts
and abandoned lists from yield.details by category. Evidence lines + copy-fix chips are
honestly omitted (not present in MenubarPayload.optimize) — a richer `optimize --format
json` emitter is flagged as a follow-up.

Implemented by Codex gpt-5.5 (high); committed by Fable (git blocked in Codex sandbox).
2026-07-10 18:33:54 -07:00