Commit graph

1190 commits

Author SHA1 Message Date
iamtoruk
700a52cd95 fix(app): packaged app finds node when spawning the CLI
GUI-launched apps inherit a minimal PATH without the user's node
install, so spawning the codeburn npm shim (#!/usr/bin/env node) failed
with 'env: node: No such file or directory' in packaged builds. Spawn
now augments PATH with the resolved binary's own directory (node sits
beside the shim in nvm, Homebrew, and npm-prefix layouts) plus the
resolver's search dirs. Dev never hit this because the terminal PATH
was inherited.
2026-07-16 08:39:30 -07:00
Resham Joshi
4abf5050b4
Merge pull request #682 from getagentseal/docs/macos-first-open
docs: macOS first-open is xattr, not right-click Open
2026-07-16 08:33:07 -07:00
iamtoruk
b5ceee93c6 docs(app): macOS first-open is xattr, not right-click Open; fix exe filename
Field-verified on macOS 15+: an ad-hoc-signed quarantined download gets
the damaged/move-to-Trash dialog and right-click Open does not bypass
it; the quarantine strip is the reliable path. Also updates the
Releases section to the hyphenated CodeBurn-Setup-<version>.exe
artifact name set via nsis.artifactName.
2026-07-16 08:32:25 -07:00
Resham Joshi
5869cad545
Merge pull request #680 from getagentseal/feat/desktop-win-linux-packaging
Desktop: Windows and Linux packaging targets
2026-07-16 08:06:44 -07:00
iamtoruk
69c1946c1c feat(app): Windows NSIS and Linux AppImage packaging targets
Cross-built from macOS alongside the existing mac config: nsis x64
(oneClick false, clean CodeBurn-Setup-<version>.exe artifact name) and
AppImage x64. DISTRIBUTION.md covers the new build commands, the
unsigned-build first-run steps per platform, and the desktop-v<version>
release tag convention the website pins.
2026-07-16 08:06:03 -07:00
Resham Joshi
b7e3bac263
Merge pull request #679 from getagentseal/feat/desktop-app
CodeBurn Desktop: standalone Electron app
2026-07-16 07:54:05 -07:00
iamtoruk
1b600d1c82 Merge origin/main into feat/desktop-app
Resolves menubar-json conflicts: main's granular-history timeline
param unions cleanly with this branch's providerDetails and currency
payload additions; both new tests kept.
2026-07-16 07:52:28 -07:00
kronos
68ad0be18b
fix(antigravity): stamp mtime fallback at emission, tighten path classification (#612)
* feat(antigravity): add support for Antigravity IDE storage on Windows

CodeBurn previously only detected Antigravity CLI usage (.pb files under
.gemini/antigravity/). Antigravity IDE on Windows stores session state in
VSCode-style storage at %APPDATA%\Antigravity IDE\User\globalStorage\state.vscdb,
which was not detected.

Add support for reading Antigravity IDE sessions from the VSCode-style storage:
- Extend CONVERSATION_ROOTS to include APPDATA Antigravity IDE path
- Refine path classification to properly identify IDE vs CLI sessions
- Handle missing per-call timestamps by stamping file mtime as fallback
- Bump CACHE_VERSION to 4 for cache invalidation

Fixes: CodeBurn reports zero usage when Antigravity IDE is actively used.

* fix(antigravity): stamp mtime fallback at emission, tighten path classification

- Apply the mtime fallback to a copy at emission instead of mutating and
  persisting it into the cache, so a later file rewrite can't retro-date a
  session's history to the new mtime. SQLite gen_metadata rows have no real
  per-call time; the RPC path still uses chatStartMetadata.createdAt.
- Drop the unreachable APPDATA classifier branch (discovery only walks the
  ~/.gemini roots; APPDATA state.vscdb holds no token usage). This also removes
  the misroute of base-antigravity paths under an "Antigravity IDE" profile dir.
- Bump CACHE_VERSION to invalidate caches that persisted a synthesized mtime.

* fix(antigravity): stabilize untimestamped call times across DB rewrites

Extract ChatStartMetadata.created_at from proto-encoded data and decode multiple timestamp formats (ISO string, Timestamp submessage, unix varint). Implement assignStableTimestamps() to preserve first-seen timestamps across file rewrites, preventing retro-dating of sessions when .db files are modified. Make conversation roots dynamic (computed per call) to honor environment overrides in tests. Add comprehensive timestamp stability tests verifying that timestamps remain fixed across file mtime changes while respecting date-range filters.

* test(antigravity): assert today range excludes first-seen timestamps

Adds a test case to verify that the 'today' date range filter correctly excludes sessions based on their first-seen timestamp, not file modification time. This ensures that even if a database file is rewritten with a later mtime, sessions with earlier first-seen dates are properly filtered out.

Refs #411
2026-07-16 07:49:54 -07:00
Resham Joshi
4307542b62
feat(claude): account for /advisor escalations under the advisor model (#659)
* feat(claude): account for /advisor escalations under the advisor model

Claude Code's advisor tool (/advisor) escalates hard decisions mid-turn
to a stronger model. Those tokens are recorded inside
message.usage.iterations as advisor_message entries with their own model
and are excluded from the top-level message.usage totals. The parser read
only the top-level totals, so advisor spend was silently dropped and never
attributed to the advisor model.

Emit a separate call per advisor_message iteration priced under the
advisor model, preserve those iterations through entry compaction and the
large-line (>32KB) byte-scanner path, and fold advisor cost into the guard
budget. Bump the claude parser and guard cache versions so existing caches
re-parse and pick up the advisor spend.

* test(guard): pin advisor cost fold in the live budget

The guard's advisor fold in computeSessionUsage had no test; dropping
advisorCost from the line cost left all 30 guard tests green. Pins the
fold (advisor line costs more than the same line without iterations)
and the per-message replace semantics under streaming rewrites.
2026-07-16 07:42:49 -07:00
iamtoruk
3ea43ea5a5 chore(app): version tracks the CLI (0.9.15)
One CodeBurn version across CLI, menubar, and desktop; splash, About,
and artifact names all read app/package.json. Documented in
DISTRIBUTION.md.
2026-07-16 07:30:49 -07:00
iamtoruk
5ceaf6bd52 docs(app): DISTRIBUTION.md states the codeburn CLI prerequisite
A packaged DMG on a machine without the CLI opens into the 'CLI not
found' state; the distribution doc now says so up front, with the
install command and the future bundle-the-CLI path.
2026-07-16 07:21:22 -07:00
iamtoruk
2c66601b47 feat(app): package the desktop app for unsigned macOS distribution
electron-builder config with ad-hoc signing (identity "-", not null,
which skips signing and breaks Apple Silicon), dmg+zip for arm64 and
x64, org.agentseal.codeburn-desktop bundle id matching the menubar
convention, icon reused from build/icon.png. DISTRIBUTION.md documents
the build, verification, the Gatekeeper first-open steps for
unnotarized builds, and the later paid-notarization upgrade path.
2026-07-16 07:16:34 -07:00
iamtoruk
9517d63ba3 fix(app): loader video floats with real alpha (no background)
The h264 loader baked a flat dark background that read as a rectangle
against the splash's warm radial tint. Re-encoded from the original as
VP9 WebM with an alpha channel (checker keyed to transparency), so the
burning flame composites directly onto the gradient. Verified over a
contrasting test canvas.

273/273, typecheck + build green.
2026-07-16 06:22:32 -07:00
iamtoruk
8d1a10369f fix(app): quota connects via macOS keychain + Connect affordance
Root causes (verified live): the Claude keychain branch was never
enabled (allowClaudeKeychain never passed), security -w returns
hex-encoded JSON the parser rejected, and Codex had no keychain
discovery at all.

- shared readKeychainPassword: Apple-signed /usr/bin/security, 90s
  window so the user can answer the macOS dialog, hex decode,
  notFound vs accessDenied classification; secrets never logged
- Claude: keychain fallback active (gated to explicit Refresh so
  launch never ambushes with a dialog); connection retained across
  keychain-less background polls
- Codex sources in order: the menubar's own cached OAuth (read-only,
  401 = one re-read, never rotate), legacy ~/.codex/auth.json
  (writable), com.openai.codex plaintext if usable; Safe Storage
  never decrypted
- new accessDenied state (amber, 'locked') + ConnectAffordance on
  Plans cards and Settings rows: login command, keychain-Allow note,
  force Refresh

Live verification: Claude connected with its real tier and windows;
Codex correctly accessDenied until the keychain dialog is allowed.

273/273 (26 files), typecheck + build green.
2026-07-16 06:20:44 -07:00
iamtoruk
000e39a034 feat(app): binary-flame brand art + animated video loader on the splash
New owner-approved art: the binary-digit flame. Checkerboard keyed out,
largest-component masking to drop glow-zone checker fringe, clean
synthetic ember glow rebuilt; composited to the Big Sur squircle as
app/build/icon.png and squared with alpha as the in-app FlameMark
raster (sidebar, About, static splash).

The supplied burn animation becomes the splash loader: checker keyed
per-frame and the splash's fixed dark canvas (#171310) baked in (h264
has no alpha), audio stripped, 944KB looping video shown while the
first scan runs. Splash canvas and text colors are now theme-fixed so
video and page never diverge; reduced motion/tests keep the static
mark, verified by test.

