Skip to content

refactor(adapter): split remaining adapter modules - #1137

Merged
ryoppippi merged 5 commits into
mainfrom
refactor/split-remaining-adapters
May 23, 2026
Merged

refactor(adapter): split remaining adapter modules#1137
ryoppippi merged 5 commits into
mainfrom
refactor/split-remaining-adapters

Conversation

@ryoppippi

@ryoppippi ryoppippi commented May 23, 2026

Copy link
Copy Markdown
Member

Splits the remaining large adapter modules for all-agent reporting, Codex, and Claude into focused files without changing their public behavior.

What changed:

  • Moved all-agent loading/reporting/types/tests into adapter/all/* modules and kept the root command behavior intact.
  • Split Codex parsing, aggregation, reporting, path discovery, speed detection, and serde types into dedicated modules.
  • Split Claude daily summary loading and path discovery out of the main adapter module.

Validation:

  • direnv exec . pnpm run format
  • direnv exec . pnpm typecheck
  • direnv exec . pnpm run test
  • release JSON parity against bunx ccusage 20.0.4 through --until 20260522 for daily/monthly/session, codex daily/session, and opencode daily/session
  • release performance median comparison against origin/main: daily -1.50%, session -21.87%, codex daily -1.13%, codex session +1.94%, opencode daily -1.16%

Summary by cubic

Split the remaining adapter modules into focused files for all, Codex, and Claude without changing public output, and fix Codex fast-tier detection when CodexSpeed::Auto to avoid false positives.

  • Refactors

    • adapter/all: Moved loading, reporting, types, and tests into adapter/all/*; kept root command behavior.
    • adapter/codex: Extracted aggregation, parsing, reporting, path discovery, speed detection, and serde types into focused modules; JSON/table output unchanged.
    • adapter/claude: Moved daily summary loading and path discovery into dedicated modules; preserved deduplication, date filtering, and project/session path extraction.
  • Bug Fixes

    • Codex speed detection: Reused shared CODEX_HOME path discovery and parsed config.toml by exact service_tier key and fast-tier values only, preventing matches like service_tier_override or substring hits (e.g., “breakfast”).

Written for commit ade8b58. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

  • New Features

    • Added a unified "all agents" usage report with JSON and improved table output, aggregation by period, and richer per-model/agent breakdowns.
    • New Codex session parsing, aggregation, and cost reporting including fast/standard speed detection.
  • Chores

    • Reorganized adapter internals for clearer module boundaries and parallelized loading for faster reports.
  • Tests

    • Expanded test coverage across loading, aggregation, deduplication, and reporting.

Review Change Stack

ryoppippi added 3 commits May 23, 2026 19:39
Move the all-agent loader, reporting, types, and tests into separate files so the root adapter module stays focused on the public entry points.

Keep the existing row construction and reporting behavior intact, while consolidating the priced summary agent loading helper used by similar adapters to reduce duplicated wrapper code.
Move Codex aggregation, parsing, path discovery, report rendering, speed detection, and serde types into focused modules.

The public adapter entry points and JSON/table report construction stay the same, which keeps output compatibility while making future parser changes easier to review.
Move Claude daily summary loading and Claude path discovery into dedicated modules while keeping the primary entry loader in mod.rs.

This reduces the size of the adapter module without changing deduplication, date filtering, or project/session path extraction behavior.
@coderabbitai

coderabbitai Bot commented May 23, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3cc61b4a-303b-44d7-9b62-a2408a48154d

📥 Commits

Reviewing files that changed from the base of the PR and between e7c3459 and ade8b58.

📒 Files selected for processing (2)
  • rust/crates/ccusage/src/adapter/codex/paths.rs
  • rust/crates/ccusage/src/adapter/codex/speed.rs

📝 Walkthrough

Walkthrough

Refactors agent adapters into focused submodules. Adds a new adapter::all with loader/report/types/tests implementing concurrent per-agent loading and aggregation. Extracts Claude daily loading and path discovery into dedicated modules. Decomposes Codex into parser/paths/aggregate/report/speed/types submodules with deterministic aggregation and reporting.

Changes

Adapter module refactoring

Layer / File(s) Summary
All adapter: core types and data structures
rust/crates/ccusage/src/adapter/all/types.rs
Introduces AllRow, AllAccumulator, AllLoadResult, AgentRows, AgentLoadSpec, and LoadedAgentRows used for aggregation and per-agent breakdowns.
All adapter: module structure and entry point
rust/crates/ccusage/src/adapter/all/mod.rs
Creates adapter::all with submodules and implements pub(crate) fn run(...) that delegates to loader::load_rows and chooses JSON or table output.
All adapter: concurrent per-agent loading
rust/crates/ccusage/src/adapter/all/loader.rs
Implements load_rows, load_agent_rows_parallel, per-agent loaders (Claude/Codex/Qwen/priced), summarization, session filtering, codex_group_row, and aggregate_rows.
All adapter: JSON and table reporting
rust/crates/ccusage/src/adapter/all/report.rs
Adds report_json, print_table, title/agent-label helpers, table row/column shaping, model-breakdown rendering, and sorting.
All adapter: comprehensive test coverage
rust/crates/ccusage/src/adapter/all/tests.rs
Adds tests covering concurrency, aggregation, JSON output, Codex group handling, model-breakdown aggregation, and table column modes.
Claude adapter: extract daily loading into submodule
rust/crates/ccusage/src/adapter/claude/daily.rs, rust/crates/ccusage/src/adapter/claude/mod.rs
Moves daily-summary loading/parse/dedup/accumulation into daily.rs; mod.rs delegates to it and exposes validation helpers as pub(super).
Claude adapter: extract path discovery into submodule
rust/crates/ccusage/src/adapter/claude/paths.rs
Adds claude_paths, usage_files, recursive JSONL collection, extract_project, and extract_session_parts.
Codex adapter: serde models and lossy deserializers
rust/crates/ccusage/src/adapter/codex/types.rs
Adds Codex Serde models and lossy deserializers consolidating token fields and supporting flexible timestamp shapes.
Codex adapter: extract JSONL parsing into submodule
rust/crates/ccusage/src/adapter/codex/parser.rs
Implements visit_codex_session_file with line-kind detection, session/headless handling, per-event usage extraction, model resolution, and timestamp normalization.
Codex adapter: extract event aggregation into submodule
rust/crates/ccusage/src/adapter/codex/aggregate.rs
Adds group-loading and aggregation (single-threaded or parallel), period grouping, per-model accumulation, and sharded deduplication utilities.
Codex adapter: loader/module refactor
rust/crates/ccusage/src/adapter/codex/mod.rs, rust/crates/ccusage/src/adapter/codex/loader.rs
Refactors codex mod to submodules and re-exports; loader.rs now imports parser::visit_codex_session_file and paths::codex_usage_paths and drops local parsing/types.
Codex adapter: reporting and cost computation
rust/crates/ccusage/src/adapter/codex/report.rs
Adds JSON/table reporting from grouped Codex data, non-cached input token helpers, model/group cost calculations, and fast-multiplier application.
Codex adapter: path discovery and speed detection
rust/crates/ccusage/src/adapter/codex/paths.rs, rust/crates/ccusage/src/adapter/codex/speed.rs
Adds codex_home_paths/codex_usage_paths and resolve_codex_speed which inspects config.toml service_tier to decide fast/standard speed.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

enhancement

Suggested reviewers

  • ubugeeei

"I'm a rabbit in the code so spry,
I hopped through modules, low and high,
Split monoliths into tidy art,
Now adapters sing — a brand new start,
Hooray for tidy code! 🐇✨"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.05% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: refactoring large adapter modules by splitting them into focused, dedicated files across adapter/all, Codex, and Claude submodules.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/split-remaining-adapters

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ryoppippi

Copy link
Copy Markdown
Member Author

@coderabbitai review\n@cubic-dev-ai review

@coderabbitai

coderabbitai Bot commented May 23, 2026

Copy link
Copy Markdown

@ryoppippi Sure, I'll review the changes in this PR now!

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented May 23, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
ccusage-guide ade8b58 Commit Preview URL

Branch Preview URL
May 23 2026, 07:10 PM

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
rust/crates/ccusage/src/adapter/all/loader.rs (1)

21-634: 🏗️ Heavy lift

Split this loader module further to reduce mixed responsibilities.

This file still combines orchestration, concurrency, per-agent adapters, session filtering, metadata shaping, and aggregation in one place, which makes future changes riskier. Please extract at least one more layer (e.g., agent-spec builder + shared summary/session utilities) to keep this module focused.

As per coding guidelines, **/*.rs: “keep modules small”.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rust/crates/ccusage/src/adapter/all/loader.rs` around lines 21 - 634, This
module mixes orchestration, concurrency, agent-spec construction,
summarization/session utilities and aggregation; extract responsibilities by (1)
moving the AgentLoadSpec list construction into a new builder function (e.g.,
build_agent_load_specs or AgentSpec::build_list) that returns Vec<AgentLoadSpec>
and update load_rows to call it, (2) extracting summary/session helper functions
(filter_session_summaries, summarize_entries, summarize_entry_sessions,
summary_metadata, summary_rows, load_summary_agent_rows,
load_priced_summary_agent_rows, load_session_capable_summary_agent_rows,
load_qwen_rows, load_codex_rows) into a new submodule (e.g., summary or
agent_utils) and keep only orchestration functions (load_rows,
load_agent_rows_parallel, append_agent_rows, aggregate_rows) here, and (3)
keeping thread orchestration and progress logic in load_agent_rows_parallel
while changing call sites to use the new builder and utilities; update
imports/visibility accordingly.
rust/crates/ccusage/src/adapter/all/tests.rs (1)

39-490: 🏗️ Heavy lift

Add at least one fixture-backed loader test for the all-adapter path.

These tests are strong on unit behavior, but loader-path regressions are easier to catch with fixture-backed inputs (stable real-world payload shapes) in addition to synthetic constructors.

As per coding guidelines, **/*.rs: “prefer fixture-backed parser/loader tests”.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rust/crates/ccusage/src/adapter/all/tests.rs` around lines 39 - 490, Add a
fixture-backed loader test that exercises the "all-adapter" loader path by
feeding a stable JSON/text fixture and asserting the parsed/aggregated output;
implement the test alongside existing unit tests and call the same loader
entrypoints used in the suite (e.g. create an AgentLoadSpec that reads the
fixture and invoke load_agent_rows_parallel or the adapter-specific loader used
by the codebase), then assert known outputs via aggregate_rows or report_json to
confirm end-to-end parsing and aggregation (use symbols from this file like
AgentLoadSpec, load_agent_rows_parallel, test_agent_rows, aggregate_rows,
report_json to locate where to hook the fixture into the test).
rust/crates/ccusage/src/adapter/codex/speed.rs (1)

