refactor(adapter): split remaining adapter modules - #1137
Conversation
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.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughRefactors 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. ChangesAdapter module refactoring
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
@coderabbitai review\n@cubic-dev-ai review |
|
✅ Actions performedReview triggered.
|
Deploying with
|
| 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 |
There was a problem hiding this comment.
🧹 Nitpick comments (3)
rust/crates/ccusage/src/adapter/all/loader.rs (1)
21-634: 🏗️ Heavy liftSplit 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 liftAdd 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 valueConsider reusing
codex_home_pathsfrompaths.rsto 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 tosuper::paths, you could import and call the shared version.Note that
paths::codex_home_paths()returnsResult<Vec<PathBuf>>while this returnsVec<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 toStandardspeed 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
📒 Files selected for processing (17)
rust/crates/ccusage/src/adapter/all.rsrust/crates/ccusage/src/adapter/all/loader.rsrust/crates/ccusage/src/adapter/all/mod.rsrust/crates/ccusage/src/adapter/all/report.rsrust/crates/ccusage/src/adapter/all/tests.rsrust/crates/ccusage/src/adapter/all/types.rsrust/crates/ccusage/src/adapter/claude/daily.rsrust/crates/ccusage/src/adapter/claude/mod.rsrust/crates/ccusage/src/adapter/claude/paths.rsrust/crates/ccusage/src/adapter/codex/aggregate.rsrust/crates/ccusage/src/adapter/codex/loader.rsrust/crates/ccusage/src/adapter/codex/mod.rsrust/crates/ccusage/src/adapter/codex/parser.rsrust/crates/ccusage/src/adapter/codex/paths.rsrust/crates/ccusage/src/adapter/codex/report.rsrust/crates/ccusage/src/adapter/codex/speed.rsrust/crates/ccusage/src/adapter/codex/types.rs
💤 Files with no reviewable changes (1)
- rust/crates/ccusage/src/adapter/all.rs
There was a problem hiding this comment.
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
| let Some(raw_usage) = raw_usage else { | ||
| return Ok(()); | ||
| }; | ||
| if raw_usage.input_tokens == 0 |
There was a problem hiding this comment.
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>
ccusage
@ccusage/ccusage-darwin-arm64
@ccusage/ccusage-darwin-x64
@ccusage/ccusage-linux-arm64
@ccusage/ccusage-linux-x64
@ccusage/ccusage-win32-arm64
@ccusage/ccusage-win32-x64
commit: |
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares 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
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated 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
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares 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
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated 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
Artifact size
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.
|
@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:
|
|
Tip For best results, initiate chat on the files or code changes.
service_tier detection fix — The approach of reusing the shared Codex home path discovery and matching only the exact 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 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! |
@ryoppippi The On the The refactor looks clean overall. Tip: get faster answers by chatting with cubic’s review copilot in the review UI |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares 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
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated 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
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares 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
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated 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
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares 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
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated 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
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares 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
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated 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
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
…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]>
…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]>
…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]>
…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]>
…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]>
…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]>
…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]>
…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]>
…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]>
…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]>
…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]>
…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]>
Splits the remaining large adapter modules for all-agent reporting, Codex, and Claude into focused files without changing their public behavior.
What changed:
Validation:
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 whenCodexSpeed::Autoto avoid false positives.Refactors
adapter/all: Moved loading, reporting, types, and tests intoadapter/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_HOMEpath discovery and parsedconfig.tomlby exactservice_tierkey and fast-tier values only, preventing matches likeservice_tier_overrideor substring hits (e.g., “breakfast”).Written for commit ade8b58. Summary will update on new commits. Review in cubic
Summary by CodeRabbit
New Features
Chores
Tests