Flame/splash/motion suites green in isolation (full suite re-verified
when the in-flight quota batch commits); typecheck + build green.
2026-07-16 06:19:12 -07:00
iamtoruk
38eef9b298 chore(app): drop superseded icon.svg trace source
The raster master (app/build/icon.png) from the approved art is now
canonical; the hand-traced SVG would only drift from it.
2026-07-16 06:10:54 -07:00
iamtoruk
0fa202b110 feat(app): exact approved flame art everywhere
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.
2026-07-16 06:10:22 -07:00
iamtoruk
3a0f4b2fb9 feat(app): retraced brand flame — one mark for icon, splash, sidebar, About
- app/build/icon.svg + icon.png: hand-retraced vector of the approved
  reference (three flat layers: coral #e86c39, amber #f7943c, cream
  #fecb8b on charcoal #231613), Big Sur squircle proportions (824/1024,
  r185, transparent corners, no glow), flame ~72% optically centered;
  8 render-and-compare iterations against the reference; legible at 16px
- FlameMark retraced to the same three paths (flat fills, no gradients);
  flicker now animates the cream core only
- AboutModal renders FlameMark instead of the old gradient flame.png;
  orphaned 70KB asset removed

253/253, typecheck + build green.
2026-07-16 05:54:40 -07:00
iamtoruk
1320807de2 polish(app): splash wordmark in brand orange + version line
CodeBurn wordmark on the splash now uses --accent (matching the
website/sidebar brand treatment) with the app version (v0.1.0, from
package.json at build time) in muted small text below. App version
bumped 0.0.0 -> 0.1.0.