26-38: 💤 Low value

Consider reusing codex_home_paths from paths.rs to avoid duplication.

This function duplicates the logic in paths::codex_home_paths() (CODEX_HOME parsing with comma-split, trim, filter empty, and ~/.codex fallback). Since this module already has access to super::paths, you could import and call the shared version.

Note that paths::codex_home_paths() returns Result<Vec<PathBuf>> while this returns Vec<PathBuf> (silently returns empty on home_dir failure), so you'd need to handle the error case—which may be intentional here to gracefully fall back to Standard speed when paths can't be determined.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rust/crates/ccusage/src/adapter/codex/speed.rs` around lines 26 - 38, The
local codex_home_paths() duplicates logic in super::paths::codex_home_paths():
replace the body to call paths::codex_home_paths() instead of reimplementing
parsing; handle the Result returned by paths::codex_home_paths() to preserve
current behavior (i.e., on Ok(vec) return it, on Err(_) return an empty Vec or
the same fallback used here so we still gracefully fall back to Standard speed
when paths can't be determined). Update the use/imports to reference
super::paths and ensure the function signature remains Vec<PathBuf>.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@rust/crates/ccusage/src/adapter/all/loader.rs`:
- Around line 21-634: This module mixes orchestration, concurrency, agent-spec
construction, summarization/session utilities and aggregation; extract
responsibilities by (1) moving the AgentLoadSpec list construction into a new
builder function (e.g., build_agent_load_specs or AgentSpec::build_list) that
returns Vec<AgentLoadSpec> and update load_rows to call it, (2) extracting
summary/session helper functions (filter_session_summaries, summarize_entries,
summarize_entry_sessions, summary_metadata, summary_rows,
load_summary_agent_rows, load_priced_summary_agent_rows,
load_session_capable_summary_agent_rows, load_qwen_rows, load_codex_rows) into a
new submodule (e.g., summary or agent_utils) and keep only orchestration
functions (load_rows, load_agent_rows_parallel, append_agent_rows,
aggregate_rows) here, and (3) keeping thread orchestration and progress logic in
load_agent_rows_parallel while changing call sites to use the new builder and
utilities; update imports/visibility accordingly.

In `@rust/crates/ccusage/src/adapter/all/tests.rs`:
- Around line 39-490: Add a fixture-backed loader test that exercises the
"all-adapter" loader path by feeding a stable JSON/text fixture and asserting
the parsed/aggregated output; implement the test alongside existing unit tests
and call the same loader entrypoints used in the suite (e.g. create an
AgentLoadSpec that reads the fixture and invoke load_agent_rows_parallel or the
adapter-specific loader used by the codebase), then assert known outputs via
aggregate_rows or report_json to confirm end-to-end parsing and aggregation (use
symbols from this file like AgentLoadSpec, load_agent_rows_parallel,
test_agent_rows, aggregate_rows, report_json to locate where to hook the fixture
into the test).

In `@rust/crates/ccusage/src/adapter/codex/speed.rs`:
- Around line 26-38: The local codex_home_paths() duplicates logic in
super::paths::codex_home_paths(): replace the body to call
paths::codex_home_paths() instead of reimplementing parsing; handle the Result
returned by paths::codex_home_paths() to preserve current behavior (i.e., on
Ok(vec) return it, on Err(_) return an empty Vec or the same fallback used here
so we still gracefully fall back to Standard speed when paths can't be
determined). Update the use/imports to reference super::paths and ensure the
function signature remains Vec<PathBuf>.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e738e2fc-f271-4739-8e69-aefdb45a6273

📥 Commits

Reviewing files that changed from the base of the PR and between b36c8c6 and e7c3459.

📒 Files selected for processing (17)
  • rust/crates/ccusage/src/adapter/all.rs
  • rust/crates/ccusage/src/adapter/all/loader.rs
  • rust/crates/ccusage/src/adapter/all/mod.rs
  • rust/crates/ccusage/src/adapter/all/report.rs
  • rust/crates/ccusage/src/adapter/all/tests.rs
  • rust/crates/ccusage/src/adapter/all/types.rs
  • rust/crates/ccusage/src/adapter/claude/daily.rs
  • rust/crates/ccusage/src/adapter/claude/mod.rs
  • rust/crates/ccusage/src/adapter/claude/paths.rs
  • rust/crates/ccusage/src/adapter/codex/aggregate.rs
  • rust/crates/ccusage/src/adapter/codex/loader.rs
  • rust/crates/ccusage/src/adapter/codex/mod.rs
  • rust/crates/ccusage/src/adapter/codex/parser.rs
  • rust/crates/ccusage/src/adapter/codex/paths.rs
  • rust/crates/ccusage/src/adapter/codex/report.rs
  • rust/crates/ccusage/src/adapter/codex/speed.rs
  • rust/crates/ccusage/src/adapter/codex/types.rs
💤 Files with no reviewable changes (1)
  • rust/crates/ccusage/src/adapter/all.rs

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

2 issues found across 17 files

