Skip to content

fix(ccusage): stabilize loading progress#1002

Merged
ryoppippi merged 2 commits into
mainfrom
codex/fix-ccusage-loading-progress
May 16, 2026
Merged

fix(ccusage): stabilize loading progress#1002
ryoppippi merged 2 commits into
mainfrom
codex/fix-ccusage-loading-progress

Conversation

@ryoppippi
Copy link
Copy Markdown
Owner

@ryoppippi ryoppippi commented May 16, 2026

Summary

  • Replace per-agent loading spinners in the all-agent report with one shared progress spinner.
  • Suppress ccusage logger output while the TTY loading spinner is active so pricing fetch logs do not corrupt the loading display.
  • Keep JSON and non-TTY output behavior unchanged.

Validation

  • `pnpm run format`
  • `pnpm typecheck`
  • `pnpm run test`
  • `pnpm --filter ccusage build`
  • cmux verification on `workspace:3` / `surface:31`: ran `node apps/ccusage/dist/index.js`; loading rendered as a single progress line and completed into the report without persisted loading/pricing-log artifacts.

Summary by cubic

Stabilizes the ccusage all-agent loading display by replacing per-agent spinners with a single progress line and silencing logs while it runs. Prevents duplicated or corrupted lines in TTY (e.g., cmux); JSON and non‑TTY behavior is unchanged.

  • Bug Fixes
    • Use one shared spinner that shows overall progress (X/Y) and currently loading agents.
    • Temporarily mute the ccusage logger while the spinner is active; always restore the original level after the run, including when JSON mode silences output.

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

Summary by CodeRabbit

  • Improvements

    • Simplified progress display to a single consolidated spinner showing aggregate load progress.
  • Bug Fixes

    • Improved error handling during agent loading with proper exit code setting and ensured logger level is restored after operations.
    • Progress stops correctly on failure.
  • Tests

    • Added unit tests covering aggregated progress text and completion behavior.

Review Change Stack

Replace the per-agent picospinner instances used by the all-agent reports with one shared progress spinner. Multiple spinner components and pricing log output were competing for the same TTY while apps/ccusage/dist/index.js loaded usage logs, which left duplicated loading lines in cmux.

Suppress ccusage logger output only while the TTY progress spinner is active so pricing fetch messages do not corrupt the loading display. JSON and non-TTY output paths are unchanged.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 16, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 83398236-ab64-4f62-89fd-4c5c6a4a5e88

📥 Commits

Reviewing files that changed from the base of the PR and between 0e3ee4b and 302ccbb.

📒 Files selected for processing (1)
  • apps/ccusage/src/commands/all.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/ccusage/src/commands/all.ts

📝 Walkthrough

Walkthrough

Consolidates per-agent spinners into a single Spinner whose text is computed from a shared per-agent state map; runAllReport now preserves/restores logger.level, stops progress and sets exit code on failures; tests added for the progress-text formatter.

Changes

Progress and Error Handling

Layer / File(s) Summary
Progress state type and spinner implementation
apps/ccusage/src/commands/all.ts
AllLoadProgressState string-union introduced. formatAllLoadProgressText(states) formats aggregated single-line spinner text. createAllLoadProgress refactored to use a shared Map<AgentId, AllLoadProgressState> and one Spinner updated from that map.
Error handling and logger restoration
apps/ccusage/src/commands/all.ts
runAllReport captures the original logger.level, sets logger.level = 0 when progress is enabled, stops the progress spinner and logs the error on failure, sets process.exitCode = 1 and returns early, and always restores logger.level in a finally block.
Progress formatter unit tests
apps/ccusage/src/commands/all.ts
Unit tests exercise formatAllLoadProgressText for single active load rendering and for omitting loading-agent labels once all loads complete.

🎯 2 (Simple) | ⏱️ ~12 minutes

"I twirl one spinner, tidy and bright,
agents counted in a single light,
if loads stumble, I halt and stay,
then bring back the logger to lead the way.
— 🐇✨"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 'fix(ccusage): stabilize loading progress' accurately describes the main change: replacing per-agent spinners with a single shared progress spinner to stabilize the loading display.
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 codex/fix-ccusage-loading-progress

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

apps/ccusage/src/commands/all.ts

[baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: npm i baseline-browser-mapping@latest -D
tsconfig.json is not found. we cannot use type-aware rules.

Oops! Something went wrong! :(

ESLint: 9.35.0

Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'eslint-plugin-format' imported from /node_modules/.pnpm/@antfu+eslint-config@4.19.0_@vue+compiler-sfc@3.5.30_eslint@9.35.0_typescript@5.9.2_vit_670a2c5c75d4275eabd7bc195a173ee6/node_modules/@antfu/eslint-config/dist/index.js
at Object.getPackageJSONURL (node:internal/modules/package_json_reader:301:9)
at packageResolve (node:internal/modules/esm/resolve:764:81)
at moduleResolve (node:internal/modules/esm/resolve:855:18)
at defaultResolve (node:internal/modules/esm/resolve:988:11)
at #cachedDefaultResolve (node:internal/modules/esm/loader:697:20)
at #resolveAndMaybeBlockOnLoaderThread (node:internal/modules/esm/loader:714:38)
at ModuleLoader.resolveSync (node:internal/modules/esm/loader:746:52)
at #resolve (node:internal/modules/esm/loader:679:17)
at ModuleLoader.getOrCreateModuleJob (node:internal/modules/esm/loader:599:35)
at node:internal/modules/esm/loader:628:32

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 16, 2026

Open in StackBlitz

@ccusage/amp

npx https://pkg.pr.new/ryoppippi/ccusage/@ccusage/amp@1002

ccusage

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

@ccusage/codex

npx https://pkg.pr.new/ryoppippi/ccusage/@ccusage/codex@1002

@ccusage/opencode

npx https://pkg.pr.new/ryoppippi/ccusage/@ccusage/opencode@1002

@ccusage/pi

npx https://pkg.pr.new/ryoppippi/ccusage/@ccusage/pi@1002

commit: 302ccbb

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 16, 2026

ccusage performance comparison

This compares the PR build against the base branch build on the same CI runner.

Committed fixture performance

Committed small fixture for stable PR-to-PR feedback and output-shape regressions.

Fixture: apps/ccusage/test/fixtures/claude
Runtime: package ccusage bin from apps/ccusage/package.json through bun -b, --offline --json, measured by hyperfine with 2 warmups and 7 runs.

Command Base median PR median PR vs base
daily --offline --json 130.2ms 130.9ms 0.99x
session --offline --json 131.5ms 131.7ms 1.00x
blocks --offline --json 130.8ms 128.5ms 1.02x

Large real-world-shaped fixture performance

Generated fixture around 1 GiB shaped from aggregate local Claude-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 fixture.

Fixture: /home/runner/work/_temp/ccusage-large-fixture
Runtime: package ccusage bin from apps/ccusage/package.json through bun -b, --offline --json, measured by hyperfine with 0 warmups and 1 runs.

Command Base median PR median PR vs base
daily --offline --json 1.414s 1.432s 0.99x

Package size

Package artifact Base PR Delta Ratio
packed ccusage-*.tgz 64.02 KiB 64.10 KiB +0.08 KiB 1.00x

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

@ryoppippi ryoppippi marked this pull request as ready for review May 16, 2026 11:02
@ryoppippi
Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 16, 2026

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/ccusage/src/commands/all.ts (1)

839-841: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Capture the original logger level before JSON-mode mutation.

Line 856 currently snapshots logger.level after Line 840 sets it to 0 for JSON mode, so the prior level is lost and cannot be restored correctly at the end of the function.

Suggested fix
 async function runAllReport(kind: ReportKind, options: AllOptions): Promise<void> {
+	const originalLoggerLevel = logger.level;
 	if (options.json === true) {
 		logger.level = 0;
 	}
@@
 	let rows: AllRow[];
 	const progress = createAllLoadProgress(shouldShowAllLoadProgress(options));
-	const originalLoggerLevel = logger.level;
 	try {

Also applies to: 856-857, 868-870

🤖 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 `@apps/ccusage/src/commands/all.ts` around lines 839 - 841, Before you mutate
logger.level for JSON mode, capture the existing level into a local variable
(e.g., originalLogLevel) so it can be restored later; specifically, move the
snapshot of logger.level to just before the block that does if (options.json ===
true) { logger.level = 0; } and then restore logger.level = originalLogLevel at
the function end where you currently reset the level. Apply the same change for
the other affected regions (the snapshot/restore around lines 856-857 and
868-870) so you always save the prior logger.level before setting it to 0 and
restore that saved value afterwards.
🤖 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.

Outside diff comments:
In `@apps/ccusage/src/commands/all.ts`:
- Around line 839-841: Before you mutate logger.level for JSON mode, capture the
existing level into a local variable (e.g., originalLogLevel) so it can be
restored later; specifically, move the snapshot of logger.level to just before
the block that does if (options.json === true) { logger.level = 0; } and then
restore logger.level = originalLogLevel at the function end where you currently
reset the level. Apply the same change for the other affected regions (the
snapshot/restore around lines 856-857 and 868-870) so you always save the prior
logger.level before setting it to 0 and restore that saved value afterwards.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 92cf047d-7f95-448d-87ea-a48f5ba79a1c

📥 Commits

Reviewing files that changed from the base of the PR and between f89c419 and 0e3ee4b.

📒 Files selected for processing (1)
  • apps/ccusage/src/commands/all.ts

Copy link
Copy Markdown

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

Choose a reason for hiding this comment

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

No issues found across 1 file

Re-trigger cubic

Capture the original logger level before JSON mode silences output, so the all-agent report restores the caller-visible logger state after loading.
@cloudflare-workers-and-pages
Copy link
Copy Markdown

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

Deploying with  Cloudflare Workers  Cloudflare Workers

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

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
ccusage-guide 302ccbb May 16 2026, 11:09 AM

@ryoppippi
Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 16, 2026

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

@ryoppippi
Copy link
Copy Markdown
Owner Author

Addressed CodeRabbit’s logger-level feedback in 302ccbb by capturing the original logger level before JSON-mode mutation. Latest CodeRabbit run reports no actionable comments, and Cubic found no issues.

@ryoppippi ryoppippi merged commit dac1de8 into main May 16, 2026
24 checks passed
@ryoppippi ryoppippi deleted the codex/fix-ccusage-loading-progress branch May 16, 2026 11:13
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