253/253, build green.
2026-07-16 05:15:35 -07:00
iamtoruk
4b1426eab2 polish(app): consistency review nits
Loading quota label matches sibling skeleton labels (Sentence case);
matchMedia test stub deduped into lib/testMatchMedia.

253/253, typecheck + build green.
2026-07-16 05:11:10 -07:00
iamtoruk
cee0f3501d feat(app): Plans settings detect subscriptions automatically
Detected subscriptions card (Claude/Codex): auto-detected tier from the
live quota with a connect hint when logged out — like the menubar,
never a fixed preset. Manual budget presets now only for providers
without OAuth quota (Cursor/SuperGrok); configured claude/codex manual
plans stay listed for removal with a superseded note. The Plans
dashboard already excludes them next to the authoritative live quota.
2026-07-16 05:11:10 -07:00
iamtoruk
0f836db72f fix(app): flame mark is the real menubar flame
Replaces the rejected hand-traced silhouette with Bootstrap Icons'
fire path (MIT, embedded with license note) — the flame.fill-style
teardrop with the inner tongue — filled with the menubar BurnFlame's
actual Ember gradient from the Swift theme (#f0a070 > #e8774a >
#c9521d > #8b3e13, bottom to top), not the brighter accent ramp.
Flicker hook moves to the whole mark (single compound path).
Also: .splash-word snapped to var(--fs-kpi).
2026-07-16 05:11:10 -07:00
iamtoruk
76bc80ca67 polish(app): skeleton loaders for Compare and the Audit lens
The motion batch gave five sections shimmer skeletons on first load but
missed Compare and Models' Audit lens (both still showed bare loading
text in an empty panel). Same SectionSkeleton treatment now.

