Skip to content

fix(cli): accept --start-of-week on top-level weekly - #1945

Merged
ryoppippi merged 3 commits into
mainfrom
cursor/weekly-start-of-week-65e7
Oct 21, 2026
Merged

ryoppippi merged 3 commits into
mainfrom
cursor/weekly-start-of-week-65e7

Conversation

@ryoppippi

@ryoppippi ryoppippi commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

Summary

Restores -w/--start-of-week on the top-level ccusage weekly command, and lists it in ccusage weekly --help.

External bug report: ENjxzlt/Claude-Code-Usage-Streamcontroller#9 (reported by @jgorres). On v20.0.39, ccusage weekly --json --offline --last 1 -w <day> fails with Unknown option '-w', even though the docs show ccusage weekly -w monday.

Root cause

In 20.x, ccusage weekly became the unified all-agent report. The parser sends it through parse_all_command, which only accepts the shared flags plus --sections/--by-agent. Only parse_claude_weekly_command (ccusage claude weekly) still handled -w/--start-of-week. On top of that, the unified loader and the --last window always used Monday weeks, and the top-level help page used the generic period option set, which doesn't include the flag.

Changes

  • AgentCommandArgs gets a start_of_week field. It defaults to Monday, so output for anyone not passing the flag is unchanged.
  • parse_all_command accepts -w/--start-of-week (including the --start-of-week=<day> form), but only for weekly. It also applies commands.weekly.startOfWeek from the config file, which config-files.md already documents and which was being ignored for the top-level command. The CLI flag overrides the config value.
  • The unified loader (load_rows/load_sections, then aggregate_rows) and the --last window both use the chosen week start.
  • Help: ccusage weekly --help now lists -w, --start-of-week with default: monday.
  • Docs: weekly-reports.md no longer calls Sunday the default for ccusage weekly (Sunday is still the default for ccusage claude weekly), and cli-options.md no longer says --start-of-week only works on ccusage claude weekly.

Tests

  • Parser:
    • The reporter's exact command, the = form, and the Monday default.
    • Config is applied, and the CLI flag beats it.
    • -w is still rejected on daily, and invalid day values are rejected.
    • ccusage weekly --help lists the flag; ccusage daily --help doesn't.
  • Unified adapter: weekly buckets follow the requested start day.
  • last_window: on the unified weekly report, --last uses the chosen week start.
  • Ran locally:
    • cargo test --workspace: all pass.
    • cargo clippy --workspace --all-targets -- -D warnings: clean.
    • Node tests: 34/34 pass.
    • oxlint: no findings.
  • End-to-end with a fixture: ccusage weekly -w sunday, -w monday, and --start-of-week=wednesday bucket correctly, and --last 1 -w <day> starts the window on that day.
Open in Web Open in Cursor 

Summary by cubic

Restores -w/--start-of-week on the top-level ccusage weekly so the documented ccusage weekly -w monday works again; since 20.x the unified all-agent parser rejected the flag with Unknown option '-w'. Output is unchanged for anyone not passing the flag (Monday stays the default).

  • The chosen week start now drives both weekly bucketing and the --last window.
  • commands.weekly.startOfWeek from the config file is now applied; the CLI flag overrides it.
  • ccusage weekly --help lists the flag with default: monday and the docs were corrected (Sunday remains the default only for ccusage claude weekly).
  • The flag is still rejected on non-weekly reports such as ccusage daily.

Written for commit eccd732. Summary will update on new commits.

View guided diff Turn on auto-fix

Summary by CodeRabbit

  • New Features

    • Weekly reports now support -w/--start-of-week, allowing any weekday to define reporting periods.
    • Week-start settings can be configured and overridden from the command line.
    • ccusage weekly defaults to Monday, while ccusage claude weekly defaults to Sunday.
    • Selected week starts are applied consistently to report grouping and --last date ranges.
  • Documentation

    • Clarified week-start defaults and configuration options.
  • Tests

    • Added coverage for weekdays, defaults, overrides, validation, and weekly date grouping.

cursoragent and others added 2 commits October 21, 2026 18:14
Since 20.x, `ccusage weekly` is the unified all-agent report and was
parsed by the generic all-agent path, which only accepted shared flags.
Only `ccusage claude weekly` still handled `-w/--start-of-week`, so the
documented `ccusage weekly -w monday` failed with "Unknown option '-w'"
and the flag was missing from `ccusage weekly --help`.

Parse `-w/--start-of-week` (and `commands.weekly.startOfWeek` config) for
the top-level weekly report, carry it on AgentCommandArgs, and use it for
both the unified week bucketing and the `--last` window. The default
stays Monday, so existing output is unchanged.

Co-authored-by: jgorres <[email protected]>
@coderabbitai

coderabbitai Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 8ae0c777-25c5-454c-973e-412188317f4a
📥 Commits

Reviewing files that changed from the base of the PR and between 4fda612 and eccd732.

📒 Files selected for processing: 3
  • docs/guide/cli-options.md
  • docs/guide/weekly-reports.md
  • rust/crates/ccusage-adapter-all/src/tests.rs
🚧 Files skipped from review as they are similar to previous changes: 1
  • docs/guide/weekly-reports.md

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

📝 Walkthrough

Weekly reports now accept a configurable start day. The selected day is passed through report loading and aggregation, and agent --last windows use the configured week boundary. The guides describe defaults for both weekly commands.

Changes: Weekly Start Configuration

Layer / File(s) Summary
Weekly CLI option and argument
rust/crates/ccusage-cli-parser/src/cli-commands.json, rust/crates/ccusage-cli-parser/src/cli-help.json, rust/crates/ccusage-cli-parser/src/parser.rs, rust/crates/ccusage-cli-parser/src/tests.rs, rust/crates/ccusage-cli/src/types.rs, rust/crates/ccusage/src/main.rs
The top-level weekly command accepts -w/--start-of-week. Parsing applies configured values and lets an explicit flag override them. The selected weekday is stored in AgentCommandArgs. Tests cover defaults, accepted forms, and invalid use.
Week-start propagation and grouping
rust/crates/ccusage-adapter-all/src/lib.rs, rust/crates/ccusage-adapter-all/src/loader.rs, rust/crates/ccusage-adapter-all/src/tests.rs
The adapter passes the selected weekday through loading and aggregation. Weekly rows use that weekday as the grouping boundary. Tests compare Monday and Sunday boundaries.
Last-window handling and documented defaults
rust/crates/ccusage/src/cli/last_window.rs, docs/guide/cli-options.md, docs/guide/weekly-reports.md
Agent --last windows use the report’s configured week start. The guides state that ccusage weekly defaults to Monday and ccusage claude weekly defaults to Sunday. They also describe explicit overrides.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant Parser as ccusage-cli-parser
  participant Args as AgentCommandArgs
  participant Adapter as ccusage-adapter-all::run
  participant Loader as loader::aggregate_rows
  Parser->>Args: sets start_of_week
  Args->>Adapter: supplies report arguments
  Adapter->>Loader: passes start_of_week
  Loader->>Loader: groups weekly rows by the selected weekday
Loading
Merge Risk: ⚪ Minimal · up to eccd7

No actionable issue remains in the selected changes; merge after normal checks.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 61.82% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 55 functions across 8 files. (2 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed 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 clearly and concisely identifies the main change: restoring --start-of-week support for the top-level weekly command.
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.
Full details: Docstring Coverage

Explanation

Docstring coverage is 61.82% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 55 functions across 8 files. (2 skipped: 2 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@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.

All reported issues were addressed across 12 files

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

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread docs/guide/cli-options.md Resolved
@pkg-pr-new

pkg-pr-new Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

ccusage

npx https://pkg.pr.new/ccusage@1945

@ccusage/ccusage-darwin-arm64

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

@ccusage/ccusage-darwin-x64

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

@ccusage/ccusage-linux-arm64

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

@ccusage/ccusage-linux-x64

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

@ccusage/ccusage-win32-x64

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

commit: eccd732

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: 4fda61287158
Base SHA: aa7c675717a1

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

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, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 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 437.0ms 2.30 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 405.6ms 2.48 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 175.9ms 5.72 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 147.2ms 6.84 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 53.9ms 44.0ms 1.23x 55.50 MiB 55.75 MiB 1.00x 0.03 MiB/s 0.04 MiB/s
claude session --offline --json 0.00 MiB 46.6ms 54.4ms 0.86x 55.50 MiB 55.25 MiB 1.00x 0.03 MiB/s 0.03 MiB/s
codex daily --offline --json 0.00 MiB 50.1ms 53.7ms 0.93x 55.50 MiB 55.25 MiB 1.00x 0.02 MiB/s 0.02 MiB/s
codex session --offline --json 0.00 MiB 50.0ms 52.4ms 0.96x 55.50 MiB 55.50 MiB 1.00x 0.02 MiB/s 0.02 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, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 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 456.5ms 460.5ms 0.99x 937.10 MiB 919.08 MiB 0.98x 2.21 GiB/s 2.19 GiB/s
codex --offline --json 1.01 GiB 180.8ms 245.8ms 0.74x 513.44 MiB 513.43 MiB 1.00x 5.57 GiB/s 4.10 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 23.83 KiB 23.83 KiB +0.00 KiB 1.00x
installed native package binary 4831.09 KiB 4835.84 KiB +4.75 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: 4fda61287158
Base SHA: aa7c675717a1

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

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, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 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 822.0ms 1.22 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 713.8ms 1.41 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 413.5ms 2.43 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 313.0ms 3.22 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 native ccusage binary 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 92.2ms 37.7ms 2.44x 55.25 MiB 22.96 MiB 0.42x 0.02 MiB/s 0.04 MiB/s
claude session --offline --json 0.00 MiB 73.5ms 31.8ms 2.32x 55.50 MiB 22.96 MiB 0.41x 0.02 MiB/s 0.05 MiB/s
codex daily --offline --json 0.00 MiB 87.1ms 35.2ms 2.47x 55.00 MiB 26.96 MiB 0.49x 0.01 MiB/s 0.02 MiB/s
codex session --offline --json 0.00 MiB 79.8ms 32.3ms 2.47x 55.75 MiB 26.96 MiB 0.48x 0.01 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, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published native ccusage binary 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 861.0ms 741.1ms 1.16x 895.09 MiB 891.07 MiB 1.00x 1.17 GiB/s 1.36 GiB/s
codex --offline --json 1.01 GiB 378.5ms 367.4ms 1.03x 463.42 MiB 479.43 MiB 1.03x 2.66 GiB/s 2.74 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 23.83 KiB 23.83 KiB +0.00 KiB 1.00x
installed native package binary 4831.09 KiB 4835.84 KiB +4.75 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.

@pullfrog pullfrog 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.

ℹ️ Minor suggestions only — the flag restoration itself looks correct.

Reviewed changes

  • Parser accepts -w on unified weekly: parse_all_command now handles -w/--start-of-week (including = form) for kind == Weekly, applies commands.weekly.startOfWeek config with CLI-overrides-config precedence, and defaults to Monday.
  • Weekly bucketing and --last follow the flag: the chosen day threads through load_rows/load_sections/aggregate_rows and the unified --last window resolution.
  • Help and docs updated: new all_weekly_options help set lists the flag on ccusage weekly --help, and the guides now state Monday is the unified default with Sunday remaining the claude weekly default.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using muse-spark-1.3-contributor (free via Pullfrog for OSS) | 𝕏

Comment thread docs/guide/weekly-reports.md Resolved
Comment on lines +428 to +429
if kind == AgentReportKind::Weekly
&& matches!(parser.peek_name(), Some("-w" | "--start-of-week"))

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.

Config and -w are gated on the invoked kind being weekly, so ccusage daily --sections daily,weekly ignores commands.weekly.startOfWeek and rejects -w even though the section loader already supports a custom start. Consider applying the config unconditionally and accepting the flag when the kind or the requested sections include weekly.

Technical details
# Weekly sections via non-weekly kinds ignore start-of-week

## Affected sites
- rust/crates/ccusage-cli-parser/src/parser.rs:416 — config only applied when `kind == Weekly`
- rust/crates/ccusage-cli-parser/src/parser.rs:429 — `-w` rejected unless `kind == Weekly`
- rust/crates/ccusage-adapter-all/src/loader.rs:913 — `aggregate_rows` already honors the passed day for every section

## Required outcome
- A weekly section requested via `--sections` from a non-weekly unified kind either honors `commands.weekly.startOfWeek`/`-w` or documents that it intentionally stays Monday.

Assert that load_rows and load_sections bucket weekly rows by the
requested start day, document that commands.weekly.startOfWeek sets the
default with the flag taking precedence, and fix the weekly-reports
example that paired a claude weekly comment with a ccusage weekly command.

Co-authored-by: jgorres <[email protected]>
@cloudflare-workers-and-pages

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 eccd732 Commit Preview URL

Branch Preview URL
Oct 21 2026, 06:40 PM

@pullfrog pullfrog 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.

✅ No new issues found.

Reviewed changes

  • Added loader-level start-of-week coverage: unified_weekly_rows_and_sections_honor_start_of_week exercises load_rows and load_sections with Sunday and Monday on a fixed-timestamp fixture.
  • Fixed docs example pairing: the --start-of-week sunday example now describes the unified report while ccusage claude weekly gets its own bare command for the Sunday default.
  • Extended --last wording: the CLI options guide states config-plus-flag precedence for both unified and claude weekly reports.

Prior feedback: the contradictory docs comment thread is resolved by this delta. The open parser-gating thread on ccusage daily --sections ...,weekly ignoring -w/config was intentionally left as documented Monday behavior, so it is not re-raised here.

Pullfrog  | Fix it ➔ | View workflow run | Using muse-spark-1.3-contributor (free via Pullfrog for OSS) | 𝕏

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: eccd732f3ab2
Base SHA: aa7c675717a1

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

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, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 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 401.9ms 2.50 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 408.1ms 2.47 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 156.3ms 6.44 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 128.7ms 7.82 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 49.8ms 47.2ms 1.06x 55.50 MiB 55.50 MiB 1.00x 0.03 MiB/s 0.03 MiB/s
claude session --offline --json 0.00 MiB 38.6ms 38.5ms 1.00x 55.50 MiB 55.50 MiB 1.00x 0.04 MiB/s 0.04 MiB/s
codex daily --offline --json 0.00 MiB 46.5ms 39.8ms 1.17x 55.75 MiB 55.50 MiB 1.00x 0.02 MiB/s 0.02 MiB/s
codex session --offline --json 0.00 MiB 38.6ms 40.1ms 0.96x 55.75 MiB 55.25 MiB 0.99x 0.02 MiB/s 0.02 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, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 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 418.3ms 429.4ms 0.97x 931.10 MiB 941.09 MiB 1.01x 2.41 GiB/s 2.34 GiB/s
codex --offline --json 1.01 GiB 190.8ms 174.1ms 1.10x 525.44 MiB 495.43 MiB 0.94x 5.28 GiB/s 5.78 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 23.83 KiB 23.83 KiB -0.00 KiB 1.00x
installed native package binary 4831.09 KiB 4835.84 KiB +4.75 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: eccd732f3ab2
Base SHA: aa7c675717a1

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

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, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 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 789.8ms 1.27 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 577.8ms 1.74 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 330.0ms 3.05 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 324.8ms 3.10 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 native ccusage binary 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 112.5ms 45.6ms 2.46x 55.25 MiB 22.96 MiB 0.42x 0.01 MiB/s 0.03 MiB/s
claude session --offline --json 0.00 MiB 109.1ms 32.9ms 3.32x 55.25 MiB 22.96 MiB 0.42x 0.01 MiB/s 0.05 MiB/s
codex daily --offline --json 0.00 MiB 117.8ms 37.0ms 3.18x 56.00 MiB 26.96 MiB 0.48x 0.01 MiB/s 0.02 MiB/s
codex session --offline --json 0.00 MiB 111.4ms 33.1ms 3.37x 55.50 MiB 26.96 MiB 0.49x 0.01 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, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published native ccusage binary 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 866.4ms 751.3ms 1.15x 941.10 MiB 889.08 MiB 0.94x 1.16 GiB/s 1.34 GiB/s
codex --offline --json 1.01 GiB 387.0ms 294.1ms 1.32x 473.42 MiB 481.42 MiB 1.02x 2.60 GiB/s 3.42 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 23.83 KiB 23.83 KiB -0.00 KiB 1.00x
installed native package binary 4831.09 KiB 4835.84 KiB +4.75 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 39fefa2 into main Oct 21, 2026
49 checks passed
@ryoppippi
ryoppippi deleted the cursor/weekly-start-of-week-65e7 branch October 21, 2026 18:49
Buster210 added a commit to Buster210/ccusage that referenced this pull request Nov 6, 2026
Upstream tip: 30b653f (2026-11-06,
chore(pricing): update models.dev snapshot)
Previous fork base: c76874e (the upstream commit this fork was synced to)

Synced 128 upstream commits on top of c76874e: 70 automated pricing
snapshot refreshes and the following meaningful ones:

  b24e7a7 docs: remove LINE MAN sponsor logo (ccusage#1910)
  a93d2fe chore: release v20.0.38 (ccusage#1938)
  d91f296 docs: add ccx to community projects (ccusage#1943)
  aa7c675 chore: release v20.0.39 (ccusage#1944)
  39fefa2 fix(cli): accept --start-of-week on top-level weekly (ccusage#1945)
  600b3c9 chore: release v20.0.40 (ccusage#1946)
  baeb991 fix(antigravity): map model ID 1402 to claude-opus-5-5 (ccusage#1948)
  06347d3 chore: release v20.0.41 (ccusage#1949)
  5649632 test(hermes): derive DeepSeek provider pricing from embedded snapshot (ccusage#1951)
  d0847af chore(deps): update node.js to >=24.22.1 (ccusage#1950)
  91dfe85 chore(deps): update pullfrog/pullfrog action to v0.1.100 (ccusage#1953)
  f335280 chore: release v20.0.42 (ccusage#1952)
  b86527d chore(deps): update rust crate rustls-webpki to 0.103.16 (ccusage#1954)
  5c85ca2 chore(deps): update pullfrog/pullfrog action to v0.1.101 (ccusage#1958)
  f268798 fix(cli): apply source-specific config in unified reports (ccusage#1959)
  37a51da chore: release v20.0.43 (ccusage#1955)
  e302366 chore(deps): update github/codeql-action action to v4.39.1 (ccusage#1960)
  7af0db6 chore(deps): update pnpm to v12.15.0 (ccusage#1961)
  730c336 chore(deps): update rust crate ureq to 3.5.0 (ccusage#1964)
  bd1a21a fix(release): publish platform packages before the wrapper (ccusage#1965)
  ca33842 chore: release v20.0.44 (ccusage#1962)
  b2c8f8b chore: remove unused npm registry gate test (ccusage#1966)
  19e71d0 chore(deps): update songmu/tagpr action to v1.21.4 (ccusage#1969)
  2a84385 fix(codex): count repeated first-response snapshots once (ccusage#1971)
  60227f2 chore(deps): update rust crate smallvec to 1.16.4 (ccusage#1973)
  3e31edd chore(deps): update hustcer/setup-nu action to v3.29 (ccusage#1974)
  d93c260 feat(pricing): add gpt-6.1-terra fast/flex multipliers (ccusage#1975)
  154e13b chore: release v20.0.45 (ccusage#1967)
  f1b50e6 chore(deps): update pullfrog/pullfrog action to v0.1.102 (ccusage#1980)
  4f1f470 perf: speed up CI and local builds (ccusage#1984)
  0bd3d19 refactor(rust): move binary-only report helpers out of ccusage-core (ccusage#1985)
  65c5837 fix(antigravity): skip unreadable conversation databases (ccusage#1992)
  6372cac chore(deps): update dependency vitepress to v2.0.0-alpha.21 (ccusage#1994)
  9a42066 chore(deps): update node.js to >=24.22.2 (ccusage#1995)
  87fa788 chore(deps): update pnpm to v12.16.0 (ccusage#1996)
  8cb2532 fix(codex): price recorded Ultrafast requests at Ultrafast rates (ccusage#1989)
  128d6a0 chore(deps): update pnpm to v12.16.1 (ccusage#1997)
  5aa9d3f chore: release v20.0.46 (ccusage#1982)
  4712880 chore(deps): update rust crate unicode-width to 0.2.3 (ccusage#1998)
  3d59863 chore(deps): update node.js to v26 (ccusage#1999)
  96e98c6 chore(deps): update dependency @types/node to v26.6.6 (ccusage#2002)
  60fac54 chore(deps): update pullfrog/pullfrog action to v0.1.103 (ccusage#2003)
  de83d19 fix(config): let space-form command sections override generic report sections (ccusage#2006)
  72b8ad4 fix(all): count OpenCode Claude Agent turns once in unified reports (ccusage#2007)
  7db7a30 test(pricing): stop the alias-precedence test depending on the LiteLLM snapshot (ccusage#2009)
  e7a7ee4 fix(all): keep sessions last active on the --until day (ccusage#2008)
  4a3da73 chore: release v20.0.47 (ccusage#2001)
  8e56c11 chore(deps): update pullfrog/pullfrog action to v0.1.104 (ccusage#2010)
  e2eddf7 chore(deps): update pullfrog/pullfrog action to v0.1.107 (ccusage#2012)
  e3d2dcb chore(deps): update pullfrog/pullfrog action to v0.1.108 (ccusage#2014)
  8995f3b chore: release v20.0.48 (ccusage#2011)
  3977fd0 chore(deps): update pullfrog/pullfrog action to v0.1.110 (ccusage#2017)
  546ae51 fix(nix): make `nix flake show` work again on nixpkgs 26.11 (ccusage#2019)
  1b5e8cc chore(deps): update kesin11/actions-timeline action to v3.2.1 (ccusage#1983)
  23c5d62 chore(deps): update rust crate jiff to 0.2.39 (ccusage#2024)
  7b7cec0 chore(deps): update rust crate ureq to 3.5.1 (ccusage#2025)
  a1e4a03 chore(deps): update pullfrog/pullfrog action to v0.1.111 (ccusage#2028)
  e84d142 chore(deps): update pnpm to v12.17.0 (ccusage#2029)

Fork wins kept: the SQLite on-disk cache with its per-namespace ledger,
--live-only and clear-cache, the pi adapter with replay suppression and
per-path namespaces, the OpenCode V2 loader (now wrapped as LinkedEntry),
the FxHash/Cow hot paths, parallel per-file loads with their single_thread
seam, the table renderer, the fork CI and tag-only release workflow, and the
pricing freshness, refresh and offline precompute paths.

Hand-resolved conflicts:

  rust/adapters/claude/src/lib.rs: upstream's DedupedEntries/pruned dedupe
    lands beside the fork's collapse_replays and requestless replay rules;
    load_daily_summaries routes through load_daily_summaries_with_detection.
  rust/adapters/opencode/{parser,loader}.rs: upstream's V2 session_message
    parsing is wrapped as the fork's LinkedEntry, and the native Claude
    session link is read from the payload so it survives a cache hit.
  rust/adapters/antigravity/src/loader.rs: upstream's rewrite is taken,
    keeping the fork's per-database outcome reporting and file order.
  rust/crates/ccusage-core/src/pricing.rs: the fork's OnceLock embedded
    loader sits beside upstream's models.dev fallback and alias resolution.
  rust/crates/ccusage/src/main.rs: upstream dispatch plus the fork's
    ClearCache command.
  rust/crates/ccusage-core/src/cache.rs: the ledger is now generic over a
    LedgerPayload trait, so it covers plain entries and OpenCode's
    entry-plus-link pairs alike.
  rust/Cargo.toml: the fork's exact `=` pins stay; jiff 0.2.39,
    smallvec 1.16.4, ureq 3.5.1, unicode-width 0.2.3, rustls-webpki
    0.103.16.
  .github/workflows/{ci,release}.yaml: the fork's design is kept.
  packages/ccusage-*/package.json (6 files) and
  rust/adapters/claude/src/daily.rs: stay deleted.
  rust/crates/ccusage-core/src/{home,last_window}.rs: upstream's crate
    split moved them to ccusage-cli and ccusage-report, with their snapshots.
  apps/ccusage/config-schema.json: regenerated from the merged Rust source
    (32 numeric minimums `0.0` -> `0`, new pi description), plus three
    snapshots regenerated in the fork layout for the codex and qwen tests.

Fixes made while landing this sync, folded in so the merge stands green:

  fix(rust): decode cache blobs written before `data_session_id`. postcard
    encodes struct fields positionally, so a field added mid-struct made
    every blob the released 20.0.36 binary wrote undecodable. A failed
    decode is not merely slow: it drops the ledger rows of deleted source
    files, which no later run can rebuild. In an isolated fixture the
    released binary still reported 101,570,002 pi tokens after the source
    files were deleted; a warm build without the decoders reported 0.
    LegacyCachedEntry and LegacyLedgerEntry decode the old layout and
    reconstruct `data_session_id` as None; decode_exact requires the whole
    buffer, so a newer blob can no longer "decode" into an older struct as
    garbage. Four regression tests cover both layouts and the tail rule.
  fix(rust): warn once per table when a cached blob decodes as no known
    layout. The files table is rebuildable; the ledger table is not, so the
    warning says to save a copy before clear-cache.
  test(opencode): isolate the Claude-agent pairing test from the developer's
    real cache; it had been writing 'agent'/'plain' ledger rows into the
    opencode-db namespace.

Version: take upstream's 20.0.48 in package.json, apps/ccusage/package.json
and docs/package.json; the Rust workspace keeps version 0.0.0.

DO NOT push a v20.0.48 tag from this fork: release.yaml would publish fork
bytes under upstream identity.
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.

2 participants