fix(config): don't require .claude directory for non-Claude agents#1017
Conversation
ccusage now supports codex, opencode, amp, and pi-agent in addition to Claude Code. Running it on a machine without a Claude data directory crashed with "No valid Claude data directories found" because getConfigSearchPaths() called the throwing getClaudePaths() while discovering ccusage.json locations. Treat Claude config dirs as best-effort: swallow the error and fall back to the local .ccusage directory so users of other agents (or no agent yet) can run ccusage without setting CLAUDE_CONFIG_DIR. Fixes #1014
|
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)
📝 WalkthroughWalkthroughClaude path discovery now returns only valid directories and no longer throws; requireClaudePaths() enforces presence and gives helpful setup errors. Data loaders now use requireClaudePaths(). Config search treats Claude resolution as best-effort and a Vitest test verifies loadConfig() does not throw when CLAUDE_CONFIG_DIR points to an empty fixture. ChangesClaude discovery and resilient config
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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
apps/ccusage/src/adapter/claude/data-loader.ts[baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: 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 apps/ccusage/src/config-loader-tokens.ts[baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: 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 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 |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
ccusage-guide | 238798c | Commit Preview URL Branch Preview URL |
May 17 2026, 09:41 AM |
commit: |
ccusage performance comparisonThis compares the PR build against the base branch build on the same CI runner. 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
Package size
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. |
Previously getClaudePaths() threw when no Claude data directory was found, which forced callers that don't actually need a Claude dir (like config discovery in getConfigSearchPaths) to wrap the call in try/catch or Result.try. That asymmetry is what made #1014 easy to hit in the first place. Make getClaudePaths() the unsurprising "give me what you find, possibly nothing" variant, and add requireClaudePaths() for explicit Claude-only entry points (claude:* command loaders, statusline session lookup) that want to surface the helpful setup hint when no data exists. debug.ts already had its own length check so it keeps using getClaudePaths(). The config layer now just calls getClaudePaths() directly — no wrapping needed — restoring the consistency with the other agents' detect functions and getClaudeProjectPaths(). No behavior change for users: - `ccusage` on a machine without .claude still runs and reports "None" - `ccusage claude daily` without .claude still surfaces the original "No valid Claude data directories found" error
Summary
Fixes #1014.
Running
bunx ccusageon a machine without a Claude data directory crashed with:ccusage now supports
codex,opencode,amp, andpi-agentin addition to Claude Code, so requiring a.claudedirectory just to load config (ccusage.json) is wrong — it blocks every command, includingccusage codex, on systems that never installed Claude Code.The crash originated in
getConfigSearchPaths()(apps/ccusage/src/config-loader-tokens.ts), which called the throwinggetClaudePaths()while building the list of locations to search forccusage.json.Fix
Treat the Claude-derived config dirs as best-effort: if
getClaudePaths()throws, swallow the error viaResult.try+Result.unwrap([])and fall back to the local.ccusagedirectory incwd. All commands (ccusage,ccusage codex,ccusage opencode,ccusage amp,ccusage pi, and the explicitccusage claude …ones) now load config without a Claude directory present. The Claude-specific loaders/debugcommand continue to surface the original error when actually loading Claude data, which is the right behavior.Verification
bun run src/index.tswithCLAUDE_CONFIG_DIR=/tmp/does-not-existnow printsDetected: NoneandNo usage data found.instead of throwing.config-loader-tokens.tsthat pointsCLAUDE_CONFIG_DIRat a directory missingprojects/and assertsloadConfig()returnsundefinedrather than throwing.pnpm typecheck,pnpm run format, andpnpm --filter ccusage test --runall pass (385 tests / 2 skipped).Test plan
pnpm typecheckpnpm run formatpnpm --filter ccusage test --runCLAUDE_CONFIG_DIR=/tmp/does-not-exist bun run src/index.tshttps://claude.ai/code/session_01H93Pfks8XvhJ5PAABFpLqh
Generated by Claude Code
Summary by cubic
Stop requiring a Claude data directory to load config so
ccusage(includingcodex,opencode,amp, andpi-agent) runs on machines without.claude. Split Claude path discovery into safe and required variants so Claude-only commands still show a clear setup error; fixes #1014.getClaudePaths()return possibly empty; addrequireClaudePaths()for Claude-only entry points.requireClaudePaths()in Claude data loaders; config discovery now callsgetClaudePaths()and searches local./.ccusage/ccusage.jsonfirst.loadConfig()returnsundefinedwhenCLAUDE_CONFIG_DIRpoints to a dir withoutprojects/.Written for commit 238798c. Summary will update on new commits. Review in cubic
Summary by CodeRabbit
Bug Fixes
Documentation
Tests