250/250.
2026-07-16 05:04:50 -07:00
iamtoruk
6c548c9883 fix(app): fallback provider ids must round-trip as --provider
Old-CLI fallback derived picker ids from providers-map keys (lowercased
display names); a key with a space ('grok build') passed to --provider
was rejected by the app's own validator, erroring the fetch and leaving
stale data under the new filter's header. Exclude keys that cannot
round-trip. (Primary fix is running the current CLI: rebuilt dist.)
2026-07-16 05:01:11 -07:00
iamtoruk
77f791376a feat(app): flame splash startup loader + living sidebar flame
- 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).
2026-07-16 04:51:30 -07:00
iamtoruk
daf944e714 feat(app): motion layer (gsap) — count-ups, chart grow-in, section fade, skeletons, toasts
- one gate (motionEnabled): off under reduced-motion, missing matchMedia,
  and vitest; every path checks it first
- mount/filter-change only: count-up and bar grow-in key off the
  period|provider|range key, so 30s poll refreshes snap values silently
  instead of re-animating
- first-load skeleton shimmer replaces bare scanning text (kept sr-only
  for screen readers); slide-in toast host for Settings/export feedback
  (validation errors stay inline); CSS hover-lift + press micro-
  interactions, all with a reduced-motion escape hatch
- gsap 3.15.0 + @gsap/react 2.1.2 (+74KB raw JS; G4 flame work shares it)

244/244, typecheck + build green.
2026-07-16 04:39:09 -07:00
iamtoruk
26ffd60e0f polish(app): retire the legacy token family
Every var(--t1/--t2/--t3/--hair/--hair2) and secondary legacy color
(--lav/--amber/--red/--mint/--blue/--purple/--cyan) repointed to the
canonical family (--ink/--mut/--mut2/--line/--line2, --warn/--bad/--ok,
--s-*); all legacy definitions and the plain.css alias shim deleted.

The explicit dark/light theme blocks carried drifted legacy literals
(including a pre-contrast-fix --t3), so this also extends the AA
contrast values to all four theme modes, which previously disagreed
with system-light.

grep-proven zero legacy usages. 235/235, build green.
2026-07-16 04:16:44 -07:00
ihearttokyo
ccd8764e5b
feat(dashboard): make Daily Activity history directly scrollable (#672)
Some checks are pending
CI / semgrep (push) Waiting to run
* feat(dashboard): add inline daily history paging

* refactor(dashboard): make daily activity directly scrollable

* fix(dashboard): keep the empty state for users with no history at all

Scrollable mode kept the dashboard shell up whenever full history exists,
but a truly-new user with zero data anywhere saw a zeroed skeleton instead
of the No usage data message. Extract the decision into showEmptyState so
the boundary is test-pinned: empty period with history renders the shell,
empty everything renders the empty state, and the loading pass never
flashes it.

---------

Co-authored-by: AgentSeal <hello@agentseal.org>
2026-07-16 04:10:08 -07:00
iamtoruk
0eb0fd60d7 polish(app): spacing scale, unified insets, shared banner classes, scrollbar cues
- --sp-1..7 scale; card headers unified on 10x14, bodies on 12x14;
  orphan gaps snapped to rungs
- CapsuleChart's orphaned CSS deleted
- StaleBanner/budget/empty/range notes moved from inline styles to
  plain.css classes; Panel bodyStyle prop retired (scroll-x class)
- thin always-visible scrollbars on scrolling panels and overflow-x
  tables; Compare pickers flex below 760px instead of overflowing
- one capitalization fix (loading quota…)

235/235, build green.
2026-07-16 04:02:21 -07:00
iamtoruk
edaa284c0f feat(app): Audit lens on Models + Pricing pane in Settings
- Models gains an Audit lens: raw provider token fields vs displayed
  totals and cost derivation per model, est badge where pricing is
  missing or recomputed cost diverges from attributed
- Settings Pricing pane: list/add/remove price overrides (USD per 1M),
  inline confirm on remove, only provided rates sent; rates validated
  finite and strictly positive on both sides of the bridge
- four new IPC channels with the established validation pattern

Root 1617/1617, app 235/235, build green.
2026-07-16 03:45:36 -07:00
iamtoruk
699ca53979 feat(cli): price-override --list --format json 2026-07-16 03:45:36 -07:00
iamtoruk
09ac453fcc feat(app): coaching signals card (menubar rule parity)
Replaces the three-rule anomaly card with a Wins/Improvements/Risks
Signals card mirroring the menubar's rule set and thresholds
(FindingsSection.swift): cache >=80% and one-shot >=0.75 and spend-down
>10% and streak >=5d as wins; top-3 optimize findings, low cache <50%,
low one-shot <0.5, retry tax >=25% of spend as improvements; weekday
spike >1.8x, week-over-week >+25%, projected month >1.3x prior month as
risks. Time-comparison rules suppressed under a custom range. Renders
nothing when empty; icons per group, never color-alone. Anomaly test
coverage ported, not deleted.

221/221, build green.
2026-07-16 03:30:51 -07:00
iamtoruk
93349e7eba feat(app): daily budget alert (USD or token cap)
- Settings/General: Daily budget row (Off / USD amount / Tokens),
  positive-finite validation, warns at 80% and alerts at 100%
- app-wide one-line banner above every section: --warn at 80%+, --bad
  at 100%+, dismissible for the rest of the day
- USD caps compare raw USD against per-provider daily cost (works under
  any filter); token caps evaluate only on the all-providers view since
  provider-filtered history zeroes token fields (comparing against a
  false zero would always pass)

212/212, build green.
2026-07-16 03:16:07 -07:00
ozymandiashh
df78e50052
feat: add CodeWhale provider support (#674)
Co-authored-by: AgentSeal <hello@agentseal.org>
2026-07-16 03:12:28 -07:00
iamtoruk
55fdbfd761 feat(app): Claude config switcher (multi-account overview scope)
- TopBar picker (shown only when >1 Claude config dir exists) threads
  --claude-config-source through getOverview; synthetic 'All Claude
  configs' entry returns to the aggregate default
- config id validation accepts the real <kind>:<16hex> id shape while
  still rejecting flag-shaped input (leading char anchored)
- both incompatibility directions handled: selecting a config resets a
  non-Claude provider filter, and picking a non-Claude provider clears
  the config scope, so the CLI rejection is unreachable
- choice persisted (localStorage); active config shown in the scope
  line and read-only in Settings/General

Verified live against 2 real config dirs. 205/205, build green.
2026-07-16 03:06:05 -07:00
ozymandiashh
5d366fb03b
feat(dashboard): add granular session and model timelines (#673)
* feat(dashboard): add granular usage timelines

* fix(dashboard): readable timeline legend and month-scale buckets

Session legend labels now use the real projectPath's last two segments
(app/web) instead of the sanitized project dir, which rendered as an
unreadable -Users-name-... dump and truncated in the legend.

Hourly buckets now cap at 8 days; longer ranges bucket daily. A 30-day
window rendered 720 overlapping hourly spikes, unreadable as a chart.

The browser no longer gives the backend session_other/model_other
aggregate a top-N slot, which rendered two identical Other legend
entries whenever the backend fold out-ranked a real series.

---------

Co-authored-by: AgentSeal <hello@agentseal.org>
2026-07-16 03:04:54 -07:00
iamtoruk
f8b2894b4e feat(app): Sessions provider quick-filter + Spend project inline expand
- Sessions: All + per-provider logo buttons (detected, cost > 0) that
  drive the same app-level provider state as the top-bar dropdown, so
  the two controls can never disagree; aria-pressed group semantics
- Spend By project: rows expand inline (single-open, aria-expanded,
  chevron rotation) to the project's sessions: date, top model, calls,
  currency-aware cost; date-only strings parsed at local noon so days
  never roll across time zones

194/194, typecheck + build green.
2026-07-16 02:49:17 -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
ozymandiashh
1e54c693b6
fix(opencode): support custom data dir and db prefix (#620)
Co-authored-by: AgentSeal <hello@agentseal.org>
2026-07-16 02:18:19 -07:00
ozymandiashh
e2d006be9d
fix(claude): support Windows Desktop sessions via APPDATA (#615)
* fix(claude): use APPDATA for Windows Desktop sessions

* test(claude): harden withPlatform mock against cross-file leak

The process.platform mock omitted configurable:true and never restored
the value when the property had no own descriptor, leaving win32 mocked
for later tests on the same Vitest worker. Add configurable + an else
branch that deletes the override to expose the real inherited value.

---------

Co-authored-by: AgentSeal <hello@agentseal.org>
2026-07-16 02:13:11 -07:00
ozymandiashh
4ef32c27cb
fix(optimize): exclude a young project's founding session from cost-outlier detection (#666)
A project's first/bootstrap session is a different kind of work (one-off
scaffolding), not an expensive instance of routine work. While a project is
still young its peer sample is thin, so the leave-one-out average is dominated
by a few routine sessions and the founding session's legitimately high one-off
cost trips the >2x outlier multiplier. Exclude each young project's earliest
costed session from the outlier finding only; mature projects are unaffected so
genuine outliers still surface. Young = fewer than 2x MIN_SESSIONS_FOR_OUTLIER
costed sessions.

Fixes #664
2026-07-16 02:03:06 -07:00
iamtoruk
916aa6430f harden(app): Electron security + spawn efficiency batch
- will-navigate/window-open denied; openExternal restricted to http(s);
  production CSP drops 'unsafe-inline' scripts (dev-only Vite plugin
  re-adds it for the Fast Refresh preamble)
- single-instance lock; before-quit reaps in-flight CLI children; 16MB
  output cap rejects with CliError 'too-large'
- read-only CLI spawns coalesce: concurrent identical calls share one
  child, a 5s result cache absorbs same-cadence pollers (six sections
  polled getOverview independently); actions bypass and flush the cache
  on completion so post-action refetches are fresh
- every renderer-supplied argv string validated (period/provider/range/
  currency allowlists, no flag-shaped tokens, absolute export path) with
  new CliError kind 'bad-args'; envelope + action stderr routed through
  sanitizeError
- quota force-refresh: manual refresh (refreshToken) passes force which
  invalidates QuotaService's cache; steady polls do not
- POSIX credential mode check gated off on win32

App suite 190/190, build green (production index.html verified strict).
2026-07-16 01:57:44 -07:00
ozymandiashh
e2cba003a8
Include archived Codex sessions in usage reports (#667)
Co-authored-by: zhangshihao03 <zhangshihao03@baijia.com>
2026-07-16 01:55:25 -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
a916981107 feat(cli): yield --provider filter
yield always analyzed all providers, so provider-filtered GUI panels
(cost per outcome, reverts, abandoned) showed all-provider numbers
under a filtered header.
2026-07-16 01:36:59 -07:00
iamtoruk
599764f39c feat(cli): menubar payload carries provider ids and active currency
ProviderCost now keeps the internal id alongside the display name. The
providers map keys stay lowercased display names (byte-identical, the
Swift menubar decodes them); new current.providerDetails exposes
{id,label,cost} so GUI clients can round-trip a valid --provider value.
New top-level currency {code,symbol,rate}: payload values remain raw
USD, clients convert at display time like the Swift menubar does.
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
44d2449d30 fix(cli): compare cache-hit rate excludes cache writes
Compare defined cache-hit as read/(input+read+write) while menubar-json
and every other surface use read/(input+read), so the same model showed
two different numbers depending on screen. Standardize on the latter;
TUI compare output changes intentionally.
2026-07-16 01:14:41 -07:00
iamtoruk
90f1d9ae1a fix(cli): optimize accepts --from/--to for custom date ranges
The desktop app's getOptimizeReport handler already appends --from/--to
when a custom range is active; without these options commander rejects
the invocation and the Optimize screen errors under a custom range.
2026-07-16 01:14:25 -07:00
Resham Joshi
405489f460
Merge pull request #665 from Enclavet/kiro_v2
Kiro: IDE v2 session store support + credit-based pricing across all formats
2026-07-16 00:18:11 -07:00