Skip to content

feat: add local Claude/Codex usage tracking (via ccusage)#193

Merged
robinebers merged 19 commits intomainfrom
feat/show-claude-token-usage
Feb 22, 2026
Merged

feat: add local Claude/Codex usage tracking (via ccusage)#193
robinebers merged 19 commits intomainfrom
feat/show-claude-token-usage

Conversation

@validatedev
Copy link
Copy Markdown
Collaborator

@validatedev validatedev commented Feb 19, 2026

Description

Scan Claude's JSONL session logs to show "Today" and "Last 30 days" cost and token counts in the Claude plugin detail view.

This pull request introduces integration with the ccusage library to provide detailed, offline token usage and cost reporting for Claude Code. The integration spans backend (Rust, Tauri), plugin API, frontend plugin logic, and documentation, and includes comprehensive tests. The main focus is to enable plugins (starting with Claude) to query and display local token usage and cost metrics, with graceful fallback if dependencies are missing.

Key changes:

ccusage Integration and Infrastructure

  • Added a Rust host API (inject_ccusage) that exposes a ccusage.query method to plugins, spawning a Bun subprocess to run a bundled bridge script for local token usage queries. This includes robust resource path resolution, Bun binary detection, and result parsing with timeouts and logging. (src-tauri/src/plugin_engine/host_api.rsR1100-R1284, F73fb5fbL628R628)
  • Bundled a new scripts/ccusage-bridge.mjs script, which loads and aggregates daily usage data via the ccusage library, and outputs results in a plugin-friendly format.
  • Updated Tauri build config to bundle and distribute the bridge script, and to run the Bun build step before dev/build. [1] [2]
  • Added ccusage as a dependency in package.json.

Plugin API and Documentation

  • Documented the new host.ccusage.query API in docs/plugins/api.md, detailing its usage, behavior, and result schema.

Claude Plugin Usage Reporting

  • Enhanced the Claude plugin to query token usage via the new API, cache results for 60 seconds, and display "Today" and "Last 30 days" usage/cost lines in probe output. Includes logic for formatting tokens and costs, and for handling missing or partial data. [1] [2] [3]

Testing and Helpers

  • Added comprehensive tests for the new usage reporting in the Claude plugin, covering cases with/without data, cost omission, caching, and aggregation.
  • Updated test helpers to mock the new ccusage API.

References:
[1] F73fb5fbL628R628, [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]

Related Issue

#19

https://x.com/RhysSullivan/status/2024183273577206090
😁

Type of Change

  • New feature

Testing

  • I ran bun run build and it succeeded
  • I ran bun run test and all tests pass
  • I tested the change locally with bun tauri dev

Screenshots

CleanShot 2026-02-19 at 03 57 54

Checklist

  • I read CONTRIBUTING.md
  • My PR targets the main branch
  • I did not introduce new dependencies without justification

Summary by cubic

Adds local, offline token and cost tracking via ccusage for Claude and Codex, showing Today, Yesterday, and Last 30 Days in plugin detail views (31-day inclusive). Replaces the bridge with a Rust host.ccusage.query that runs pinned ccusage CLIs across multiple runners and returns a status envelope.

  • New Features

    • host.ccusage.query: executes ccusage@18.0.5 and @ccusage/codex@18.0.5 via bunx → pnpm dlx → yarn dlx → npm exec → npx; provider-aware; supports since/until and homePath (CLAUDE_CONFIG_DIR/CODEX_HOME); normalizes output to { daily }; returns status: ok | no_runner | runner_failed; no provider API calls.
    • Claude and Codex plugins: add Today/Yesterday/Last 30 Days lines; robust date parsing (ISO, compact, locale); shared cost+token helpers; tests cover empty/zero data and 31-day window; docs and README updated.
  • Bug Fixes

    • After timeout, kill then wait on the ccusage process to prevent zombie processes.
    • Stabilize App test by using findAllByText for async rendering.

Written for commit 03a220c. Summary will update on new commits.

Scan Claude's JSONL session logs to show "Today" and "Last 30 days"
cost and token counts in the Claude plugin detail view.

- Add host.fs.glob API (Rust + JS wrapper) for recursive file discovery
  with path, size, and mtimeMs metadata
- Implement incremental JSONL scanner with per-file caching, streaming
  dedup, and 60s rate limiting
- Add model pricing table with tiered rates for Sonnet models
- Support CLAUDE_CONFIG_DIR env var for custom config locations
- Handle edge cases: oversized files clear stale cache, scan failures
  preserve old data, NaN/malformed entries are skipped
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds comprehensive local token usage tracking for the Claude plugin by scanning JSONL session logs and displaying aggregated "Today" and "Last 30 days" cost and token counts in the plugin detail view. The PR also introduces a new file system glob API for recursive file discovery.

Changes:

  • Implements a new host.fs.glob API in Rust that supports recursive file pattern matching with glob syntax, returning file metadata (path, size, mtime) for cache invalidation
  • Adds comprehensive token usage tracking logic in the Claude plugin that scans local JSONL logs, deduplicates streaming chunks, aggregates tokens and costs per day/model, and caches results
  • Documents the new glob API with examples and usage guidelines in the plugin API documentation

Reviewed changes

Copilot reviewed 8 out of 10 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src-tauri/src/plugin_engine/host_api.rs Implements the Rust _globRaw function for file discovery using glob patterns with tilde expansion and metadata collection
src-tauri/src/plugin_engine/runtime.rs Adds wrapper patch initialization for the new fs.glob API
src-tauri/Cargo.toml Adds glob crate dependency for pattern matching
src-tauri/Cargo.lock Updates lockfile with glob dependency
plugins/claude/plugin.js Implements token usage scanning, caching, aggregation, and cost calculation with model-specific tiered pricing
plugins/claude/plugin.json Adds "Today" and "Last 30 days" text line definitions for the UI
plugins/claude/plugin.test.js Adds 14 comprehensive test cases covering scanning, deduplication, caching, error handling, and edge cases
plugins/test-helpers.js Adds glob mock to test context
docs/plugins/api.md Documents the new host.fs.glob API with signature, behavior, and usage examples
bun.lock Updates lucide-react dependency to 0.564.0

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src-tauri/src/plugin_engine/host_api.rs Outdated
Comment thread plugins/claude/plugin.js Outdated
Comment thread plugins/claude/plugin.js
Comment thread plugins/claude/plugin.js Outdated
Comment thread plugins/claude/plugin.js Outdated
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 10 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src-tauri/src/plugin_engine/host_api.rs">

<violation number="1" location="src-tauri/src/plugin_engine/host_api.rs:7">
P2: Avoid expanding the plugin env allowlist beyond CODEX_HOME. Exposing additional env vars like CLAUDE_CONFIG_DIR increases the risk of leaking local configuration paths/secrets to plugins.

(Based on your team's feedback about exposing only CODEX_HOME to plugins when allowing environment variable access.) [FEEDBACK_USED]</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread src-tauri/src/plugin_engine/host_api.rs Outdated
@validatedev
Copy link
Copy Markdown
Collaborator Author

Currently it works without any problem, with minimal dep. In the future we can migrate to https://ccusage.com/guide/library-usage, with consolidating other providers. Let's start with that way!

@robinebers
Copy link
Copy Markdown
Owner

Thanks Mert! I looked into this a bit deeper. This well, well done.

Only problem is the initial start time which in my case (with not a lot of cache files) took 14.2s (!) on first launch before cache creation. This has the potential to confuse people, especially if they have a lot more cache or more data in general.

I had GPT-5.3-Codex look at ccusage and it concluded that it does this more efficiently by streaming and multi-threading the results. It is a lot faster. I also looked into how to use this, and I think giving our Rust host the ability to query ccusage would be awesome.

It would also enable usage for Codex (and Amp, if we'd like to).

What do you think?

Comment thread plugins/claude/plugin.js Outdated
Comment thread plugins/claude/plugin.js Outdated
Comment thread plugins/claude/plugin.js Outdated
@validatedev
Copy link
Copy Markdown
Collaborator Author

validatedev commented Feb 19, 2026

@robinebers @davidarny thank you 🙏

took 14.2s (!) on first launch before cache creation.

It didn't take me that long, but I agree with you, it should be much faster.

I think giving our Rust host the ability to query ccusage would be awesome.

Also agree. We shouldn't maintain a list of models, and I'm really not a fan of changing the configuration every time a new model releases.

Doing something which leverages ccusage now. I expect this feature to be completed today 🤞

Replace the hand-rolled JSONL scanner (~370 lines) with the ccusage
library via a Bun subprocess bridge, gaining accurate LiteLLM pricing
and support for newer models like claude-opus-4-6.

The bridge uses an adapter-pattern dispatch so adding future providers
(Codex, OpenCode) requires only a new adapter function. Rust
auto-injects `_provider` from the plugin ID, keeping plugin JS
unchanged.

Also removes dead `host.fs.glob` code and the `glob` crate, which were
only needed by the old scanner.
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 13 files (changes from recent commits).

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src-tauri/src/plugin_engine/host_api.rs">

<violation number="1" location="src-tauri/src/plugin_engine/host_api.rs:1223">
P2: After timing out you kill the child process but never wait to reap it. This can leave zombie processes if ccusage repeatedly times out. Call `child.wait()` after `kill()` before returning.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread src-tauri/src/plugin_engine/host_api.rs Outdated
Call child.wait() after child.kill() to prevent zombie processes
when the ccusage bridge repeatedly times out.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 12 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@validatedev
Copy link
Copy Markdown
Collaborator Author

@robinebers all done! and we can add codex/amp easily with existing structure, adhering ocp :)

…ayKey function for consistent date formatting. Update test cases to utilize this new function for improved readability and maintainability.
@robinebers
Copy link
Copy Markdown
Owner

cursor review
@cubic-dev-ai review

@cubic-dev-ai
Copy link
Copy Markdown
Contributor

cubic-dev-ai Bot commented Feb 21, 2026

cursor review
@cubic-dev-ai review

@robinebers I have started the AI code review. It will take a few minutes to complete.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 issues found across 12 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="plugins/codex/plugin.test.js">

<violation number="1" location="plugins/codex/plugin.test.js:235">
P2: This test relies on the real system clock to build the ccusage date key, which can make it flaky across time zones or around midnight. Use a fixed system time (e.g., vi.useFakeTimers/vi.setSystemTime) so the plugin’s “Today” logic matches a deterministic date.</violation>
</file>

<file name="src-tauri/src/plugin_engine/host_api.rs">

<violation number="1" location="src-tauri/src/plugin_engine/host_api.rs:1487">
P1: Pipe deadlock: stdout and stderr are piped but never drained while waiting for the child to exit. If ccusage outputs more than the OS pipe buffer (~64 KB), the child blocks on a write, the parent is stuck in the `try_wait` poll loop, and the process times out instead of succeeding. Use `child.wait_with_output()` to read pipes and wait concurrently, removing the manual poll loop.</violation>
</file>

<file name="plugins/claude/plugin.js">

<violation number="1" location="plugins/claude/plugin.js:487">
P2: `ccusage` daily entries don’t include `totalTokens`, so this will always treat token counts as 0. Compute totals from `inputTokens`/`outputTokens`/cache token fields instead.</violation>
</file>

<file name="docs/plugins/api.md">

<violation number="1" location="docs/plugins/api.md:454">
P2: The ccusage API docs omit supported options (`provider` and `homePath`). This misleads plugin authors and hides the Codex/home override support implemented in the host API.</violation>

<violation number="2" location="docs/plugins/api.md:461">
P3: The description says ccusage queries “Claude Code” only, but the host API supports Codex too. Update the docs to describe it as provider-agnostic.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread src-tauri/src/plugin_engine/host_api.rs
Comment thread plugins/codex/plugin.test.js
Comment thread plugins/claude/plugin.js Outdated
}
}

const todayTokens = Number(todayEntry && todayEntry.totalTokens) || 0
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: ccusage daily entries don’t include totalTokens, so this will always treat token counts as 0. Compute totals from inputTokens/outputTokens/cache token fields instead.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At plugins/claude/plugin.js, line 487:

<comment>`ccusage` daily entries don’t include `totalTokens`, so this will always treat token counts as 0. Compute totals from `inputTokens`/`outputTokens`/cache token fields instead.</comment>

<file context>
@@ -397,6 +464,86 @@
+        }
+      }
+
+      const todayTokens = Number(todayEntry && todayEntry.totalTokens) || 0
+      const todayCost = usageCostUsd(todayEntry)
+      if (todayTokens > 0) {
</file context>
Fix with Cubic

Comment thread docs/plugins/api.md Outdated
Comment thread docs/plugins/api.md Outdated
…rt multiple providers (Claude and Codex). Update query options for improved flexibility, and refine daily usage reporting structure. Modify plugin JSON files to include new metrics for "Yesterday" and "Last 30 Days". Update tests to validate new provider handling and ensure accurate token reporting.
@davidarny
Copy link
Copy Markdown
Collaborator

davidarny commented Feb 21, 2026

@robinebers looked through this - I wonder what if ccusage is not installed? Seems we'll still show all these new stats (Today/Yesterday/Last 30 Days) and they'll remain always zeroed. When host.ccusage.query() returns null (no runner found), the plugin falls back to showing $0.00 · 0 tokens for Today and Yesterday.

UPD: The same behavior is confirmed by the test shows empty Today state when ccusage returns null - it explicitly asserts that Today and Yesterday lines appear with $0.00 and 0 tokens when ccusage returns null.

@robinebers
Copy link
Copy Markdown
Owner

@robinebers looked through this - I wonder what if ccusage is not installed? Seems we'll still show all these new stats (Today/Yesterday/Last 30 Days) and they'll remain always zeroed. When host.ccusage.query() returns null (no runner found), the plugin falls back to showing $0.00 · 0 tokens for Today and Yesterday.

UPD: The same behavior is confirmed by the test shows empty Today state when ccusage returns null - it explicitly asserts that Today and Yesterday lines appear with $0.00 and 0 tokens when ccusage returns null.

Excellent point about the runner. Two things:

  1. Since this was refactored, ccusage doesn't need to be installed or bundled ever
  2. But about the empty states, great point. In an ideal case scenario, there would be a message that a runner is required to show cost. Or it just fails quietly.

I do wonder how many people do not have at least one of the 4 runners installed.

Nevertheless, I think hiding it if all runners failed is a good idea. Will add something along these lines.

…e plugin

Introduce a new function, dayKeyFromUsageDate, to parse various date formats for usage data. Update the plugin to utilize this function for improved date handling in usage reporting. Modify tests to reflect changes, ensuring accurate display of "Today" and "Yesterday" lines when no usage data is available, and validate locale-formatted date handling.
@davidarny
Copy link
Copy Markdown
Collaborator

@robinebers I've misunderstood actually. Thought we'll try to run kind of globally installed ccusage. Now seeing npx (and alternatives) used for that seems my previous comments is not that valid anymore.

I do wonder how many people do not have at least one of the 4 runners installed.

Yes, only considering we implicitly require runners to be installed - that's the valid case. Still good to be covered though 😄

…ctured status responses. Update API documentation to reflect new status envelopes for usage queries, including handling cases for no available runners and execution failures. Modify tests to validate new response structures and ensure accurate reporting of usage data.
… reusable function for displaying daily token usage. Update tests to ensure accurate representation of "Today" and "Yesterday" states, including handling cases with zero tokens.
@robinebers
Copy link
Copy Markdown
Owner

Okay, I added a Rust to TypeScript result contract that now only renders the tokens when a runner is available and did not fail.

A couple of things I'd love to improve in a future version:

  • Shared utilities (queryTokenUsage, fmtTokens, dayKeyFromDate, usageCostUsd, costAndTokensLabel)
  • Slight UI changes to remove spacing between the lines
  • Intelligent caching of runner look-up for performance boost

davidarny
davidarny previously approved these changes Feb 21, 2026
@validatedev
Copy link
Copy Markdown
Collaborator Author

Thanks for the changes @robinebers, don't have time to review there rn, planning to check later today (GMT +3), if you both @robinebers @davidarny think that the final form is OK it's OK to me also, sorry for the delay

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 13 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/plugins/api.md Outdated

- **Runtime runners**: Executes pinned `ccusage@18.0.5` (Claude) or `@ccusage/codex@18.0.5` (Codex) via fallback chain `bunx -> pnpm dlx -> yarn dlx -> npm exec -> npx`
- **Provider-aware**: Resolves provider from `opts.provider` or plugin id (`claude`/`codex`)
- **Offline only**: Reads local JSONL session files, no network requests
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs state this API is “Offline only” with “no network requests”. However, the current implementation runs bunx/pnpm/yarn/npm/npx against a package spec, which can trigger network access to download the CLI the first time (or when cache is missing). Consider rewording to clarify that it doesn’t call provider APIs, but may require registry access to obtain the runner/package.

Suggested change
- **Offline only**: Reads local JSONL session files, no network requests
- **No provider API calls**: Usage is computed from local JSONL session files; the host does not call Claude/Codex (or other provider) APIs, but package runners may contact a package registry to download the `ccusage` CLI if it is not already available locally

Copilot uses AI. Check for mistakes.
Comment thread plugins/claude/plugin.js
Comment on lines +276 to +282
const since = new Date()
since.setDate(since.getDate() - 31)
const y = since.getFullYear()
const m = since.getMonth() + 1
const d = since.getDate()
const sinceStr = "" + y + (m < 10 ? "0" : "") + m + (d < 10 ? "0" : "") + d

Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since is computed as “today - 31 days”, but the UI label is “Last 30 Days” and the aggregation sums all returned daily entries. If ccusage treats --since as inclusive (typical), this can include 32 calendar days of data. Consider aligning the query/aggregation window to 30 days (e.g., use 29/30 days back, and/or cap client-side by day key).

Copilot uses AI. Check for mistakes.
Comment thread plugins/codex/plugin.js
Comment on lines +295 to +301
const since = new Date()
since.setDate(since.getDate() - 31)
const y = since.getFullYear()
const m = since.getMonth() + 1
const d = since.getDate()
const sinceStr = "" + y + (m < 10 ? "0" : "") + m + (d < 10 ? "0" : "") + d
const queryOpts = { provider: "codex", since: sinceStr }
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since is computed as “today - 31 days”, but the UI label is “Last 30 Days” and the aggregation sums all returned daily entries. If ccusage treats --since as inclusive (typical), this can include 32 calendar days of data. Consider aligning the query/aggregation window to 30 days (e.g., use 29/30 days back, and/or cap client-side by day key).

Copilot uses AI. Check for mistakes.
Comment thread plugins/claude/plugin.js
Comment on lines +508 to +511
const usageResult = queryTokenUsage(ctx)
if (usageResult.status === "ok") {
const usage = usageResult.data
const now = new Date()
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

queryTokenUsage is invoked on every probe, and the host implementation may spawn multiple external runner processes (plus runner detection) per call. Given probes can run on an interval, this can become a noticeable performance/latency hit. Consider adding a short TTL cache (the PR description mentions 60s) and/or only refreshing token usage when the detail view is open.

Copilot uses AI. Check for mistakes.
Comment thread plugins/codex/plugin.js
Comment on lines +607 to +610
const tokenUsageResult = queryTokenUsage(ctx)
if (tokenUsageResult.status === "ok") {
const tokenUsage = tokenUsageResult.data
const now = new Date()
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

queryTokenUsage is invoked on every probe, and the host implementation may spawn multiple external runner processes (plus runner detection) per call. Given probes can run on an interval, this can become a noticeable performance/latency hit. Consider adding a short TTL cache (the PR description mentions 60s) and/or only refreshing token usage when the detail view is open.

Copilot uses AI. Check for mistakes.
Comment on lines +1635 to +1644
var rawFn = __openusage_ctx.host.ccusage._queryRaw;
__openusage_ctx.host.ccusage.query = function(opts) {
var result = rawFn(JSON.stringify(opts || {}));
try {
var parsed = JSON.parse(result);
if (parsed && typeof parsed === "object" && typeof parsed.status === "string") {
return parsed;
}
} catch (e) {}
return { status: "runner_failed" };
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

patch_ccusage_wrapper calls JSON.stringify(opts || {}) without a try/catch. If a plugin passes a non-serializable value (e.g., circular reference), this wrapper will throw and can abort the whole probe. Consider mirroring patch_ls_wrapper by catching stringify/parse failures and returning a stable fallback { status: "runner_failed" } (or no_runner) instead of throwing.

Copilot uses AI. Check for mistakes.
Comment on lines +1589 to +1596
let provider = resolve_ccusage_provider(&opts, &pid);
let runners = collect_ccusage_runners();
if runners.is_empty() {
log::warn!(
"[plugin:{}] no package runner found for ccusage query",
pid
);
return Ok(serde_json::json!({ "status": "no_runner" }).to_string());
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

collect_ccusage_runners() is executed on every host.ccusage.query call, and resolve_ccusage_runner_binary spawns --version processes for each candidate path. Since probes can run on an interval, this adds unnecessary process churn even when the runner set never changes. Consider caching the resolved runner list (e.g., OnceLock + optional TTL) and only re-detecting on failure.

Copilot uses AI. Check for mistakes.
@davidarny
Copy link
Copy Markdown
Collaborator

Pull request overview

Copilot reviewed 12 out of 13 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@copilot which model do you use for code reviews?

@robinebers
Copy link
Copy Markdown
Owner

great feedback thanks. will to iterate tomorrow!

@validatedev
Copy link
Copy Markdown
Collaborator Author

checked the current implementation, much much cleaner approach thanks @robinebers !

actually don’t see anything problematic from my side, but copilot blames some.

agree with caching though, i don’t want to recalculate things over and over again if we have the computed result. we should improve this.

ui doesn’t “bother” me though, but can be improved, yes.

looks perfect to me for the first iteration of ccusage support!

@robinebers
Copy link
Copy Markdown
Owner

OK, making some minor changes and then merging this for now. let's roll it out and see :)

…ex plugins. Change offline usage reporting to clarify that no provider API calls are made, and adjust date calculations to reflect a 31-day inclusive range. Enhance tests to validate new date handling and ensure accurate usage queries.
@github-actions github-actions Bot added the core label Feb 22, 2026
Copy link
Copy Markdown
Owner

@robinebers robinebers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM now, at least for now

@robinebers robinebers merged commit 96d0c8b into main Feb 22, 2026
3 checks passed
@robinebers robinebers deleted the feat/show-claude-token-usage branch February 22, 2026 05:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core docs plugin rust Pull requests that update rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants