Commit graph

467 commits

Author SHA1 Message Date
Resham Joshi
f92d57d24a
feat(optimize): detect context-heavy sessions
Adds a context-bloat finding to codeburn optimize that flags sessions where effective input/cache tokens (cache-discounted via existing pricing constants) are large and disproportionate to output. Suggests starting fresh with a tightened context. Sessions flagged here are excluded from the cost-outlier finding to avoid double-listing. Growth-from-previous-session callouts are suppressed when the predecessor is more than 7 days back. Three impact tiers (low/medium/high). Supersedes #242 with review fixes from real-data probe. Original implementation by @ozymandiashh.
2026-05-06 00:11:12 -07:00
Resham Joshi
6151cf6d73
fix(parser): use Claude cwd for Windows project paths
Reads the canonical cwd already stored inside Claude session JSONL files and uses it as the project path, then groups sessions by a normalized path key (case + slash insensitive) so Windows projects no longer split into 3+ rows on case/slash variants. Falls back to the legacy slug-derived path when cwd is missing. Closes #217. Supersedes #228 with a fix that preserves the canonical cwd even when mixed with slug-only sessions in the same directory. Original implementation by @ozymandiashh.
2026-05-05 23:53:31 -07:00
Resham Joshi
be6068b244
feat(report): add per-model efficiency metrics
Adds per-model efficiency metrics (edit turns, one-shot rate, retries/edit, cost/edit) to the TUI By Model panel, JSON report output, and CSV export. Closes item 4 of #12. Supersedes #226 with review fixes (units rename, min-sample guard in TUI, tighter <synthetic> filter, multi-model attribution test). Original implementation by @ozymandiashh.
2026-05-05 23:36:59 -07:00
ozymandiashh
fc4c4f0091
feat(export): support custom date ranges 2026-05-05 23:18:48 -07:00
iamtoruk
869474b3b4 Fix update button stuck spinning after successful install
Some checks are pending
CI / semgrep (push) Waiting to run
terminationHandler only reset isUpdating on non-zero exit, assuming
the app would be killed and relaunched on success. If pkill fails
silently the old process survives with isUpdating stuck true. Now
always resets on termination and clears the update badge on success.
2026-05-05 11:38:54 -07:00
iamtoruk
18c3c8f908 Fix stale menubar data after sleep and silent refresh button
Cache now tracks the calendar date and clears on day rollover so
overnight sleep no longer shows yesterday's numbers. Wake-from-sleep
invalidates the entire cache before fetching. Manual refresh and wake
explicitly request loading feedback so the spinner is visible even
when stale data exists.
2026-05-05 11:35:38 -07:00
Resham Joshi
474c71a77b
Merge pull request #220 from NihalJain/fix_copilot_auto
fix: update model aliases and enhance event parsing for Copilot provider
2026-05-05 11:24:04 -07:00
iamtoruk
58b14c7561 Keep copilot-auto as provider-agnostic fallback
copilot-openai-auto maps to gpt-5.3-codex pricing, which is wrong
for users on Anthropic models. The original copilot-auto fallback
is provider-agnostic and correct when no model can be inferred.
2026-05-05 11:23:52 -07:00
iamtoruk
719432aaf4 Add session outlier detector and menubar spinner fix to changelog
Some checks are pending
CI / semgrep (push) Waiting to run
2026-05-04 23:12:46 -07:00
iamtoruk
c706cd2de2 Strip optimize from menubar, fix stuck loading spinner
The menubar ran --optimize on every 30-second CLI invocation. As
sessions accumulated throughout the day, optimize got heavier until
it exceeded the 45-second timeout. When the fetch failed with no
cached data, the loading overlay had no escape hatch and stayed
forever.

- Never pass includeOptimize from the menubar (background loop,
  forceRefresh, tab/period switches, manual refresh button)
- On fetch failure with empty cache, retry without optimize as
  fallback so the spinner always clears
- refreshQuietly also skips optimize
2026-05-04 23:11:42 -07:00
Resham Joshi
e7560052ed
Merge pull request #224 from ozymandiashh/feat/session-outlier-detection
feat(optimize): detect session cost outliers
2026-05-04 20:21:33 -07:00
iamtoruk
38d21643bd Merge origin/main into feat/session-outlier-detection 2026-05-04 20:21:26 -07:00
Resham Joshi
4ac8e8de34
Merge pull request #223 from ozymandiashh/feat/mcp-tool-coverage
feat(optimize): MCP tool coverage detector with cache-aware costing
2026-05-04 20:13:27 -07:00
iamtoruk
5120ec696c Merge origin/main into feat/mcp-tool-coverage 2026-05-04 20:13:15 -07:00
iamtoruk
735f41bc6c Fix cache-write pricing and shell-quote server names in fix commands
- Use 1.25x multiplier for cache-write tokens to match Anthropic's
  actual pricing (was incorrectly using 1x)
- Shell-quote server names in `claude mcp remove` fix text to prevent
  issues with unusual server names
2026-05-04 20:11:50 -07:00
iamtoruk
bfa5fe7fa0 fix(labels): update remaining 'all' period labels to '6 Months'
PR #221 unified the period logic but missed the TUI hotkey bar,
GNOME indicator popup, and macOS menubar app. All surfaces now
consistently show '6 Months' instead of 'All' or 'all time'.
2026-05-04 19:46:20 -07:00
Resham Joshi
32dfa8e165
Merge pull request #221 from ozymandiashh/fix/unify-all-period-semantics
fix(date-range): unify 'all' period semantics between CLI and dashboard
2026-05-04 19:43:28 -07:00
ozymandiashh
d18ba3d2fe feat(optimize): detect session cost outliers 2026-05-05 05:25:49 +03:00
ozymandiashh
e46b20b927 fix(optimize): reuse mcp coverage and type schema estimator 2026-05-05 05:11:00 +03:00
ozymandiashh
9a258a8a99 fix(date-range): avoid all-period month overflow 2026-05-05 05:05:13 +03:00
ozymandiashh
1a080a006f feat(optimize): MCP tool coverage detector with cache-aware costing
Adds a per-tool optimizer finding for MCP servers whose schema is loaded
on every turn but rarely invoked. Builds on the existing server-level
`detectUnusedMcp` (zero invocations) by reporting partial-use cases:
"loaded 54 tools, called 0" or "loaded 26 tools, called 2 (8% coverage)".

Inventory comes from Claude Code's JSONL `attachment.deferred_tools_delta`
entries: `addedNames` lists the exact tools available at that turn,
including every fully-qualified `mcp__<server>__<tool>` name. We union
across all delta entries in a session (not just the first) because tool
availability can change mid-session when the user reloads MCP config or
a subagent inherits a different tool set. Names that don't match the
`mcp__<server>__<tool>` shape with both segments non-empty are rejected
at extraction so downstream `split('__')` consumers can't be poisoned.

Token-savings estimates are cache-aware. MCP tool schemas live in the
cached prefix of the system prompt: a session pays the full input price
on each cache-creation turn (rebuilds happen every ~5 minutes of
inactivity) and the cache-read discount on subsequent turns. Each call's
contribution is capped at its observed `cacheCreationInputTokens` /
`cacheReadInputTokens` so we never claim more MCP overhead than the
call's own cache buckets could contain.

When multiple servers are flagged, costing happens in a single combined
pass: the per-call cap applies to the total unused-schema budget across
all flagged servers, not per server. Two flagged servers cannot both
independently claim the same call's cache bucket, which would otherwise
overstate `tokensSaved` and misclassify findings as high impact.

A session counts toward `loadedSessions` (and toward the cost estimate)
only if its observed inventory included the server. Pure invocation-only
sessions, where the server appears in `mcpBreakdown` or `call.mcpTools`
without any matching `deferred_tools_delta`, do not satisfy the
`>= 2 sessions` threshold on their own. The same invariant applies in
`estimateMcpSchemaCost` so the two passes agree.

Coverage is computed against the inventory only: invocations of names
not present in any observed inventory (older config, hallucinated tool,
typo) do not inflate `toolsInvoked` and cannot drive `unusedCount`
negative. `toolsInvoked` is derived as `inventory.size - unusedTools.length`
to keep both numbers consistent.

`detectUnusedMcp` and the new detector are explicitly disjoint:
`detectUnusedMcp` skips servers that the coverage detector will report,
not every server that happens to be in any inventory, so a small
inventoried-but-uninvoked server below the coverage thresholds still
gets flagged as "configured but never called."

Thresholds for the coverage finding:
- > 10 tools available (small servers are noise)
- < 20% coverage
- >= 2 sessions with observed inventory
- High impact when total effective tokens >= 200_000 or >= 3 servers flagged

Smoke-tested on a real account: 7 servers flagged across 93 sessions
(`office-word-mcp` 0/54, `notebooklm-mcp` 0/38, `office-ppt-mcp` 0/37,
`excel-mcp-server` 0/25, `github-mcp-server` 2/26, `peekaboo` 3/22, plus
`claude_ai_Asana`). Combined-cap costing keeps `tokensSaved` honest.

Changes:
- src/types.ts: optional `mcpInventory: string[]` on `SessionSummary`.
  Provider-agnostic field; currently populated only by the Claude parser.
- src/parser.ts: `extractMcpInventory` walks all entries, validates
  fully-qualified names, returns sorted unique list. `buildSessionSummary`
  passes it through; field is omitted when empty so JSON exports stay
  clean.
- src/optimize.ts: `aggregateMcpCoverage`, `estimateMcpSchemaCost`
  (single- and multi-server signatures), `detectMcpToolCoverage`. Wired
  into `scanAndDetect`. `detectUnusedMcp` updated to disjoint with the
  new detector.
- tests/mcp-coverage.test.ts: 23 cases covering aggregation, costing,
  combined-cap behaviour, threshold gates, invocation-only-session
  filtering, foreign-tool invocations, cache rebuild events, write+read
  on the same call, multi-server pluralisation.
- tests/parser-mcp-inventory.test.ts: 12 cases for the JSONL extractor
  including malformed name rejection and tolerant attachment parsing.
- CHANGELOG.md: entry under Unreleased / Added (CLI).

Closes #2
2026-05-05 04:13:04 +03:00
Resham Joshi
f5cbfe28bb
Overhaul GNOME Shell extension with full-featured UI (#222)
Some checks are pending
CI / semgrep (push) Waiting to run
* Rewrite GNOME extension UI with branded popover matching macOS menubar

Combines PR #212's modular architecture (DataClient, GSettings, Libadwaita
prefs) with the custom St widget UI from feat/tauri-menubar-win-linux.

Adds: branded header, horizontal agent tabs, hero typography, period/insight
pills, 19-day token histogram, 6 content views (Activity, Trend, Forecast,
Pulse, Stats, Plan), currency switcher with FX conversion, findings CTA,
budget alerts, theme detection, payload caching with TTL.

* Add Main.panel.addToStatusArea call to extension entry point

* Align activity/model rows as table with separators, gear icon for prefs

* Add table column headers, oneshot placeholder, currency picker dropdown

* Enhance GNOME extension with scrollable UI, dark mode, charts, and performance fixes

- Add vertical scroll for popup content and horizontal scroll for 6+ provider tabs
- Add token histogram chart with hover tooltips showing date, in/out tokens, cost
- Add skeleton loading animation with stale-while-revalidate caching (5min TTL)
- Add dark/light theme support with force-dark-mode setting
- Add exact costs toggle for full decimal values
- Add right-aligned columns for cost, turns, oneshot, and model data
- Remove unsupported St CSS properties (text-align, letter-spacing)
- Fix post-destroy crash: guard async callbacks, abort Soup session on teardown
- Fix dataClient double-resolve race with settled guard
- Expand PATH resolution for volta, bun, cargo, asdf, fnm, pnpm
- Reduce CLI timeout from 45s to 15s and cache augmented PATH
- Remove unused imports (Pango, Main) and dead constants
- Show 10 top activities, remove Plan pill
2026-05-04 18:05:59 -07:00
ozymandiashh
3dc3e32715 fix(date-range): unify 'all' period semantics between CLI and dashboard
`getDateRange` was duplicated across `src/cli.ts` and `src/dashboard.tsx`
with conflicting semantics for `'all'`. The CLI intentionally bounded
`'all'` to the last 6 months (justified inline: keeps Codex/Cursor parses
responsive on sparse multi-year history). The dashboard returned
`new Date(0)` instead, so the same `--period all` flag silently meant
two different windows depending on which entry point you hit.

`Period`, `PERIODS`, `PERIOD_LABELS`, and `toPeriod` were duplicated as
well, and `cli-date.ts` already existed for date helpers
(`parseDateRangeFlags`) so the consolidation lives there.

Both call sites now go through a single `getDateRange(period: string)`
in `cli-date.ts` that returns `{ range, label }`. The dashboard wraps it
as `getPeriodRange(period: Period)` to keep the strict `Period` type at
the React boundary while letting the CLI continue to accept extras like
`'yesterday'`.

`PERIOD_LABELS.all` becomes `'6 Months'` (short, for the dashboard tab
strip; the previous `'All Time'` was misleading and the long-form
`'Last 6 months'` from `getDateRange().label` already drives CLI output).

Changes:
- src/cli-date.ts: add `Period`, `PERIODS`, `PERIOD_LABELS`, `toPeriod`,
  `getDateRange`. Pull the existing 6-month rationale into a named
  `ALL_TIME_MONTHS` constant.
- src/cli.ts: drop the local copies and import from cli-date.
- src/dashboard.tsx: drop the local copies, route through
  `getPeriodRange`, alias the shared `getDateRange` import to
  `getDateRangeShared` to avoid shadowing the wrapper.
- tests/cli-date.test.ts: 13 cases covering `'all'` regression guard
  (must never silently fall back to `Date(0)`), CLI/dashboard agreement,
  end-of-month clamping tolerance, `'yesterday'` support, and
  unknown-input fallback.
- README.md, CHANGELOG.md: surface the bound and point heavy users at
  `--from`/`--to` for unbounded windows.

The CLI flag `--period all` continues to be accepted; only the dashboard
window changes to match what the CLI was already doing. No public API
or schema change.

Refs #93
2026-05-05 03:53:46 +03:00
Nihal Jain
90772a3267 fix: update model aliases and enhance event parsing for Copilot provider
- Fixes #219
2026-05-05 04:21:40 +05:30
Resham Joshi
18335a1f9d
Merge pull request #212 from thameem-abbas/feat/gnome-extension
Some checks are pending
CI / semgrep (push) Waiting to run
Merging GNOME Shell extension as foundation - will enhance UI in follow-up
2026-05-04 10:50:36 -07:00
iamtoruk
6fb05c6813 Fix command injection in yield via execFileSync
Replace execSync with execFileSync and argument arrays so shell
metacharacters in git branch names cannot be interpreted as commands.
Add SAFE_REF_PATTERN validation as defense in depth for branch names
from git symbolic-ref.

Addresses #214.
2026-05-04 10:13:40 -07:00
iamtoruk
15334fac67 Add SHA-256 checksum verification to menubar installer
The installer now downloads and verifies a .sha256 companion file
before extracting and launching the menubar app. Build script and
CI workflow generate the checksum alongside the zip. Adds SECURITY.md
with reporting instructions.

Addresses #215.
2026-05-04 10:08:58 -07:00
thameem-abbas
87e45f43df fix: compact mode toggle updates instantly without restart
Toggle label visibility instead of rebuilding panel children.
Label always added to panel, just hidden when compact=true.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 09:46:21 -04:00
thameem-abbas
30b3ad0503 feat: add GNOME Shell extension for Linux panel indicator
GNOME 45+ extension that shows live token costs in the top bar panel
with a dropdown for provider breakdown, top activities/models, cache
stats, and budget alerts. Polls `codeburn status --format menubar-json`
every 30s — same data contract as the macOS menubar app.

Includes GSettings preferences (refresh interval, compact mode, budget
threshold, per-provider enable/disable toggles) with Libadwaita UI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 09:44:35 -04:00
Resham Joshi
cf8c2aa493
Merge pull request #206 from voidborne-d/fix/skill-subcategory-203
Some checks are pending
CI / semgrep (push) Waiting to run
fix(classifier): surface skill name as subCategory for general turns (#203)
2026-05-03 16:42:47 -07:00
Resham Joshi
ac8081bb08
Merge pull request #207 from ozymandiashh/fix/codex-stream-large-sessions
Stream-parse Codex session files to fix oversize-cap drops on heavy users
2026-05-03 16:35:30 -07:00
ozymandiashh
61be92a834 Stream-parse Codex session files to handle 250+ MB rollouts
Heavy Codex users hit MAX_SESSION_FILE_BYTES (128 MB) on long-running
sessions. The file is read in full via readSessionFile and then split on
'\n', so even bumping the cap eventually runs into V8's 512 MB string
limit (split doubles the high-water mark).

readSessionLines is a streaming generator that already exists in
fs-utils for exactly this case but only readFirstLine was using it.
Switch the Codex provider to consume it and let the cap apply only when
streaming would still be unreasonable.

Changes:
- src/fs-utils.ts: introduce MAX_STREAM_SESSION_FILE_BYTES (2 GB) and
  apply it in readSessionLines instead of the full-read cap. Keep
  MAX_SESSION_FILE_BYTES for readSessionFile / readSessionFileSync
  consumers that materialize the whole file.
- src/providers/codex.ts: replace `readSessionFile -> split('\n')` with
  `for await (... of readSessionLines)`. Add sawAnyLine guard so a
  failed/empty stream skips cache write, preserving the previous
  early-return behavior.

Empirical impact on a real account with one 247 MB rollout: 7-day totals
went from 4,536 calls / €358.69 / 20.1M input tokens to 6,111 calls /
€550.67 / 37.3M input tokens. The previously-skipped session is now
included; no other behavior changes.

Refs #204
2026-05-04 02:15:04 +03:00
voidborne-d
c16b21ec50 fix(classifier): surface skill name as subCategory for general turns (#203)
Turns whose only assistant tool is `Skill` collapse to category `general`
because `classifyByToolPattern` returns `'general'` and `refineByKeywords`
only operates on `coding`/`exploration`. In environments that lean on Claude
Code skills, the per-activity dashboard column flattens — every `/init`,
`/review`, `/security-review`, `/claude-api`, plus user-defined skills, all
land in `general` with no signal about which workflow ran.

Implements Option A from the issue:

- `ParsedApiCall.skills: string[]` populated in the Anthropic-path parser
  via a new `extractSkillNames` helper that reads `input.skill || input.name`
  from each `Skill` ToolUseBlock (mirrors `detectGhostSkills` extraction at
  optimize.ts:765 so the two stay in sync).
- `ClassifiedTurn.subCategory?: string` set to the first skill name when the
  resolved category is `general` AND any skill identifier was extracted.
  Top-level category stays `general` — existing aggregations, exports, and
  category-keyed code paths unchanged.
- `SessionSummary.skillBreakdown: Record<string, {turns,costUSD,editTurns,
  oneShotTurns}>` populated in the same per-turn loop that builds
  `categoryBreakdown`. Provider sessions (Codex/Cursor/etc.) keep `skills:
  []` — they don't expose the Skill tool surface today.
- Dashboard `ActivityBreakdown` renders top-N skill sub-rows beneath the
  `general` row when present (indented `/skill-name`, dimmed). Other
  categories render exactly as before; if no skills were invoked, the panel
  is byte-identical to current output.

Existing 419 tests still pass. New `tests/classifier.test.ts` adds 8 cases:
single skill via `input.skill`, single via `input.name`, first-wins for
multi-skill turns, aggregation across multiple assistant calls in one turn,
no-name fallback (`subCategory` stays undefined), `Skill+Edit` promoting to
`coding` and dropping subCategory, non-Skill general turns, and a legacy
ParsedApiCall shape with `skills` field absent (forward-compat). Pre-fix
verification by stashing the source change reproduces 4/8 failures with the
exact "expected 'init', received undefined" diff; restoring → 8/8 pass.

Closes #203.

🤖 AI assistance disclosure: assistant-scaffolded by Claude (Opus 4.7);
author of record reviewed every line, ran the full vitest suite locally
(`npm test` → 32 files / 427 tests pass), `npx tsc --noEmit` clean, and
`npm run build` produces a clean ESM bundle.
2026-05-04 06:26:45 +08:00
iamtoruk
7501aee130 Add Goose and Antigravity providers to README, bump provider count to 18 2026-05-03 12:14:35 -07:00
iamtoruk
6dbd25ce55 Bump version to 0.9.6 2026-05-03 12:12:56 -07:00
iamtoruk
988398abfc Fix $0.0000 display for near-zero costs
Closes #205
2026-05-03 12:11:10 -07:00
iamtoruk
6702d55345 Fix menubar provider view showing $0.00 after idle and refresh race condition
CLI timeout increased from 20s to 45s to handle cold file-cache latency on
provider-specific queries. Loading overlay now appears when the all-provider
payload confirms a provider has spend but its dedicated data hasn't loaded yet.
Manual refresh (force: true) bypasses the in-flight guard so users can always
re-fetch. Tab strip prefers the provider-specific payload cost when available
so it stays in sync with the hero section.
2026-05-03 12:00:03 -07:00
AgentSeal
8cf68e7a16 Fix Antigravity dedup collision and add Codex ChatGPT Plus token estimation (#204)
- Antigravity: use loop index as fallback when responseId is empty to prevent
  all entries in a cascade sharing the same dedup key; bump CACHE_VERSION to
  force re-parse of stale cached data
- Codex: estimate tokens from message text when info is null (ChatGPT Plus/Pro
  subscription sessions), feeding through calculateCost so subscription users
  see API-equivalent spend; add costIsEstimated flag to ParsedProviderCall
- Update LiteLLM pricing snapshot
2026-05-03 19:51:13 +02:00
Resham Joshi
95585febf4
Merge pull request #201 from getagentseal/fix/streaming-dedup
Some checks are pending
CI / semgrep (push) Waiting to run
Fix streaming dedup: keep last message.id occurrence for accurate tokens and tools
2026-05-02 22:30:48 -07:00
iamtoruk
800c106250 Fix streaming dedup: keep last occurrence of each message.id within session files
Claude Code writes the same message.id multiple times during streaming.
The first write has partial tokens (often 1) and no tool_use blocks.
The last write has authoritative token counts and all tool_use/MCP blocks.

Old behavior kept the first occurrence (keep-first), silently dropping
real output tokens (+6.3% undercount) and all MCP tool calls.

New behavior keeps the last occurrence's content but preserves the first
occurrence's timestamp for correct date bucketing.

Validated against 21,390 real session files: 40.5% had duplicate IDs,
output tokens were understated by up to 78% per session.
2026-05-02 22:30:17 -07:00
iamtoruk
341aa46f78 Strip ANSI escapes from bash commands across all providers
Use strip-ansi (already in dep tree via Ink) in extractBashCommands
to prevent terminal escape codes from leaking into dashboard bash
breakdown keys. Route goose, gemini, qwen, and openclaw through
extractBashCommands instead of inline split, which also gives them
multi-command extraction (matching claude/codex/droid behavior).
2026-05-02 20:59:24 -07:00
iamtoruk
292265bf47 Add deno dx as a run method 2026-05-02 20:31:27 -07:00
iamtoruk
fe1007cc63 Add missing Antigravity model aliases for gemini-3-pro, flash-image, flash-lite 2026-05-02 20:26:45 -07:00
Resham Joshi
f5b66861f7
Merge pull request #199 from NihalJain/fix_Antigravity
Good catch on the Antigravity model aliases
2026-05-02 20:26:05 -07:00
Nihal Jain
73cf90cb2c Add Antigravity Gemini model IDs with preview pricing aliases 2026-05-03 05:46:33 +05:30
iamtoruk
87b660e584 Fix hardcoded $ in forecast comparison text
Some checks are pending
CI / semgrep (push) Waiting to run
The "vs last month" line in the forecast section used a hardcoded $
instead of the user's selected currency symbol and rate. Use
asCompactCurrency() which handles both.

Closes #197
2026-05-02 16:16:43 -07:00
iamtoruk
c511627e87 Fix dashboard hang and ExperimentalWarning on Windows
Strip Ink v7 DEC mode 2026 synchronized output markers (BSU/ESU) on
Windows. ConPTY does not implement this protocol and buffers
indefinitely, causing the dashboard to hang with no output. The patch
intercepts standalone BSU/ESU writes on stdout while preserving full
interactivity (keyboard, live refresh, cursor management).

Fix ExperimentalWarning timing: the process.emit patch was restored
synchronously in the finally block, but Node defers the warning via
process.nextTick. Delay restore by one tick so the patch is still
active when the warning fires.

Closes #195
2026-05-02 11:54:58 -07:00
Resham Joshi
db993196cf
Fix menubar ghost status item on macOS Tahoe
Set accessory activation policy in willFinishLaunching before the
focus chain forms. Debounce observation tracking to coalesce rapid
property changes into a single status bar refresh.
2026-05-02 10:14:14 -07:00
Resham Joshi
3ea4a62408
Add Goose provider, fix Codex fork dedup
Some checks are pending
CI / semgrep (push) Waiting to run
Goose: read token usage from ~/.local/share/goose/sessions/sessions.db.
Lazy-loaded, zero overhead for non-Goose users.

Codex: use sessionId instead of file path in dedup key so forked
sessions sharing the same session_id don't double-count tokens.
2026-05-02 09:58:52 -07:00
Resham Joshi
8c845253c2
Add Antigravity IDE provider
Fetch token usage from Antigravity's local language server via RPC.
Falls back to cached results when the IDE is closed.
2026-05-02 08:58:23 -07:00