Prompt for AI agents (unresolved 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="rust/crates/ccusage/src/adapter/codex/parser.rs">

<violation number="1" location="rust/crates/ccusage/src/adapter/codex/parser.rs:152">
P2: Session events with only `total_tokens` are incorrectly skipped because the zero-usage guard ignores `total_tokens`.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread rust/crates/ccusage/src/adapter/codex/speed.rs Outdated
let Some(raw_usage) = raw_usage else {
return Ok(());
};
if raw_usage.input_tokens == 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: Session events with only total_tokens are incorrectly skipped because the zero-usage guard ignores total_tokens.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At rust/crates/ccusage/src/adapter/codex/parser.rs, line 152:

<comment>Session events with only `total_tokens` are incorrectly skipped because the zero-usage guard ignores `total_tokens`.</comment>

<file context>
@@ -0,0 +1,674 @@
+    let Some(raw_usage) = raw_usage else {
+        return Ok(());
+    };
+    if raw_usage.input_tokens == 0
+        && raw_usage.cached_input_tokens == 0
+        && raw_usage.output_tokens == 0
</file context>

@pkg-pr-new

pkg-pr-new Bot commented May 23, 2026

Copy link
Copy Markdown

Open in StackBlitz

ccusage

npx https://pkg.pr.new/ryoppippi/ccusage@1137

@ccusage/ccusage-darwin-arm64

npx https://pkg.pr.new/ryoppippi/ccusage/@ccusage/ccusage-darwin-arm64@1137

@ccusage/ccusage-darwin-x64

npx https://pkg.pr.new/ryoppippi/ccusage/@ccusage/ccusage-darwin-x64@1137

@ccusage/ccusage-linux-arm64

npx https://pkg.pr.new/ryoppippi/ccusage/@ccusage/ccusage-linux-arm64@1137

@ccusage/ccusage-linux-x64

npx https://pkg.pr.new/ryoppippi/ccusage/@ccusage/ccusage-linux-x64@1137

@ccusage/ccusage-win32-arm64

npx https://pkg.pr.new/ryoppippi/ccusage/@ccusage/ccusage-win32-arm64@1137

@ccusage/ccusage-win32-x64

npx https://pkg.pr.new/ryoppippi/ccusage/@ccusage/ccusage-win32-x64@1137

commit: ade8b58

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: e7c3459234d1
Base SHA: b36c8c6bb62b

This compares the Rust PR release binary against the configured base package on the same CI runner.

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new b36c8c6bb62b 935.5ms 390.1ms 35.0ms 3
PR pkg.pr.new e7c3459234d1 357.7ms 352.6ms 35.4ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: b36c8c6bb62b; PR package: e7c3459234d1. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, measured by hyperfine with 0 warmups and 1 runs.

Command Input Base median PR median PR vs base Base throughput PR throughput
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 500.4ms 499.2ms 1.00x 2.01 GiB/s 2.02 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 371.7ms 371.9ms 1.00x 2.71 GiB/s 2.71 GiB/s

Package runtime diagnostics

Compares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
All rows run --offline --json, measured by hyperfine with 0 warmups and 1 runs. This isolates wrapper overhead from the installed native optional dependency and the workspace release binary built on the runner.

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 504.0ms 2.00 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 465.2ms 2.16 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 363.6ms 2.77 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 336.6ms 2.99 GiB/s 1

Committed fixture performance

Committed small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage.

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs rust/target/release/ccusage directly. Both run --offline --json, measured by hyperfine with 2 warmups and 7 runs.

Command Input Base median PR median PR vs base Base throughput PR throughput
claude daily --offline --json 0.00 MiB 32.4ms 4.2ms 7.66x 0.05 MiB/s 0.37 MiB/s
claude session --offline --json 0.00 MiB 32.5ms 4.3ms 7.51x 0.05 MiB/s 0.36 MiB/s
codex daily --offline --json 0.00 MiB 32.3ms 3.9ms 8.20x 0.03 MiB/s 0.22 MiB/s
codex session --offline --json 0.00 MiB 31.2ms 4.0ms 7.81x 0.03 MiB/s 0.21 MiB/s

Large real-world-shaped fixture performance

Generated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs rust/target/release/ccusage directly. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.

Command Input Base median PR median PR vs base Base throughput PR throughput
claude --offline --json 1.01 GiB 510.8ms 477.6ms 1.07x 1.97 GiB/s 2.11 GiB/s
codex --offline --json 1.01 GiB 366.1ms 339.3ms 1.08x 2.75 GiB/s 2.97 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 14.25 KiB 14.25 KiB -0.00 KiB 1.00x
installed native package binary 3225.49 KiB 3225.49 KiB +0.00 KiB 1.00x

Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees.

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: e7c3459234d1
Base SHA: b36c8c6bb62b

This compares the PR package against the configured base package on the same CI runner.

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new b36c8c6bb62b 497.0ms 437.9ms 33.6ms 3
PR pkg.pr.new e7c3459234d1 496.9ms 403.8ms 34.1ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: b36c8c6bb62b; PR package: e7c3459234d1. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, measured by hyperfine with 0 warmups and 1 runs.

Command Input Base median PR median PR vs base Base throughput PR throughput
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 488.9ms 494.7ms 0.99x 2.06 GiB/s 2.04 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 361.4ms 364.2ms 0.99x 2.79 GiB/s 2.76 GiB/s

Package runtime diagnostics

Compares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
All rows run --offline --json, measured by hyperfine with 0 warmups and 1 runs. This isolates wrapper overhead from the installed native optional dependency and the workspace release binary built on the runner.

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 485.4ms 2.07 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 464.3ms 2.17 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 359.6ms 2.80 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 326.7ms 3.08 GiB/s 1

Committed fixture performance

Committed small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage.

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 2 warmups and 7 runs.

Command Input Base median PR median PR vs base Base throughput PR throughput
claude daily --offline --json 0.00 MiB 30.4ms 31.0ms 0.98x 0.05 MiB/s 0.05 MiB/s
claude session --offline --json 0.00 MiB 31.0ms 30.6ms 1.01x 0.05 MiB/s 0.05 MiB/s
codex daily --offline --json 0.00 MiB 31.0ms 30.7ms 1.01x 0.03 MiB/s 0.03 MiB/s
codex session --offline --json 0.00 MiB 30.2ms 30.1ms 1.00x 0.03 MiB/s 0.03 MiB/s

Large real-world-shaped fixture performance

Generated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.

Command Input Base median PR median PR vs base Base throughput PR throughput
claude --offline --json 1.01 GiB 504.3ms 491.4ms 1.03x 2.00 GiB/s 2.05 GiB/s
codex --offline --json 1.01 GiB 355.0ms 356.3ms 1.00x 2.84 GiB/s 2.83 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 14.25 KiB 14.25 KiB -0.00 KiB 1.00x
installed native package binary 3225.49 KiB 3225.49 KiB +0.00 KiB 1.00x

Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees.

Reuse the shared Codex home path discovery from the paths module so speed resolution does not carry a second CODEX_HOME parser.

Parse config.toml service_tier entries by exact key and exact fast-tier values. This prevents unrelated keys such as service_tier_override or substring values such as breakfast from selecting fast Codex pricing.
@ryoppippi

Copy link
Copy Markdown
Member Author

@coderabbitai @cubic-dev-ai addressed the service_tier detection finding by reusing shared Codex home path discovery and parsing only the exact service_tier key with exact fast/priority values.

I intentionally did not change the total_tokens-only session event behavior from Cubic's second finding because it changes real output totals relative to the current published v20 CLI. I verified that keeping current behavior preserves exact stdout parity with bunx ccusage across daily/monthly/session, Codex daily/session, and opencode daily/session.

Validation:

  • direnv exec . pnpm run format
  • direnv exec . pnpm typecheck
  • direnv exec . pnpm run test
  • direnv exec .. cargo test -p ccusage adapter::codex::
  • direnv exec . cargo build -p ccusage --release
  • current release binary stdout matches bunx ccusage for the commands above
  • performance rechecked against main release binary; no regression observed in median timings

@coderabbitai

coderabbitai Bot commented May 23, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@ryoppippi Thanks for the detailed update!

service_tier detection fix — The approach of reusing the shared Codex home path discovery and matching only the exact service_tier key with fast/priority values sounds solid. That's a clean and precise fix.

total_tokens-only session event behavior — Understood and agreed. Preserving exact stdout parity with the published v20 CLI is a valid and important constraint, especially for users scripting against the output. The tradeoff is well-reasoned, and the cross-command parity verification against bunx ccusage is strong evidence the behavior is correct by design. No further changes needed there.

The validation steps look comprehensive — format, typecheck, unit tests, Codex-specific cargo tests, release binary parity, and performance regression checks all passing is great confidence.


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

@cubic-dev-ai

cubic-dev-ai Bot commented May 23, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai @cubic-dev-ai addressed the service_tier detection finding by reusing shared Codex home path discovery and parsing only the exact service_tier key with exact fast/priority values.

I intentionally did not change the total_tokens-only session event behavior from Cubic's second finding because it changes real output totals relative to the current published v20 CLI. I verified that keeping current behavior preserves exact stdout parity with bunx ccusage across daily/monthly/session, Codex daily/session, and opencode daily/session.

Validation:
...

@ryoppippi The service_tier change looks good. Using split_once('=') with exact key/value matching (key.trim() != "service_tier", matches!(value, "fast" | "priority")) eliminates the false positives from keys like service_tier_override or values like breakfast. The delegation to paths::codex_home_paths() also removes the duplicate CODEX_HOME parser that was in the original mod.rs.

On the total_tokens-only behavior — makes total sense. Preserving exact stdout parity with the published v20 CLI is the right call. The performance numbers confirm there's no regression either, so nothing to worry about there.

The refactor looks clean overall.

Tip: get faster answers by chatting with cubic’s review copilot in the review UI

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: 0191915a02b3
Base SHA: b36c8c6bb62b

This compares the PR package against the configured base package on the same CI runner.

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new b36c8c6bb62b 422.9ms 468.2ms 35.8ms 3
PR pkg.pr.new 0191915a02b3 512.7ms 437.0ms 35.9ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: b36c8c6bb62b; PR package: 0191915a02b3. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, measured by hyperfine with 0 warmups and 1 runs.

Command Input Base median PR median PR vs base Base throughput PR throughput
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 512.1ms 511.3ms 1.00x 1.97 GiB/s 1.97 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 387.0ms 391.9ms 0.99x 2.60 GiB/s 2.57 GiB/s

Package runtime diagnostics

Compares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
All rows run --offline --json, measured by hyperfine with 0 warmups and 1 runs. This isolates wrapper overhead from the installed native optional dependency and the workspace release binary built on the runner.

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 500.7ms 2.01 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 481.9ms 2.09 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 378.4ms 2.66 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 347.8ms 2.89 GiB/s 1

Committed fixture performance

Committed small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage.

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 2 warmups and 7 runs.

Command Input Base median PR median PR vs base Base throughput PR throughput
claude daily --offline --json 0.00 MiB 32.0ms 32.3ms 0.99x 0.05 MiB/s 0.05 MiB/s
claude session --offline --json 0.00 MiB 32.1ms 31.9ms 1.01x 0.05 MiB/s 0.05 MiB/s
codex daily --offline --json 0.00 MiB 31.6ms 32.1ms 0.99x 0.03 MiB/s 0.03 MiB/s
codex session --offline --json 0.00 MiB 32.5ms 32.5ms 1.00x 0.03 MiB/s 0.03 MiB/s

Large real-world-shaped fixture performance

Generated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.

Command Input Base median PR median PR vs base Base throughput PR throughput
claude --offline --json 1.01 GiB 500.6ms 507.8ms 0.99x 2.01 GiB/s 1.98 GiB/s
codex --offline --json 1.01 GiB 375.4ms 376.9ms 1.00x 2.68 GiB/s 2.67 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 14.25 KiB 14.25 KiB -0.00 KiB 1.00x
installed native package binary 3225.49 KiB 3225.49 KiB +0.00 KiB 1.00x

Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees.

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: 0191915a02b3
Base SHA: b36c8c6bb62b

This compares the Rust PR release binary against the configured base package on the same CI runner.

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new b36c8c6bb62b 797.7ms 779.6ms 31.8ms 3
PR pkg.pr.new 0191915a02b3 680.6ms 542.5ms 33.4ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: b36c8c6bb62b; PR package: 0191915a02b3. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, measured by hyperfine with 0 warmups and 1 runs.

Command Input Base median PR median PR vs base Base throughput PR throughput
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 486.5ms 489.3ms 0.99x 2.07 GiB/s 2.06 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 356.8ms 361.0ms 0.99x 2.82 GiB/s 2.79 GiB/s

Package runtime diagnostics

Compares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
All rows run --offline --json, measured by hyperfine with 0 warmups and 1 runs. This isolates wrapper overhead from the installed native optional dependency and the workspace release binary built on the runner.

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 487.4ms 2.07 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 460.3ms 2.19 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 350.1ms 2.88 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 330.8ms 3.04 GiB/s 1

Committed fixture performance

Committed small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage.

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs rust/target/release/ccusage directly. Both run --offline --json, measured by hyperfine with 2 warmups and 7 runs.

Command Input Base median PR median PR vs base Base throughput PR throughput
claude daily --offline --json 0.00 MiB 29.8ms 4.0ms 7.45x 0.05 MiB/s 0.39 MiB/s
claude session --offline --json 0.00 MiB 30.1ms 4.1ms 7.39x 0.05 MiB/s 0.38 MiB/s
codex daily --offline --json 0.00 MiB 29.6ms 3.7ms 7.90x 0.03 MiB/s 0.23 MiB/s
codex session --offline --json 0.00 MiB 29.9ms 3.7ms 8.01x 0.03 MiB/s 0.23 MiB/s

Large real-world-shaped fixture performance

Generated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs rust/target/release/ccusage directly. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.

Command Input Base median PR median PR vs base Base throughput PR throughput
claude --offline --json 1.01 GiB 496.2ms 468.8ms 1.06x 2.03 GiB/s 2.15 GiB/s
codex --offline --json 1.01 GiB 358.6ms 330.6ms 1.08x 2.81 GiB/s 3.05 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 14.25 KiB 14.25 KiB -0.00 KiB 1.00x
installed native package binary 3225.49 KiB 3225.49 KiB +0.00 KiB 1.00x

Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees.

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: ade8b5859459
Base SHA: 9b5c307b45b4

This compares the Rust PR release binary against the configured base package on the same CI runner.

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new 9b5c307b45b4 845.3ms 378.9ms 33.9ms 3
PR pkg.pr.new ade8b5859459 495.9ms 492.3ms 34.5ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: 9b5c307b45b4; PR package: ade8b5859459. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 507.1ms 509.8ms 0.99x 256.70 MiB 268.45 MiB 1.05x 1.99 GiB/s 1.97 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 379.2ms 372.2ms 1.02x 57.08 MiB 59.45 MiB 1.04x 2.65 GiB/s 2.70 GiB/s

Package runtime diagnostics

Compares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
All rows run --offline --json, measured by hyperfine with 0 warmups and 1 runs. This isolates wrapper overhead from the installed native optional dependency and the workspace release binary built on the runner.

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 496.9ms 2.03 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 468.5ms 2.15 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 362.3ms 2.78 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 337.2ms 2.99 GiB/s 1

Committed fixture performance

Committed small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage.

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs rust/target/release/ccusage directly. Both run --offline --json, measured by hyperfine with 2 warmups and 7 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude daily --offline --json 0.00 MiB 31.4ms 4.2ms 7.39x 43.61 MiB 2.83 MiB 0.06x 0.05 MiB/s 0.36 MiB/s
claude session --offline --json 0.00 MiB 31.1ms 4.4ms 7.10x 43.48 MiB 2.83 MiB 0.07x 0.05 MiB/s 0.35 MiB/s
codex daily --offline --json 0.00 MiB 31.3ms 4.0ms 7.78x 43.48 MiB 2.83 MiB 0.07x 0.03 MiB/s 0.21 MiB/s
codex session --offline --json 0.00 MiB 31.7ms 4.0ms 7.88x 43.61 MiB 2.83 MiB 0.06x 0.03 MiB/s 0.21 MiB/s

Large real-world-shaped fixture performance

Generated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs rust/target/release/ccusage directly. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude --offline --json 1.01 GiB 507.6ms 480.7ms 1.06x 280.70 MiB 262.20 MiB 0.93x 1.98 GiB/s 2.09 GiB/s
codex --offline --json 1.01 GiB 368.9ms 341.9ms 1.08x 66.33 MiB 63.08 MiB 0.95x 2.73 GiB/s 2.94 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 14.25 KiB 14.25 KiB +0.00 KiB 1.00x
installed native package binary 3225.49 KiB 3225.49 KiB +0.00 KiB 1.00x

Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees.

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: ade8b5859459
Base SHA: 9b5c307b45b4

This compares the PR package against the configured base package on the same CI runner.

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new 9b5c307b45b4 556.8ms 785.0ms 33.9ms 3
PR pkg.pr.new ade8b5859459 468.0ms 667.2ms 34.2ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: 9b5c307b45b4; PR package: ade8b5859459. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 509.1ms 504.0ms 1.01x 268.33 MiB 270.20 MiB 1.01x 1.98 GiB/s 2.00 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 369.6ms 370.9ms 1.00x 55.45 MiB 58.95 MiB 1.06x 2.72 GiB/s 2.71 GiB/s

Package runtime diagnostics

Compares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
All rows run --offline --json, measured by hyperfine with 0 warmups and 1 runs. This isolates wrapper overhead from the installed native optional dependency and the workspace release binary built on the runner.

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 491.0ms 2.05 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 468.6ms 2.15 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 360.7ms 2.79 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 336.7ms 2.99 GiB/s 1

Committed fixture performance

Committed small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage.

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 2 warmups and 7 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude daily --offline --json 0.00 MiB 30.5ms 30.7ms 0.99x 43.61 MiB 43.36 MiB 0.99x 0.05 MiB/s 0.05 MiB/s
claude session --offline --json 0.00 MiB 30.7ms 30.8ms 1.00x 43.61 MiB 43.36 MiB 0.99x 0.05 MiB/s 0.05 MiB/s
codex daily --offline --json 0.00 MiB 30.0ms 30.8ms 0.97x 43.48 MiB 43.48 MiB 1.00x 0.03 MiB/s 0.03 MiB/s
codex session --offline --json 0.00 MiB 31.0ms 31.1ms 1.00x 43.36 MiB 43.48 MiB 1.00x 0.03 MiB/s 0.03 MiB/s

Large real-world-shaped fixture performance

Generated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude --offline --json 1.01 GiB 493.1ms 481.7ms 1.02x 267.08 MiB 249.20 MiB 0.93x 2.04 GiB/s 2.09 GiB/s
codex --offline --json 1.01 GiB 367.4ms 363.9ms 1.01x 60.08 MiB 65.33 MiB 1.09x 2.74 GiB/s 2.77 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 14.25 KiB 14.25 KiB +0.00 KiB 1.00x
installed native package binary 3225.49 KiB 3225.49 KiB +0.00 KiB 1.00x

Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees.

@ryoppippi
ryoppippi merged commit 41c0c6f into main May 23, 2026
40 checks passed
@ryoppippi
ryoppippi deleted the refactor/split-remaining-adapters branch May 23, 2026 19:22
jay-tau added a commit to jay-tau/ccusage that referenced this pull request Jun 8, 2026
…oc-comment

Both Opus 4.8 (seq-18 r1b) and Opus 4.7-xhigh (seq-18 r1b)
independently flagged the same Nit on the doc-comment added in
`a293751`: two of the three Claude citations pointed at
unrelated code.

## What was wrong

1. **`claude/mod.rs:768`** was cited as evidence that Claude
   preserves `costUSD`. That line is `cost_usd: None,` inside
   a test fixture (`mod tests` block at lines 760-787) — literally
   the opposite of cost preservation.
2. **`is_valid_daily_usage_entry`, `claude/mod.rs:272`** — the
   function does NOT live in `mod.rs` at this tip. It was moved
   into `daily.rs` by 41c0c6f ("refactor(adapter): split remaining
   adapter modules (ccusage#1137)") long before this PR. Its actual
   location is `claude/daily.rs:314` (definition); the call site
   is `claude/daily.rs:272`. Line 272 of `mod.rs` is an
   unrelated dedup `push_deduped_index` call.

The third citation (`claude/daily.rs:152`) was correct.

The substantive technical claim — that Claude preserves `costUSD`
per-message and the skip predicate doesn't drop zero-token entries
with a usage block — is true. Only the citations were wrong.

## Fix

Replaced the Claude bullet with verifiable citations:

- `claude/daily.rs:131` — `cost_usd: Option<f64>` field on
  `DailyUsageEntry`.
- `claude/daily.rs:152` — `cost_usd: entry.data.message.cost_usd`
  in `into_entry` (preservation site, was already correct).
- `claude/daily.rs:279` — `data.cost_usd` plumbed into
  `calculate_cost_for_usage` (production consumer).
- `claude/daily.rs:314` — `fn is_valid_daily_usage_entry`
  definition (skip predicate).
- `claude/daily.rs:272` — call site of `is_valid_daily_usage_entry`
  (where the per-line skip decision happens).

Verifying reader can now grep any of these lines and immediately
confirm the claim. The Hermes (`hermes/parser.rs:41-49`), Pi
(`pi/parser.rs:55-57`), and OpenCode (`opencode/parser.rs:34-40`)
citations all already verified cleanly and are unchanged.

## Validation at this tip

- `cd rust && cargo fmt --check` — clean
- `cd rust && cargo clippy --workspace --all-targets -- -D warnings` — clean
- `cd rust && cargo test --workspace` — 368 tests pass (unchanged;
  doc-comment-only change)

Refs ccusage#1174.

Co-authored-by: Copilot <[email protected]>
jay-tau added a commit to jay-tau/ccusage that referenced this pull request Jun 8, 2026
…omment

Opus 4.7-xhigh (seq-18 r1f) caught a stale doc-comment value: the
header for `accepts_fractional_premium_request_cost`
(`parser.rs:1194`) says the fixture mixes "a fractional row
(Opus 4.7, cost 7.5) with an integer-cost sibling (Sonnet, cost 4)",
but the actual fixture (`parser.rs:1221`) sets the Sonnet sibling
to cost 1 ("1 request × 1× multiplier = cost 1"), the inline
comment at `parser.rs:1219-1220` says "1× multiplier ... so 1
request × 1× = cost 1", and the assertion at `parser.rs:1240`
checks `Some(1.0)`.

Reviewer's git archaeology: the fixture was introduced as `cost: 4`
in `20b20ca` together with the matching "Sonnet, cost 4" header.
A later commit (`cc48cad`) renumbered the fixture to `cost: 1`
and added the "1× multiplier" inline comment, but the older
header line was not updated alongside it. Both commits are in this
PR's history.

## Fix

Reworded the header parenthetical from "(Sonnet, cost 4)" to
"(Sonnet 4.5, cost 1 — 1 request × 1× multiplier)". This:

- Matches the fixture (cost 1).
- Matches the inline comment's multiplier explanation.
- Names the specific Sonnet variant (4.5) so a reader doesn't
  have to scroll to the fixture to disambiguate.

## Validation at this tip

- `cd rust && cargo fmt --check` — clean
- `cd rust && cargo clippy --workspace --all-targets -- -D warnings` — clean
- `cd rust && cargo test --workspace` — 368 tests pass (unchanged;
  doc-comment-only change)

## Out-of-scope finding from same round (NOT addressed by this commit)

GPT-5.5 (seq-18 r1f) flagged a HIGH about `codex/aggregate.rs:347`
double-counting branch-history events because the aggregate dedupe
key includes `session_id` while the loader dedupe intentionally
removed it. `git blame` confirms that file was last touched by
upstream PRs ccusage#1158 (eef2543) and ccusage#1137 (41c0c6f) and has NOT been
touched by PR ccusage#1209. `git log upstream/main..HEAD -- rust/crates/ccusage/src/adapter/codex/`
returns zero commits from this PR.

That bug is pre-existing in the Codex adapter and unrelated to PR
ccusage#1209's scope (Copilot adapter + cross-source --all credits
handling). Per repo guidelines ("Don't fix pre-existing issues
unrelated to your task ... unless they're tightly coupled to the
code you're changing"), it's out of scope here and should be filed
as a separate issue against the Codex adapter or fixed in a
follow-up PR. The seq-17 / seq-18 review framework happened to
surface it, but addressing it in this branch would expand scope.

Refs ccusage#1174.

Co-authored-by: Copilot <[email protected]>
jay-tau added a commit to jay-tau/ccusage that referenced this pull request Jun 9, 2026
…oc-comment

Both Opus 4.8 (seq-18 r1b) and Opus 4.7-xhigh (seq-18 r1b)
independently flagged the same Nit on the doc-comment added in
`a293751`: two of the three Claude citations pointed at
unrelated code.

## What was wrong

1. **`claude/mod.rs:768`** was cited as evidence that Claude
   preserves `costUSD`. That line is `cost_usd: None,` inside
   a test fixture (`mod tests` block at lines 760-787) — literally
   the opposite of cost preservation.
2. **`is_valid_daily_usage_entry`, `claude/mod.rs:272`** — the
   function does NOT live in `mod.rs` at this tip. It was moved
   into `daily.rs` by 41c0c6f ("refactor(adapter): split remaining
   adapter modules (ccusage#1137)") long before this PR. Its actual
   location is `claude/daily.rs:314` (definition); the call site
   is `claude/daily.rs:272`. Line 272 of `mod.rs` is an
   unrelated dedup `push_deduped_index` call.

The third citation (`claude/daily.rs:152`) was correct.

The substantive technical claim — that Claude preserves `costUSD`
per-message and the skip predicate doesn't drop zero-token entries
with a usage block — is true. Only the citations were wrong.

## Fix

Replaced the Claude bullet with verifiable citations:

- `claude/daily.rs:131` — `cost_usd: Option<f64>` field on
  `DailyUsageEntry`.
- `claude/daily.rs:152` — `cost_usd: entry.data.message.cost_usd`
  in `into_entry` (preservation site, was already correct).
- `claude/daily.rs:279` — `data.cost_usd` plumbed into
  `calculate_cost_for_usage` (production consumer).
- `claude/daily.rs:314` — `fn is_valid_daily_usage_entry`
  definition (skip predicate).
- `claude/daily.rs:272` — call site of `is_valid_daily_usage_entry`
  (where the per-line skip decision happens).

Verifying reader can now grep any of these lines and immediately
confirm the claim. The Hermes (`hermes/parser.rs:41-49`), Pi
(`pi/parser.rs:55-57`), and OpenCode (`opencode/parser.rs:34-40`)
citations all already verified cleanly and are unchanged.

## Validation at this tip

- `cd rust && cargo fmt --check` — clean
- `cd rust && cargo clippy --workspace --all-targets -- -D warnings` — clean
- `cd rust && cargo test --workspace` — 368 tests pass (unchanged;
  doc-comment-only change)

Refs ccusage#1174.

Co-authored-by: Copilot <[email protected]>
jay-tau added a commit to jay-tau/ccusage that referenced this pull request Jun 9, 2026
…omment

Opus 4.7-xhigh (seq-18 r1f) caught a stale doc-comment value: the
header for `accepts_fractional_premium_request_cost`
(`parser.rs:1194`) says the fixture mixes "a fractional row
(Opus 4.7, cost 7.5) with an integer-cost sibling (Sonnet, cost 4)",
but the actual fixture (`parser.rs:1221`) sets the Sonnet sibling
to cost 1 ("1 request × 1× multiplier = cost 1"), the inline
comment at `parser.rs:1219-1220` says "1× multiplier ... so 1
request × 1× = cost 1", and the assertion at `parser.rs:1240`
checks `Some(1.0)`.

Reviewer's git archaeology: the fixture was introduced as `cost: 4`
in `20b20ca` together with the matching "Sonnet, cost 4" header.
A later commit (`cc48cad`) renumbered the fixture to `cost: 1`
and added the "1× multiplier" inline comment, but the older
header line was not updated alongside it. Both commits are in this
PR's history.

## Fix

Reworded the header parenthetical from "(Sonnet, cost 4)" to
"(Sonnet 4.5, cost 1 — 1 request × 1× multiplier)". This:

- Matches the fixture (cost 1).
- Matches the inline comment's multiplier explanation.
- Names the specific Sonnet variant (4.5) so a reader doesn't
  have to scroll to the fixture to disambiguate.

## Validation at this tip

- `cd rust && cargo fmt --check` — clean
- `cd rust && cargo clippy --workspace --all-targets -- -D warnings` — clean
- `cd rust && cargo test --workspace` — 368 tests pass (unchanged;
  doc-comment-only change)

## Out-of-scope finding from same round (NOT addressed by this commit)

GPT-5.5 (seq-18 r1f) flagged a HIGH about `codex/aggregate.rs:347`
double-counting branch-history events because the aggregate dedupe
key includes `session_id` while the loader dedupe intentionally
removed it. `git blame` confirms that file was last touched by
upstream PRs ccusage#1158 (eef2543) and ccusage#1137 (41c0c6f) and has NOT been
touched by PR ccusage#1209. `git log upstream/main..HEAD -- rust/crates/ccusage/src/adapter/codex/`
returns zero commits from this PR.

That bug is pre-existing in the Codex adapter and unrelated to PR
ccusage#1209's scope (Copilot adapter + cross-source --all credits
handling). Per repo guidelines ("Don't fix pre-existing issues
unrelated to your task ... unless they're tightly coupled to the
code you're changing"), it's out of scope here and should be filed
as a separate issue against the Codex adapter or fixed in a
follow-up PR. The seq-17 / seq-18 review framework happened to
surface it, but addressing it in this branch would expand scope.

Refs ccusage#1174.

Co-authored-by: Copilot <[email protected]>
jay-tau added a commit to jay-tau/ccusage that referenced this pull request Jun 9, 2026
…oc-comment

Both Opus 4.8 (seq-18 r1b) and Opus 4.7-xhigh (seq-18 r1b)
independently flagged the same Nit on the doc-comment added in
`a293751`: two of the three Claude citations pointed at
unrelated code.

## What was wrong

1. **`claude/mod.rs:768`** was cited as evidence that Claude
   preserves `costUSD`. That line is `cost_usd: None,` inside
   a test fixture (`mod tests` block at lines 760-787) — literally
   the opposite of cost preservation.
2. **`is_valid_daily_usage_entry`, `claude/mod.rs:272`** — the
   function does NOT live in `mod.rs` at this tip. It was moved
   into `daily.rs` by 41c0c6f ("refactor(adapter): split remaining
   adapter modules (ccusage#1137)") long before this PR. Its actual
   location is `claude/daily.rs:314` (definition); the call site
   is `claude/daily.rs:272`. Line 272 of `mod.rs` is an
   unrelated dedup `push_deduped_index` call.

The third citation (`claude/daily.rs:152`) was correct.

The substantive technical claim — that Claude preserves `costUSD`
per-message and the skip predicate doesn't drop zero-token entries
with a usage block — is true. Only the citations were wrong.

## Fix

Replaced the Claude bullet with verifiable citations:

- `claude/daily.rs:131` — `cost_usd: Option<f64>` field on
  `DailyUsageEntry`.
- `claude/daily.rs:152` — `cost_usd: entry.data.message.cost_usd`
  in `into_entry` (preservation site, was already correct).
- `claude/daily.rs:279` — `data.cost_usd` plumbed into
  `calculate_cost_for_usage` (production consumer).
- `claude/daily.rs:314` — `fn is_valid_daily_usage_entry`
  definition (skip predicate).
- `claude/daily.rs:272` — call site of `is_valid_daily_usage_entry`
  (where the per-line skip decision happens).

Verifying reader can now grep any of these lines and immediately
confirm the claim. The Hermes (`hermes/parser.rs:41-49`), Pi
(`pi/parser.rs:55-57`), and OpenCode (`opencode/parser.rs:34-40`)
citations all already verified cleanly and are unchanged.

## Validation at this tip

- `cd rust && cargo fmt --check` — clean
- `cd rust && cargo clippy --workspace --all-targets -- -D warnings` — clean
- `cd rust && cargo test --workspace` — 368 tests pass (unchanged;
  doc-comment-only change)

Refs ccusage#1174.

Co-authored-by: Copilot <[email protected]>
jay-tau added a commit to jay-tau/ccusage that referenced this pull request Jun 9, 2026
…omment

Opus 4.7-xhigh (seq-18 r1f) caught a stale doc-comment value: the
header for `accepts_fractional_premium_request_cost`
(`parser.rs:1194`) says the fixture mixes "a fractional row
(Opus 4.7, cost 7.5) with an integer-cost sibling (Sonnet, cost 4)",
but the actual fixture (`parser.rs:1221`) sets the Sonnet sibling
to cost 1 ("1 request × 1× multiplier = cost 1"), the inline
comment at `parser.rs:1219-1220` says "1× multiplier ... so 1
request × 1× = cost 1", and the assertion at `parser.rs:1240`
checks `Some(1.0)`.

Reviewer's git archaeology: the fixture was introduced as `cost: 4`
in `20b20ca` together with the matching "Sonnet, cost 4" header.
A later commit (`cc48cad`) renumbered the fixture to `cost: 1`
and added the "1× multiplier" inline comment, but the older
header line was not updated alongside it. Both commits are in this
PR's history.

## Fix

Reworded the header parenthetical from "(Sonnet, cost 4)" to
"(Sonnet 4.5, cost 1 — 1 request × 1× multiplier)". This:

- Matches the fixture (cost 1).
- Matches the inline comment's multiplier explanation.
- Names the specific Sonnet variant (4.5) so a reader doesn't
  have to scroll to the fixture to disambiguate.

## Validation at this tip

- `cd rust && cargo fmt --check` — clean
- `cd rust && cargo clippy --workspace --all-targets -- -D warnings` — clean
- `cd rust && cargo test --workspace` — 368 tests pass (unchanged;
  doc-comment-only change)

## Out-of-scope finding from same round (NOT addressed by this commit)

GPT-5.5 (seq-18 r1f) flagged a HIGH about `codex/aggregate.rs:347`
double-counting branch-history events because the aggregate dedupe
key includes `session_id` while the loader dedupe intentionally
removed it. `git blame` confirms that file was last touched by
upstream PRs ccusage#1158 (eef2543) and ccusage#1137 (41c0c6f) and has NOT been
touched by PR ccusage#1209. `git log upstream/main..HEAD -- rust/crates/ccusage/src/adapter/codex/`
returns zero commits from this PR.

That bug is pre-existing in the Codex adapter and unrelated to PR
ccusage#1209's scope (Copilot adapter + cross-source --all credits
handling). Per repo guidelines ("Don't fix pre-existing issues
unrelated to your task ... unless they're tightly coupled to the
code you're changing"), it's out of scope here and should be filed
as a separate issue against the Codex adapter or fixed in a
follow-up PR. The seq-17 / seq-18 review framework happened to
surface it, but addressing it in this branch would expand scope.

Refs ccusage#1174.

Co-authored-by: Copilot <[email protected]>
jay-tau added a commit to jay-tau/ccusage that referenced this pull request Jun 10, 2026
…oc-comment

Both Opus 4.8 (seq-18 r1b) and Opus 4.7-xhigh (seq-18 r1b)
independently flagged the same Nit on the doc-comment added in
`a293751`: two of the three Claude citations pointed at
unrelated code.

## What was wrong

1. **`claude/mod.rs:768`** was cited as evidence that Claude
   preserves `costUSD`. That line is `cost_usd: None,` inside
   a test fixture (`mod tests` block at lines 760-787) — literally
   the opposite of cost preservation.
2. **`is_valid_daily_usage_entry`, `claude/mod.rs:272`** — the
   function does NOT live in `mod.rs` at this tip. It was moved
   into `daily.rs` by 41c0c6f ("refactor(adapter): split remaining
   adapter modules (ccusage#1137)") long before this PR. Its actual
   location is `claude/daily.rs:314` (definition); the call site
   is `claude/daily.rs:272`. Line 272 of `mod.rs` is an
   unrelated dedup `push_deduped_index` call.

The third citation (`claude/daily.rs:152`) was correct.

The substantive technical claim — that Claude preserves `costUSD`
per-message and the skip predicate doesn't drop zero-token entries
with a usage block — is true. Only the citations were wrong.

## Fix

Replaced the Claude bullet with verifiable citations:

- `claude/daily.rs:131` — `cost_usd: Option<f64>` field on
  `DailyUsageEntry`.
- `claude/daily.rs:152` — `cost_usd: entry.data.message.cost_usd`
  in `into_entry` (preservation site, was already correct).
- `claude/daily.rs:279` — `data.cost_usd` plumbed into
  `calculate_cost_for_usage` (production consumer).
- `claude/daily.rs:314` — `fn is_valid_daily_usage_entry`
  definition (skip predicate).
- `claude/daily.rs:272` — call site of `is_valid_daily_usage_entry`
  (where the per-line skip decision happens).

Verifying reader can now grep any of these lines and immediately
confirm the claim. The Hermes (`hermes/parser.rs:41-49`), Pi
(`pi/parser.rs:55-57`), and OpenCode (`opencode/parser.rs:34-40`)
citations all already verified cleanly and are unchanged.

## Validation at this tip

- `cd rust && cargo fmt --check` — clean
- `cd rust && cargo clippy --workspace --all-targets -- -D warnings` — clean
- `cd rust && cargo test --workspace` — 368 tests pass (unchanged;
  doc-comment-only change)

Refs ccusage#1174.

Co-authored-by: Copilot <[email protected]>
jay-tau added a commit to jay-tau/ccusage that referenced this pull request Jun 10, 2026
…omment

Opus 4.7-xhigh (seq-18 r1f) caught a stale doc-comment value: the
header for `accepts_fractional_premium_request_cost`
(`parser.rs:1194`) says the fixture mixes "a fractional row
(Opus 4.7, cost 7.5) with an integer-cost sibling (Sonnet, cost 4)",
but the actual fixture (`parser.rs:1221`) sets the Sonnet sibling
to cost 1 ("1 request × 1× multiplier = cost 1"), the inline
comment at `parser.rs:1219-1220` says "1× multiplier ... so 1
request × 1× = cost 1", and the assertion at `parser.rs:1240`
checks `Some(1.0)`.

Reviewer's git archaeology: the fixture was introduced as `cost: 4`
in `20b20ca` together with the matching "Sonnet, cost 4" header.
A later commit (`cc48cad`) renumbered the fixture to `cost: 1`
and added the "1× multiplier" inline comment, but the older
header line was not updated alongside it. Both commits are in this
PR's history.

## Fix

Reworded the header parenthetical from "(Sonnet, cost 4)" to
"(Sonnet 4.5, cost 1 — 1 request × 1× multiplier)". This:

- Matches the fixture (cost 1).
- Matches the inline comment's multiplier explanation.
- Names the specific Sonnet variant (4.5) so a reader doesn't
  have to scroll to the fixture to disambiguate.

## Validation at this tip

- `cd rust && cargo fmt --check` — clean
- `cd rust && cargo clippy --workspace --all-targets -- -D warnings` — clean
- `cd rust && cargo test --workspace` — 368 tests pass (unchanged;
  doc-comment-only change)

## Out-of-scope finding from same round (NOT addressed by this commit)

GPT-5.5 (seq-18 r1f) flagged a HIGH about `codex/aggregate.rs:347`
double-counting branch-history events because the aggregate dedupe
key includes `session_id` while the loader dedupe intentionally
removed it. `git blame` confirms that file was last touched by
upstream PRs ccusage#1158 (eef2543) and ccusage#1137 (41c0c6f) and has NOT been
touched by PR ccusage#1209. `git log upstream/main..HEAD -- rust/crates/ccusage/src/adapter/codex/`
returns zero commits from this PR.

That bug is pre-existing in the Codex adapter and unrelated to PR
ccusage#1209's scope (Copilot adapter + cross-source --all credits
handling). Per repo guidelines ("Don't fix pre-existing issues
unrelated to your task ... unless they're tightly coupled to the
code you're changing"), it's out of scope here and should be filed
as a separate issue against the Codex adapter or fixed in a
follow-up PR. The seq-17 / seq-18 review framework happened to
surface it, but addressing it in this branch would expand scope.

Refs ccusage#1174.

Co-authored-by: Copilot <[email protected]>
jay-tau added a commit to jay-tau/ccusage that referenced this pull request Jun 11, 2026
…oc-comment

Both Opus 4.8 (seq-18 r1b) and Opus 4.7-xhigh (seq-18 r1b)
independently flagged the same Nit on the doc-comment added in
`a293751`: two of the three Claude citations pointed at
unrelated code.

## What was wrong

1. **`claude/mod.rs:768`** was cited as evidence that Claude
   preserves `costUSD`. That line is `cost_usd: None,` inside
   a test fixture (`mod tests` block at lines 760-787) — literally
   the opposite of cost preservation.
2. **`is_valid_daily_usage_entry`, `claude/mod.rs:272`** — the
   function does NOT live in `mod.rs` at this tip. It was moved
   into `daily.rs` by 41c0c6f ("refactor(adapter): split remaining
   adapter modules (ccusage#1137)") long before this PR. Its actual
   location is `claude/daily.rs:314` (definition); the call site
   is `claude/daily.rs:272`. Line 272 of `mod.rs` is an
   unrelated dedup `push_deduped_index` call.

The third citation (`claude/daily.rs:152`) was correct.

The substantive technical claim — that Claude preserves `costUSD`
per-message and the skip predicate doesn't drop zero-token entries
with a usage block — is true. Only the citations were wrong.

## Fix

Replaced the Claude bullet with verifiable citations:

- `claude/daily.rs:131` — `cost_usd: Option<f64>` field on
  `DailyUsageEntry`.
- `claude/daily.rs:152` — `cost_usd: entry.data.message.cost_usd`
  in `into_entry` (preservation site, was already correct).
- `claude/daily.rs:279` — `data.cost_usd` plumbed into
  `calculate_cost_for_usage` (production consumer).
- `claude/daily.rs:314` — `fn is_valid_daily_usage_entry`
  definition (skip predicate).
- `claude/daily.rs:272` — call site of `is_valid_daily_usage_entry`
  (where the per-line skip decision happens).

Verifying reader can now grep any of these lines and immediately
confirm the claim. The Hermes (`hermes/parser.rs:41-49`), Pi
(`pi/parser.rs:55-57`), and OpenCode (`opencode/parser.rs:34-40`)
citations all already verified cleanly and are unchanged.

## Validation at this tip

- `cd rust && cargo fmt --check` — clean
- `cd rust && cargo clippy --workspace --all-targets -- -D warnings` — clean
- `cd rust && cargo test --workspace` — 368 tests pass (unchanged;
  doc-comment-only change)

Refs ccusage#1174.

Co-authored-by: Copilot <[email protected]>
jay-tau added a commit to jay-tau/ccusage that referenced this pull request Jun 11, 2026
…omment

Opus 4.7-xhigh (seq-18 r1f) caught a stale doc-comment value: the
header for `accepts_fractional_premium_request_cost`
(`parser.rs:1194`) says the fixture mixes "a fractional row
(Opus 4.7, cost 7.5) with an integer-cost sibling (Sonnet, cost 4)",
but the actual fixture (`parser.rs:1221`) sets the Sonnet sibling
to cost 1 ("1 request × 1× multiplier = cost 1"), the inline
comment at `parser.rs:1219-1220` says "1× multiplier ... so 1
request × 1× = cost 1", and the assertion at `parser.rs:1240`
checks `Some(1.0)`.

Reviewer's git archaeology: the fixture was introduced as `cost: 4`
in `20b20ca` together with the matching "Sonnet, cost 4" header.
A later commit (`cc48cad`) renumbered the fixture to `cost: 1`
and added the "1× multiplier" inline comment, but the older
header line was not updated alongside it. Both commits are in this
PR's history.

## Fix

Reworded the header parenthetical from "(Sonnet, cost 4)" to
"(Sonnet 4.5, cost 1 — 1 request × 1× multiplier)". This:

- Matches the fixture (cost 1).
- Matches the inline comment's multiplier explanation.
- Names the specific Sonnet variant (4.5) so a reader doesn't
  have to scroll to the fixture to disambiguate.

## Validation at this tip

- `cd rust && cargo fmt --check` — clean
- `cd rust && cargo clippy --workspace --all-targets -- -D warnings` — clean
- `cd rust && cargo test --workspace` — 368 tests pass (unchanged;
  doc-comment-only change)

## Out-of-scope finding from same round (NOT addressed by this commit)

GPT-5.5 (seq-18 r1f) flagged a HIGH about `codex/aggregate.rs:347`
double-counting branch-history events because the aggregate dedupe
key includes `session_id` while the loader dedupe intentionally
removed it. `git blame` confirms that file was last touched by
upstream PRs ccusage#1158 (eef2543) and ccusage#1137 (41c0c6f) and has NOT been
touched by PR ccusage#1209. `git log upstream/main..HEAD -- rust/crates/ccusage/src/adapter/codex/`
returns zero commits from this PR.

That bug is pre-existing in the Codex adapter and unrelated to PR
ccusage#1209's scope (Copilot adapter + cross-source --all credits
handling). Per repo guidelines ("Don't fix pre-existing issues
unrelated to your task ... unless they're tightly coupled to the
code you're changing"), it's out of scope here and should be filed
as a separate issue against the Codex adapter or fixed in a
follow-up PR. The seq-17 / seq-18 review framework happened to
surface it, but addressing it in this branch would expand scope.

Refs ccusage#1174.

Co-authored-by: Copilot <[email protected]>
jay-tau added a commit to jay-tau/ccusage that referenced this pull request Jun 11, 2026
…oc-comment

Both Opus 4.8 (seq-18 r1b) and Opus 4.7-xhigh (seq-18 r1b)
independently flagged the same Nit on the doc-comment added in
`a293751`: two of the three Claude citations pointed at
unrelated code.

## What was wrong

1. **`claude/mod.rs:768`** was cited as evidence that Claude
   preserves `costUSD`. That line is `cost_usd: None,` inside
   a test fixture (`mod tests` block at lines 760-787) — literally
   the opposite of cost preservation.
2. **`is_valid_daily_usage_entry`, `claude/mod.rs:272`** — the
   function does NOT live in `mod.rs` at this tip. It was moved
   into `daily.rs` by 41c0c6f ("refactor(adapter): split remaining
   adapter modules (ccusage#1137)") long before this PR. Its actual
   location is `claude/daily.rs:314` (definition); the call site
   is `claude/daily.rs:272`. Line 272 of `mod.rs` is an
   unrelated dedup `push_deduped_index` call.

The third citation (`claude/daily.rs:152`) was correct.

The substantive technical claim — that Claude preserves `costUSD`
per-message and the skip predicate doesn't drop zero-token entries
with a usage block — is true. Only the citations were wrong.

## Fix

Replaced the Claude bullet with verifiable citations:

- `claude/daily.rs:131` — `cost_usd: Option<f64>` field on
  `DailyUsageEntry`.
- `claude/daily.rs:152` — `cost_usd: entry.data.message.cost_usd`
  in `into_entry` (preservation site, was already correct).
- `claude/daily.rs:279` — `data.cost_usd` plumbed into
  `calculate_cost_for_usage` (production consumer).
- `claude/daily.rs:314` — `fn is_valid_daily_usage_entry`
  definition (skip predicate).
- `claude/daily.rs:272` — call site of `is_valid_daily_usage_entry`
  (where the per-line skip decision happens).

Verifying reader can now grep any of these lines and immediately
confirm the claim. The Hermes (`hermes/parser.rs:41-49`), Pi
(`pi/parser.rs:55-57`), and OpenCode (`opencode/parser.rs:34-40`)
citations all already verified cleanly and are unchanged.

## Validation at this tip

- `cd rust && cargo fmt --check` — clean
- `cd rust && cargo clippy --workspace --all-targets -- -D warnings` — clean
- `cd rust && cargo test --workspace` — 368 tests pass (unchanged;
  doc-comment-only change)

Refs ccusage#1174.

Co-authored-by: Copilot <[email protected]>
jay-tau added a commit to jay-tau/ccusage that referenced this pull request Jun 11, 2026
…omment

Opus 4.7-xhigh (seq-18 r1f) caught a stale doc-comment value: the
header for `accepts_fractional_premium_request_cost`
(`parser.rs:1194`) says the fixture mixes "a fractional row
(Opus 4.7, cost 7.5) with an integer-cost sibling (Sonnet, cost 4)",
but the actual fixture (`parser.rs:1221`) sets the Sonnet sibling
to cost 1 ("1 request × 1× multiplier = cost 1"), the inline
comment at `parser.rs:1219-1220` says "1× multiplier ... so 1
request × 1× = cost 1", and the assertion at `parser.rs:1240`
checks `Some(1.0)`.

Reviewer's git archaeology: the fixture was introduced as `cost: 4`
in `20b20ca` together with the matching "Sonnet, cost 4" header.
A later commit (`cc48cad`) renumbered the fixture to `cost: 1`
and added the "1× multiplier" inline comment, but the older
header line was not updated alongside it. Both commits are in this
PR's history.

## Fix

Reworded the header parenthetical from "(Sonnet, cost 4)" to
"(Sonnet 4.5, cost 1 — 1 request × 1× multiplier)". This:

- Matches the fixture (cost 1).
- Matches the inline comment's multiplier explanation.
- Names the specific Sonnet variant (4.5) so a reader doesn't
  have to scroll to the fixture to disambiguate.

## Validation at this tip

- `cd rust && cargo fmt --check` — clean
- `cd rust && cargo clippy --workspace --all-targets -- -D warnings` — clean
- `cd rust && cargo test --workspace` — 368 tests pass (unchanged;
  doc-comment-only change)

## Out-of-scope finding from same round (NOT addressed by this commit)

GPT-5.5 (seq-18 r1f) flagged a HIGH about `codex/aggregate.rs:347`
double-counting branch-history events because the aggregate dedupe
key includes `session_id` while the loader dedupe intentionally
removed it. `git blame` confirms that file was last touched by
upstream PRs ccusage#1158 (eef2543) and ccusage#1137 (41c0c6f) and has NOT been
touched by PR ccusage#1209. `git log upstream/main..HEAD -- rust/crates/ccusage/src/adapter/codex/`
returns zero commits from this PR.

That bug is pre-existing in the Codex adapter and unrelated to PR
ccusage#1209's scope (Copilot adapter + cross-source --all credits
handling). Per repo guidelines ("Don't fix pre-existing issues
unrelated to your task ... unless they're tightly coupled to the
code you're changing"), it's out of scope here and should be filed
as a separate issue against the Codex adapter or fixed in a
follow-up PR. The seq-17 / seq-18 review framework happened to
surface it, but addressing it in this branch would expand scope.

Refs ccusage#1174.

Co-authored-by: Copilot <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant