-
-
Notifications
You must be signed in to change notification settings - Fork 317
feat: Support multiple Claude data directories to handle v1.0.30+ path change #122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Warning Rate limit exceeded@ryoppippi has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 18 minutes and 21 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📥 CommitsReviewing files that changed from the base of the PR and between 1e62e473455a17408fa31027f47d5ea57c01a4b6 and b58b655. ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (10)
WalkthroughThis update introduces support for multiple Claude Code data directories by adding logic to aggregate usage data from both the old and new default paths, as well as custom directories specified via the Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant CLI Tool
participant DataLoader
participant FileSystem
User->>CLI Tool: Run usage command
CLI Tool->>DataLoader: Request usage data
DataLoader->>FileSystem: Read CLAUDE_CONFIG_DIR env var
alt CLAUDE_CONFIG_DIR set
DataLoader->>FileSystem: Parse comma-separated paths
else
DataLoader->>FileSystem: Use default paths (~/.config/claude, ~/.claude)
end
DataLoader->>FileSystem: Validate and aggregate project directories
DataLoader->>FileSystem: Load and merge usage data from all valid directories
DataLoader-->>CLI Tool: Return aggregated usage data
CLI Tool-->>User: Display results
Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Possibly related PRs
Poem
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
commit: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summary of Changes
Hello @ryoppippi, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request significantly enhances the flexibility and robustness of ccusage by enabling it to seamlessly handle usage data spread across multiple Claude Code installation directories. This change ensures backward compatibility and future-proofs the tool against potential changes in Claude Code's data storage locations, providing a more reliable experience for users with varying Claude Code versions or custom setups.
Highlights
- Multi-Directory Support: Implemented support for
ccusageto automatically detect and aggregate usage data from multiple Claude Code data directories, specifically addressing the path change from~/.claude/projects/to~/.config/claude/projects/in Claude Code v1.0.30+. - Environment Variable Configuration: Introduced support for the
CLAUDE_CONFIG_DIRenvironment variable, allowing users to specify one or more custom, comma-separated Claude data directory paths, which take precedence over default locations. - Enhanced Data Loading: Modified core data loading functions (
loadDailyUsageData,loadSessionData,loadSessionBlockData) to collect and process usage data from all identified Claude data directories, ensuring comprehensive reporting regardless of where the data resides. - New Path Resolution Logic: Added a new
getClaudePaths()function to resolve all valid Claude data directories based on environment variables, the new default path (~/.config/claude), and the legacy default path (~/.claude), while deprecating the oldgetDefaultClaudePath(). - Utility Function & Tests: Included a new
ensureArray()utility function for cleaner array handling and added comprehensive unit and integration tests to validate the multi-path functionality, environment variable parsing, and data aggregation.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request enhances ccusage by adding support for multiple Claude data directories. The changes include a new getClaudePaths function for path discovery and updates to data loading functions to aggregate data from multiple sources. The PR is well-structured and the code is clear. I suggest optimizing a potentially O(N^2) operation in loadSessionData and improving the determinism of a unit test for getClaudePaths.
src/data-loader.ts
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current method of re-associating baseDir with sorted file paths uses filesWithBase.find() inside a map() call, which can lead to O(N^2) time complexity. Consider using a Map to store baseDir associated with each file path before sorting for O(1) lookups during re-association, making it O(N).
Additionally, item?.baseDir ?? '' will result in an empty baseDir if item is unexpectedly undefined, potentially leading to incorrect session and project path extraction. A more robust approach would be to throw an error if item is not found, or ensure baseDir is never an empty string if a valid path is expected.
sortedFiles.map((file) => {
const item = filesWithBase.find(f => f.file === file);
return { file, baseDir: item?.baseDir ?? '' };
}),
src/data-loader.ts
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test case for getClaudePaths() when the environment variable is not set relies on the test environment's file system, which can make the test non-deterministic. Consider mocking isDirectorySync to control its return value for specific paths and verify getClaudePaths() behavior under controlled conditions (e.g., no default paths found, only old default path found, etc.). This ensures the test verifies the logic independently of the environment's file system state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (1)
CLAUDE.md (1)
49-60: Good documentation update with minor punctuation suggestion.The multi-directory support documentation is clear and helpful for developers. Consider adding a comma for better readability on line 60.
-This addresses the breaking change in Claude Code where logs moved from `~/.claude` to `~/.config/claude`. +This addresses the breaking change in Claude Code, where logs moved from `~/.claude` to `~/.config/claude`.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📥 Commits
Reviewing files that changed from the base of the PR and between e2f4b7b and e1d4058d3c8384796d026e83fbd54b5c95df2e95.
📒 Files selected for processing (5)
CLAUDE.md(1 hunks)README.md(1 hunks)src/consts.internal.ts(1 hunks)src/data-loader.ts(7 hunks)src/utils.internal.ts(2 hunks)
🧰 Additional context used
🪛 ESLint
src/utils.internal.ts
[error] 379-379: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 380-380: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 381-381: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 381-381: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 381-381: Unsafe member access .toEqual on an error typed value.
(ts/no-unsafe-member-access)
[error] 382-382: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 382-382: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 382-382: Unsafe member access .toEqual on an error typed value.
(ts/no-unsafe-member-access)
[error] 383-383: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 383-383: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 383-383: Unsafe member access .toEqual on an error typed value.
(ts/no-unsafe-member-access)
[error] 386-386: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 387-387: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 387-387: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 387-387: Unsafe member access .toEqual on an error typed value.
(ts/no-unsafe-member-access)
[error] 388-388: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 388-388: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 388-388: Unsafe member access .toEqual on an error typed value.
(ts/no-unsafe-member-access)
[error] 389-389: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 389-389: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 389-389: Unsafe member access .toEqual on an error typed value.
(ts/no-unsafe-member-access)
[error] 390-390: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 390-390: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 390-390: Unsafe member access .toEqual on an error typed value.
(ts/no-unsafe-member-access)
[error] 393-393: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 395-395: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 395-395: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 395-395: Unsafe member access .toEqual on an error typed value.
(ts/no-unsafe-member-access)
[error] 396-396: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 396-396: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 396-396: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
src/data-loader.ts
[error] 61-61: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 61-61: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 61-61: Unsafe member access .env on an error typed value.
(ts/no-unsafe-member-access)
[error] 61-61: Unsafe member access .trim on an error typed value.
(ts/no-unsafe-member-access)
[error] 63-63: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 63-63: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 63-63: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 63-63: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 63-63: Unsafe member access .split on an error typed value.
(ts/no-unsafe-member-access)
[error] 63-63: Unsafe member access .map on an error typed value.
(ts/no-unsafe-member-access)
[error] 63-63: Unsafe return of a value of type any.
(ts/no-unsafe-return)
[error] 63-63: Unsafe call of a(n) any typed value.
(ts/no-unsafe-call)
[error] 63-63: Unsafe member access .trim on an any value.
(ts/no-unsafe-member-access)
[error] 63-63: Unsafe member access .filter on an error typed value.
(ts/no-unsafe-member-access)
[error] 65-65: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 65-65: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 66-66: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 66-66: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 66-66: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 67-67: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 67-67: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 69-69: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 70-70: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 79-79: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 79-79: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 80-80: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 80-80: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 84-84: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 84-84: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 85-85: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 85-85: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 85-85: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 86-86: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 86-86: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 88-88: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 89-89: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 98-98: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 98-98: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 99-99: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 99-99: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 114-114: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 114-114: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 114-114: Unsafe member access .env on an error typed value.
(ts/no-unsafe-member-access)
[error] 114-114: Unsafe member access .trim on an error typed value.
(ts/no-unsafe-member-access)
[error] 117-117: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 117-117: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 117-117: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 117-117: Unsafe member access .split on an error typed value.
(ts/no-unsafe-member-access)
[error] 117-117: Unsafe member access [0] on an error typed value.
(ts/no-unsafe-member-access)
[error] 119-119: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 119-119: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 122-122: Unsafe return of a value of type error.
(ts/no-unsafe-return)
[error] 127-127: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 127-127: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 127-127: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 128-128: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 128-128: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 129-129: Unsafe return of a value of type error.
(ts/no-unsafe-return)
[error] 133-133: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 133-133: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 133-133: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 134-134: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 134-134: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 135-135: Unsafe return of a value of type error.
(ts/no-unsafe-return)
[error] 139-139: Unsafe return of a value of type error.
(ts/no-unsafe-return)
[error] 651-651: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 651-651: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 651-651: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 652-655: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 652-652: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 653-653: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 656-656: Unsafe spread of an error typed type.
(ts/no-unsafe-argument)
[error] 780-780: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 780-780: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 780-780: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 781-784: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 781-781: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 782-782: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 787-787: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 787-787: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 827-827: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 827-827: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 827-827: Unsafe member access .relative on an error typed value.
(ts/no-unsafe-member-access)
[error] 1033-1033: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1033-1033: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 1033-1033: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 1034-1037: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1034-1034: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 1035-1035: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1038-1038: Unsafe spread of an error typed type.
(ts/no-unsafe-argument)
[error] 3652-3652: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3653-3653: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3654-3654: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3654-3654: Unsafe member access .unstubAllEnvs on an error typed value.
(ts/no-unsafe-member-access)
[error] 3657-3657: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3658-3660: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3658-3658: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3661-3663: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3661-3661: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3665-3665: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3665-3665: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3665-3665: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3665-3665: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3668-3668: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3668-3668: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3668-3668: Unsafe member access .toEqual on an error typed value.
(ts/no-unsafe-member-access)
[error] 3668-3668: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3668-3668: Unsafe member access .arrayContaining on an error typed value.
(ts/no-unsafe-member-access)
[error] 3668-3668: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3668-3668: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3670-3670: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3670-3670: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3670-3670: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3670-3670: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3671-3671: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3671-3671: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3671-3671: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3671-3671: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3674-3674: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3675-3675: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3675-3675: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3680-3680: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3680-3680: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3680-3680: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3681-3681: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3681-3681: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3681-3681: Unsafe member access .toBeGreaterThan on an error typed value.
(ts/no-unsafe-member-access)
[error] 3684-3684: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3684-3684: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3684-3684: Unsafe member access .toMatch on an error typed value.
(ts/no-unsafe-member-access)
[error] 3688-3688: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3689-3691: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3689-3689: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3693-3693: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3693-3693: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3693-3693: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3696-3696: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3696-3696: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3696-3696: Unsafe member access .toEqual on an error typed value.
(ts/no-unsafe-member-access)
[error] 3696-3696: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3696-3696: Unsafe member access .arrayContaining on an error typed value.
(ts/no-unsafe-member-access)
[error] 3696-3696: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3697-3697: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3697-3697: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3697-3697: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3697-3697: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3700-3700: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3701-3703: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3701-3701: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3705-3705: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3705-3705: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3705-3705: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3705-3705: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3709-3709: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3710-3710: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3710-3710: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3710-3710: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3714-3714: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3715-3715: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3716-3728: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3716-3716: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3730-3742: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3730-3730: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3744-3744: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3744-3744: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3744-3744: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3744-3744: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3748-3748: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3748-3748: Unsafe member access .date on an error typed value.
(ts/no-unsafe-member-access)
[error] 3749-3749: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3749-3749: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3749-3749: Unsafe member access .toBeDefined on an error typed value.
(ts/no-unsafe-member-access)
[error] 3750-3750: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3750-3750: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3750-3750: Unsafe member access .inputTokens on an error typed value.
(ts/no-unsafe-member-access)
[error] 3750-3750: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3751-3751: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3751-3751: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3751-3751: Unsafe member access .outputTokens on an error typed value.
(ts/no-unsafe-member-access)
[error] 3751-3751: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3752-3752: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3752-3752: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3752-3752: Unsafe member access .totalCost on an error typed value.
(ts/no-unsafe-member-access)
[error] 3752-3752: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
🪛 LanguageTool
CLAUDE.md
[uncategorized] ~60-60: Possible missing comma found....
Context: ...addresses the breaking change in Claude Code where logs moved from ~/.claude to `
(AI_HYDRA_LEO_MISSING_COMMA)
🔇 Additional comments (11)
src/utils.internal.ts (2)
251-260: LGTM! Clean utility function with good type safety.The
ensureArrayfunction is well-implemented with proper generic typing and clear logic. The JSDoc documentation is comprehensive and the function serves its purpose perfectly for the multi-directory support feature.
379-398: Comprehensive test coverage looks good.The tests cover all the important scenarios including arrays, primitives, null/undefined values, and object reference preservation. The static analysis errors about "unsafe calls" are false positives related to the vitest testing setup and can be safely ignored.
src/consts.internal.ts (2)
45-49: LGTM! New constant properly supports v1.0.30+ Claude path.The
DEFAULT_CLAUDE_CONFIG_PATHconstant correctly defines the new default Claude data directory path, complementing the existing legacy path constant.
51-55: LGTM! Environment variable constant is well-defined.The
CLAUDE_CONFIG_DIR_ENVconstant provides a clean way to reference the environment variable name and supports the comma-separated paths feature as described in the PR objectives.README.md (1)
126-149: Excellent documentation for the multi-directory feature.The new Configuration section clearly explains how ccusage handles multiple Claude data directories, provides helpful context about the v1.0.30 breaking change, and shows practical examples of environment variable usage. This will be very helpful for users managing multiple Claude Code installations.
CLAUDE.md (1)
64-68: LGTM! Architecture documentation properly updated.The updates to the architecture overview correctly reflect the multi-directory support feature and maintain consistency with the implementation changes.
src/data-loader.ts (5)
107-140: Well-implemented backward compatibilityThe deprecated function maintains backward compatibility effectively by:
- Only using the first path when multiple are provided
- Preferring the old default path if it exists
- Clear deprecation notice pointing to the new function
645-657: Correct implementation of multi-path supportThe changes properly handle both single paths and arrays of paths using
ensureArray, and correctly aggregate files from all valid directories.
778-803: Excellent handling of multiple base directoriesThe implementation correctly tracks the base directory for each file, which is essential for proper session and project path extraction. The approach of storing
{ file, baseDir }pairs ensures accurate relative path computation.
1027-1039: Consistent multi-path implementationThe changes follow the same pattern as the other load functions, ensuring consistency across the codebase.
61-61: Fix TypeScript type safety for environment variable accessThe static analysis indicates type safety issues with
process.envaccess. Consider adding proper type annotations or using optional chaining more defensively.- const envPaths = (process.env[CLAUDE_CONFIG_DIR_ENV] ?? '').trim(); + const envPaths = (process.env[CLAUDE_CONFIG_DIR_ENV] || '').trim();Likely an incorrect or invalid review comment.
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/data-loader.ts (1)
115-145: Good backward compatibility implementation with minor documentation suggestion.The deprecated function maintains backward compatibility well. Consider enhancing the deprecation notice:
/** * Default path for Claude data directory * Uses environment variable CLAUDE_CONFIG_DIR if set, otherwise defaults to ~/.claude - * @deprecated Use getClaudePaths() instead for multiple path support + * @deprecated Use getClaudePaths() instead for multiple path support. This function only returns the first path when multiple are configured. */
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📥 Commits
Reviewing files that changed from the base of the PR and between 2feda46a1b3c6005e7b74623af1a39faba5904e7 and aec9f94cd8d5574fa9289fe796fea9f5cb4d6fd8.
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (2)
package.json(1 hunks)src/data-loader.ts(8 hunks)
✅ Files skipped from review due to trivial changes (1)
- package.json
🧰 Additional context used
🪛 ESLint
src/data-loader.ts
[error] 62-62: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 62-62: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 62-62: Unsafe member access .env on an error typed value.
(ts/no-unsafe-member-access)
[error] 62-62: Unsafe member access .trim on an error typed value.
(ts/no-unsafe-member-access)
[error] 64-64: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 64-64: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 64-64: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 64-64: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 64-64: Unsafe member access .split on an error typed value.
(ts/no-unsafe-member-access)
[error] 64-64: Unsafe member access .map on an error typed value.
(ts/no-unsafe-member-access)
[error] 64-64: Unsafe return of a value of type any.
(ts/no-unsafe-return)
[error] 64-64: Unsafe call of a(n) any typed value.
(ts/no-unsafe-call)
[error] 64-64: Unsafe member access .trim on an any value.
(ts/no-unsafe-member-access)
[error] 64-64: Unsafe member access .filter on an error typed value.
(ts/no-unsafe-member-access)
[error] 66-66: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 66-66: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 66-66: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 67-67: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 67-67: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 68-68: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 68-68: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 68-68: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 69-69: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 69-69: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 71-71: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 72-72: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 73-73: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 82-82: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 82-82: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 83-83: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 83-83: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 87-87: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 87-87: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 87-87: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 88-88: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 88-88: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 89-89: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 89-89: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 89-89: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 90-90: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 90-90: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 92-92: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 93-93: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 94-94: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 103-103: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 103-103: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 104-104: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 104-104: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 119-119: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 119-119: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 119-119: Unsafe member access .env on an error typed value.
(ts/no-unsafe-member-access)
[error] 119-119: Unsafe member access .trim on an error typed value.
(ts/no-unsafe-member-access)
[error] 122-122: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 122-122: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 122-122: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 122-122: Unsafe member access .split on an error typed value.
(ts/no-unsafe-member-access)
[error] 122-122: Unsafe member access [0] on an error typed value.
(ts/no-unsafe-member-access)
[error] 124-124: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 124-124: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 127-127: Unsafe return of a value of type error.
(ts/no-unsafe-return)
[error] 132-132: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 132-132: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 132-132: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 133-133: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 133-133: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 134-134: Unsafe return of a value of type error.
(ts/no-unsafe-return)
[error] 138-138: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 138-138: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 138-138: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 139-139: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 139-139: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 140-140: Unsafe return of a value of type error.
(ts/no-unsafe-return)
[error] 144-144: Unsafe return of a value of type error.
(ts/no-unsafe-return)
[error] 651-651: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 651-651: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 656-656: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 656-656: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 656-656: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 657-660: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 657-657: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 658-658: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 661-661: Unsafe spread of an error typed type.
(ts/no-unsafe-argument)
[error] 780-780: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 780-780: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 785-785: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 785-785: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 785-785: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 786-789: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 786-786: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 787-787: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 792-792: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 792-792: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 834-834: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 834-834: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 834-834: Unsafe member access .relative on an error typed value.
(ts/no-unsafe-member-access)
[error] 1035-1035: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1035-1035: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 1040-1040: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1040-1040: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 1040-1040: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 1041-1044: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1041-1041: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 1042-1042: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1045-1045: Unsafe spread of an error typed type.
(ts/no-unsafe-argument)
[error] 1200-1200: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 1200-1200: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 1200-1200: Unsafe member access .toMatch on an error typed value.
(ts/no-unsafe-member-access)
[error] 3659-3659: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3660-3660: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3661-3661: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3661-3661: Unsafe member access .unstubAllEnvs on an error typed value.
(ts/no-unsafe-member-access)
[error] 3664-3664: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3665-3667: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3665-3665: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3669-3669: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3669-3669: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3669-3669: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3671-3671: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3671-3671: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3671-3671: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3671-3671: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3674-3674: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3675-3675: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3675-3675: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3680-3680: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3680-3680: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3680-3680: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3681-3681: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3681-3681: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3681-3681: Unsafe member access .toBeGreaterThan on an error typed value.
(ts/no-unsafe-member-access)
[error] 3684-3684: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3685-3687: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3685-3685: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3688-3690: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3688-3688: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3692-3692: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3692-3692: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3692-3692: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3692-3692: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3694-3694: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3694-3694: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3694-3694: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3694-3694: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3694-3694: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3694-3694: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3694-3694: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3694-3694: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3698-3698: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3699-3699: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3700-3700: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3700-3700: Unsafe member access .unstubAllEnvs on an error typed value.
(ts/no-unsafe-member-access)
[error] 3703-3703: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3704-3706: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3704-3704: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3707-3709: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3707-3707: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3711-3711: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3711-3711: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3711-3711: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3711-3711: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3714-3714: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3714-3714: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3714-3714: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3714-3714: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3715-3715: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3715-3715: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3715-3715: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3715-3715: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3717-3717: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3717-3717: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3717-3717: Unsafe member access .toEqual on an error typed value.
(ts/no-unsafe-member-access)
[error] 3717-3717: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3717-3717: Unsafe member access .arrayContaining on an error typed value.
(ts/no-unsafe-member-access)
[error] 3719-3719: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3719-3719: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3719-3719: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3720-3720: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3720-3720: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3720-3720: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3723-3723: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3724-3726: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3724-3724: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3728-3728: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3728-3728: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3728-3728: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3731-3731: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3731-3731: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3731-3731: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3731-3731: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3732-3732: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3732-3732: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3732-3732: Unsafe member access .toEqual on an error typed value.
(ts/no-unsafe-member-access)
[error] 3732-3732: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3732-3732: Unsafe member access .arrayContaining on an error typed value.
(ts/no-unsafe-member-access)
[error] 3733-3733: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3733-3733: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3733-3733: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3736-3736: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3737-3739: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3737-3737: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3741-3741: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3741-3741: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3741-3741: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3741-3741: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3744-3744: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3744-3744: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3744-3744: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3744-3744: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3747-3747: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3747-3747: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3747-3747: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3751-3751: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3752-3752: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3753-3765: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3753-3753: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3767-3779: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3767-3767: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3781-3781: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3781-3781: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3781-3781: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3781-3781: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3785-3785: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3785-3785: Unsafe member access .date on an error typed value.
(ts/no-unsafe-member-access)
[error] 3786-3786: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3786-3786: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3786-3786: Unsafe member access .toBeDefined on an error typed value.
(ts/no-unsafe-member-access)
[error] 3787-3787: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3787-3787: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3787-3787: Unsafe member access .inputTokens on an error typed value.
(ts/no-unsafe-member-access)
[error] 3787-3787: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3788-3788: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3788-3788: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3788-3788: Unsafe member access .outputTokens on an error typed value.
(ts/no-unsafe-member-access)
[error] 3788-3788: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3789-3789: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3789-3789: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3789-3789: Unsafe member access .totalCost on an error typed value.
(ts/no-unsafe-member-access)
[error] 3789-3789: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
🔇 Additional comments (5)
src/data-loader.ts (5)
12-12: LGTM! Good imports for the new functionality.The
toArrayutility and updated constants properly support the multi-path functionality.Also applies to: 20-20
57-110: Excellent implementation of multi-path support.The
getClaudePaths()function is well-designed with proper:
- Environment variable parsing with comma-separated support
- Path normalization and validation
- Set-based deduplication to avoid duplicates
- Error handling when no valid paths are found
- Prioritization of environment paths over defaults
This effectively addresses the Claude Code v1.0.30+ breaking change while maintaining flexibility.
650-662: Well-implemented multi-path data aggregation.The data loading functions correctly:
- Use
toArrayto handle both single paths and arrays- Collect files from all configured Claude directories
- Maintain existing deduplication and sorting logic
- Properly track base directories for session path extraction (lines 801-810)
The Map-based approach for file-to-baseDir lookup addresses previous O(N²) performance concerns.
Also applies to: 779-810, 1034-1046
3658-3791: Comprehensive test coverage for multi-path functionality.The tests effectively cover:
- Environment variable parsing with single and multiple paths
- Path validation and filtering
- Data aggregation across multiple directories
- Deduplication logic
- Backward compatibility scenarios
This provides confidence in the robustness of the implementation.
62-110: Address ESLint false positives for standard Node.js operations.The ESLint errors about "unsafe" operations on
process.envandpathmodule usage are false positives. These are standard, type-safe Node.js operations. Consider updating your ESLint configuration to properly handle these patterns or add specific type annotations if needed.The actual implementation is correct and safe.
Could you run the following to verify these are false positives:
#!/bin/bash # Check if these are standard Node.js patterns that should be safe echo "Checking process.env usage patterns..." rg "process\.env\[" --type ts -A 2 -B 2 echo "Checking path module usage..." rg "path\.(join|resolve|relative)" --type ts -A 1 -B 1Also applies to: 119-145
aec9f94 to
1e62e47
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces support for multiple Claude data directories to handle the new installation paths and maintain backward compatibility via a new environment variable.
- Updated import paths to use TypeScript (.ts) extensions.
- Added a new getClaudePaths() function and refactored data loading to aggregate JSONL usage files from multiple directories.
- Enhanced CI and documentation to reflect changes in configuration and default directory locations.
Reviewed Changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/session-blocks.internal.ts | Updated import extension from .js to .ts for consistency. |
| src/debug.ts | Updated import paths to .ts and removed deprecated constants. |
| src/data-loader.ts | Added getClaudePaths() function and refactored default path logic for multi-directory support. |
| src/consts.internal.ts | Introduced new constants for the new default path and CLAUDE_CONFIG_DIR environment variable. |
| src/commands/mcp.ts & src/commands/blocks.ts | Updated import paths to .ts. |
| package.json | Added dependency @antfu/utils for utility functions. |
| README.md & CLAUDE.md | Updated documentation to include new configuration options and path support. |
| .github/workflows/ci.yaml | Modified CI to create both legacy and new default directories for tests. |
src/data-loader.ts
Outdated
Copilot
AI
Jun 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fallback logic in getDefaultClaudePath returns the old default path even if it isn't a valid directory, which may lead to unexpected behavior. Consider clarifying the fallback behavior by either throwing an error or explicitly documenting that returning a non-existent path is intentional.
| // If neither exists, return the old default for backward compatibility | |
| return oldDefaultPath; | |
| // If neither exists, throw an error to avoid returning a non-existent path | |
| throw new Error(`Neither the new default path (${newDefaultPath}) nor the old default path (${oldDefaultPath}) exists. Please ensure a valid Claude data directory is available.`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (2)
src/data-loader.ts (2)
801-810: Optimize file-to-base mapping performanceThe current implementation creates a Map for O(1) lookups, which is good, but there's still a potential issue with the fallback to empty string.
The performance optimization using
Mapis well-implemented, but as noted in past reviews, returning an emptybaseDirwhenitemis undefined could lead to incorrect session/project path extraction. Consider throwing an error instead:const sortedFilesWithBase = await sortFilesByTimestamp( filesWithBase.map(f => f.file), ).then(sortedFiles => sortedFiles.map(file => ({ file, - baseDir: fileToBaseMap.get(file) ?? '', + baseDir: fileToBaseMap.get(file) ?? (() => { throw new Error(`Base directory not found for file: ${file}`); })(), })), );
653-662: Extract shared file collection logic to reduce duplicationThe logic for collecting files across multiple paths is repeated in three loader functions. This creates maintenance overhead and potential inconsistencies.
As suggested in past reviews, consider extracting this into a shared helper function:
async function collectFilesFromPaths( claudePaths: string[], projectsDirName: string, globPattern: string ): Promise<string[]> { const allFiles: string[] = []; for (const claudePath of claudePaths) { const claudeDir = path.join(claudePath, projectsDirName); const files = await glob([globPattern], { cwd: claudeDir, absolute: true, }); allFiles.push(...files); } return allFiles; }Then update the loader functions:
- // Collect files from all paths - const allFiles: string[] = []; - for (const claudePath of claudePaths) { - const claudeDir = path.join(claudePath, CLAUDE_PROJECTS_DIR_NAME); - const files = await glob([USAGE_DATA_GLOB_PATTERN], { - cwd: claudeDir, - absolute: true, - }); - allFiles.push(...files); - } + const allFiles = await collectFilesFromPaths(claudePaths, CLAUDE_PROJECTS_DIR_NAME, USAGE_DATA_GLOB_PATTERN);Also applies to: 782-794, 1037-1046
🧹 Nitpick comments (3)
CLAUDE.md (2)
60-60: Add missing comma for clarityInsert a comma after "Claude Code" to improve readability:
- This addresses the breaking change in Claude Code where logs moved... + This addresses the breaking change in Claude Code, where logs moved...
64-69: Document getClaudePaths() and resolution priorityEnhance the architecture overview to mention the new
getClaudePaths()utility and clarify the path resolution order:
- Paths from
CLAUDE_CONFIG_DIR- New default (
~/.config/claude/projects/)- Legacy (
~/.claude/projects/)This will help maintainers understand how multi‐path support is orchestrated.
src/data-loader.ts (1)
100-107: Improve error message clarity and usefulnessThe error message could be more helpful by providing specific guidance and checking actual directory states.
if (paths.length === 0) { throw new Error( - `No valid Claude data directories found. Please ensure at least one of the following exists: -- ${path.join(USER_HOME_DIR, DEFAULT_CLAUDE_CONFIG_PATH, CLAUDE_PROJECTS_DIR_NAME)} -- ${path.join(USER_HOME_DIR, DEFAULT_CLAUDE_CODE_PATH, CLAUDE_PROJECTS_DIR_NAME)} -- Or set ${CLAUDE_CONFIG_DIR_ENV} environment variable to valid directory path(s) containing a '${CLAUDE_PROJECTS_DIR_NAME}' subdirectory`.trim(), + `No valid Claude data directories found. + +Searched locations: +- ${path.join(USER_HOME_DIR, DEFAULT_CLAUDE_CONFIG_PATH, CLAUDE_PROJECTS_DIR_NAME)} ${isDirectorySync(path.join(USER_HOME_DIR, DEFAULT_CLAUDE_CONFIG_PATH)) ? '(directory exists, but no projects subdirectory)' : '(directory not found)'} +- ${path.join(USER_HOME_DIR, DEFAULT_CLAUDE_CODE_PATH, CLAUDE_PROJECTS_DIR_NAME)} ${isDirectorySync(path.join(USER_HOME_DIR, DEFAULT_CLAUDE_CODE_PATH)) ? '(directory exists, but no projects subdirectory)' : '(directory not found)'} + +To fix this: +1. Install Claude Code application, or +2. Set ${CLAUDE_CONFIG_DIR_ENV} environment variable to a directory containing a '${CLAUDE_PROJECTS_DIR_NAME}' subdirectory`.trim(), ); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📥 Commits
Reviewing files that changed from the base of the PR and between aec9f94cd8d5574fa9289fe796fea9f5cb4d6fd8 and 1e62e473455a17408fa31027f47d5ea57c01a4b6.
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (10)
.github/workflows/ci.yaml(1 hunks)CLAUDE.md(2 hunks)README.md(1 hunks)package.json(1 hunks)src/commands/blocks.ts(1 hunks)src/commands/mcp.ts(1 hunks)src/consts.internal.ts(1 hunks)src/data-loader.ts(8 hunks)src/debug.ts(1 hunks)src/session-blocks.internal.ts(1 hunks)
✅ Files skipped from review due to trivial changes (4)
- src/commands/mcp.ts
- src/debug.ts
- src/session-blocks.internal.ts
- src/commands/blocks.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- .github/workflows/ci.yaml
- package.json
- src/consts.internal.ts
- README.md
🧰 Additional context used
🪛 ESLint
src/data-loader.ts
[error] 62-62: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 62-62: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 62-62: Unsafe member access .env on an error typed value.
(ts/no-unsafe-member-access)
[error] 62-62: Unsafe member access .trim on an error typed value.
(ts/no-unsafe-member-access)
[error] 64-64: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 64-64: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 64-64: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 64-64: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 64-64: Unsafe member access .split on an error typed value.
(ts/no-unsafe-member-access)
[error] 64-64: Unsafe member access .map on an error typed value.
(ts/no-unsafe-member-access)
[error] 64-64: Unsafe return of a value of type any.
(ts/no-unsafe-return)
[error] 64-64: Unsafe call of a(n) any typed value.
(ts/no-unsafe-call)
[error] 64-64: Unsafe member access .trim on an any value.
(ts/no-unsafe-member-access)
[error] 64-64: Unsafe member access .filter on an error typed value.
(ts/no-unsafe-member-access)
[error] 66-66: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 66-66: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 66-66: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 67-67: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 67-67: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 68-68: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 68-68: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 68-68: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 69-69: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 69-69: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 71-71: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 72-72: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 73-73: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 82-82: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 82-82: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 83-83: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 83-83: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 87-87: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 87-87: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 87-87: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 88-88: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 88-88: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 89-89: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 89-89: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 89-89: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 90-90: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 90-90: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 92-92: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 93-93: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 94-94: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 103-103: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 103-103: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 104-104: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 104-104: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 119-119: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 119-119: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 119-119: Unsafe member access .env on an error typed value.
(ts/no-unsafe-member-access)
[error] 119-119: Unsafe member access .trim on an error typed value.
(ts/no-unsafe-member-access)
[error] 122-122: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 122-122: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 122-122: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 122-122: Unsafe member access .split on an error typed value.
(ts/no-unsafe-member-access)
[error] 122-122: Unsafe member access [0] on an error typed value.
(ts/no-unsafe-member-access)
[error] 124-124: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 124-124: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 127-127: Unsafe return of a value of type error.
(ts/no-unsafe-return)
[error] 132-132: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 132-132: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 132-132: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 133-133: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 133-133: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 134-134: Unsafe return of a value of type error.
(ts/no-unsafe-return)
[error] 138-138: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 138-138: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 138-138: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 139-139: Unexpected any value in conditional. An explicit comparison or type conversion is required.
(ts/strict-boolean-expressions)
[error] 139-139: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 140-140: Unsafe return of a value of type error.
(ts/no-unsafe-return)
[error] 144-144: Unsafe return of a value of type error.
(ts/no-unsafe-return)
[error] 651-651: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 651-651: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 656-656: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 656-656: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 656-656: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 657-660: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 657-657: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 658-658: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 661-661: Unsafe spread of an error typed type.
(ts/no-unsafe-argument)
[error] 780-780: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 780-780: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 785-785: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 785-785: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 785-785: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 786-789: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 786-786: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 787-787: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 792-792: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 792-792: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 834-834: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 834-834: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 834-834: Unsafe member access .relative on an error typed value.
(ts/no-unsafe-member-access)
[error] 1035-1035: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1035-1035: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 1040-1040: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1040-1040: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 1040-1040: Unsafe member access .join on an error typed value.
(ts/no-unsafe-member-access)
[error] 1041-1044: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1041-1041: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 1042-1042: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1045-1045: Unsafe spread of an error typed type.
(ts/no-unsafe-argument)
[error] 1200-1200: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 1200-1200: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 1200-1200: Unsafe member access .toMatch on an error typed value.
(ts/no-unsafe-member-access)
[error] 3659-3659: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3660-3660: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3661-3661: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3661-3661: Unsafe member access .unstubAllEnvs on an error typed value.
(ts/no-unsafe-member-access)
[error] 3664-3664: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3665-3667: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3665-3665: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3669-3669: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3669-3669: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3669-3669: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3671-3671: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3671-3671: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3671-3671: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3671-3671: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3674-3674: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3675-3675: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3675-3675: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3680-3680: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3680-3680: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3680-3680: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3681-3681: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3681-3681: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3681-3681: Unsafe member access .toBeGreaterThan on an error typed value.
(ts/no-unsafe-member-access)
[error] 3684-3684: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3685-3687: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3685-3685: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3688-3690: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3688-3688: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3692-3692: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3692-3692: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3692-3692: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3692-3692: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3694-3694: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3694-3694: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3694-3694: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3694-3694: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3694-3694: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3694-3694: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3694-3694: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3694-3694: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3698-3698: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3699-3699: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3700-3700: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3700-3700: Unsafe member access .unstubAllEnvs on an error typed value.
(ts/no-unsafe-member-access)
[error] 3701-3701: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3701-3701: Unsafe member access .unstubAllGlobals on an error typed value.
(ts/no-unsafe-member-access)
[error] 3704-3704: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3705-3707: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3705-3705: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3708-3710: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3708-3708: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3712-3712: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3712-3712: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3712-3712: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3712-3712: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3715-3715: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3715-3715: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3715-3715: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3715-3715: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3716-3716: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3716-3716: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3716-3716: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3716-3716: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3718-3718: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3718-3718: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3718-3718: Unsafe member access .toEqual on an error typed value.
(ts/no-unsafe-member-access)
[error] 3718-3718: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3718-3718: Unsafe member access .arrayContaining on an error typed value.
(ts/no-unsafe-member-access)
[error] 3720-3720: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3720-3720: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3720-3720: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3721-3721: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3721-3721: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3721-3721: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3724-3724: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3725-3727: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3725-3725: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3729-3729: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3729-3729: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3729-3729: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3732-3732: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3732-3732: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3732-3732: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3732-3732: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3733-3733: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3733-3733: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3733-3733: Unsafe member access .toEqual on an error typed value.
(ts/no-unsafe-member-access)
[error] 3733-3733: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3733-3733: Unsafe member access .arrayContaining on an error typed value.
(ts/no-unsafe-member-access)
[error] 3734-3734: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3734-3734: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3734-3734: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3737-3737: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3738-3740: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3738-3738: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3742-3742: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3742-3742: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3742-3742: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3742-3742: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3745-3745: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3745-3745: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3745-3745: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3745-3745: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3748-3748: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3748-3748: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3748-3748: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3751-3751: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3752-3752: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3752-3752: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3752-3752: Unsafe member access .fn on an error typed value.
(ts/no-unsafe-member-access)
[error] 3755-3755: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3755-3755: Unsafe member access .importActual on an error typed value.
(ts/no-unsafe-member-access)
[error] 3756-3756: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3756-3756: Unsafe member access .doMock on an error typed value.
(ts/no-unsafe-member-access)
[error] 3757-3757: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3765-3765: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3765-3765: Unsafe member access .mockImplementation on an error typed value.
(ts/no-unsafe-member-access)
[error] 3785-3785: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3785-3785: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3793-3793: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3793-3793: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3793-3793: Unsafe member access .toContain on an error typed value.
(ts/no-unsafe-member-access)
[error] 3793-3793: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3793-3793: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3794-3794: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3794-3794: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3794-3794: Unsafe member access .toContain on an error typed value.
(ts/no-unsafe-member-access)
[error] 3794-3794: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3794-3794: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3795-3795: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3795-3795: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3795-3795: Unsafe member access .not on an error typed value.
(ts/no-unsafe-member-access)
[error] 3795-3795: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3795-3795: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3798-3798: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3798-3798: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3798-3798: Unsafe member access .toHaveBeenCalledWith on an error typed value.
(ts/no-unsafe-member-access)
[error] 3798-3798: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3798-3798: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3799-3799: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3799-3799: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3799-3799: Unsafe member access .toHaveBeenCalledWith on an error typed value.
(ts/no-unsafe-member-access)
[error] 3799-3799: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3799-3799: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3800-3800: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3800-3800: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3800-3800: Unsafe member access .toHaveBeenCalledWith on an error typed value.
(ts/no-unsafe-member-access)
[error] 3800-3800: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3800-3800: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3803-3803: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3803-3803: Unsafe member access .doUnmock on an error typed value.
(ts/no-unsafe-member-access)
[error] 3807-3807: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3808-3808: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3809-3821: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3809-3809: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3823-3835: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3823-3823: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3837-3837: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3837-3837: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3837-3837: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3837-3837: Unsafe member access .path on an error typed value.
(ts/no-unsafe-member-access)
[error] 3841-3841: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3841-3841: Unsafe member access .date on an error typed value.
(ts/no-unsafe-member-access)
[error] 3842-3842: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3842-3842: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3842-3842: Unsafe member access .toBeDefined on an error typed value.
(ts/no-unsafe-member-access)
[error] 3843-3843: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3843-3843: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3843-3843: Unsafe member access .inputTokens on an error typed value.
(ts/no-unsafe-member-access)
[error] 3843-3843: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3844-3844: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3844-3844: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3844-3844: Unsafe member access .outputTokens on an error typed value.
(ts/no-unsafe-member-access)
[error] 3844-3844: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
[error] 3845-3845: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3845-3845: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3845-3845: Unsafe member access .totalCost on an error typed value.
(ts/no-unsafe-member-access)
[error] 3845-3845: Unsafe member access .toBe on an error typed value.
(ts/no-unsafe-member-access)
🪛 GitHub Check: ci
src/data-loader.ts
[failure] 3793-3793: src/data-loader.ts > getClaudePaths > handles directory existence checks deterministically with mocked isDirectorySync
AssertionError: expected [ '/home/runner/.config/claude', …(1) ] to include '/mock/path1'
❯ src/data-loader.ts:3793:18
🪛 GitHub Actions: CI
src/data-loader.ts
[error] 3793-3793: Test failure in 'getClaudePaths' - handles directory existence checks deterministically with mocked isDirectorySync: AssertionError: expected [ '/home/runner/.config/claude', …(1) ] to include '/mock/path1'
🪛 LanguageTool
CLAUDE.md
[uncategorized] ~60-60: Possible missing comma found....
Context: ...addresses the breaking change in Claude Code where logs moved from ~/.claude to `
(AI_HYDRA_LEO_MISSING_COMMA)
🔇 Additional comments (3)
src/data-loader.ts (3)
12-12: Verify import consistencyThe import of
toArrayfrom@antfu/utilsis appropriate for normalizing the claudePath parameter to always be an array. This is a clean solution for handling both single path and multi-path scenarios.Also applies to: 20-20
115-116: Deprecation notice is well-documentedThe deprecation notice clearly indicates the preferred alternative function and maintains backward compatibility while guiding users toward the new multi-path approach.
62-64: Fix TypeScript safety issues with environment variable accessThe code has multiple unsafe operations when accessing
process.env. Environment variables can beundefined, but the code treats them as strings.- const envPaths = (process.env[CLAUDE_CONFIG_DIR_ENV] ?? '').trim(); + const envPaths = (process.env[CLAUDE_CONFIG_DIR_ENV] ?? '').trim(); if (envPaths !== '') { - const envPathList = envPaths.split(',').map(p => p.trim()).filter(p => p !== ''); + const envPathList = envPaths.split(',').map((p: string) => p.trim()).filter((p: string) => p !== '');However, the real issue is the TypeScript configuration is too strict. Consider using proper type assertions:
- const envPaths = (process.env[CLAUDE_CONFIG_DIR_ENV] ?? '').trim(); + const envVar = process.env[CLAUDE_CONFIG_DIR_ENV]; + const envPaths = (envVar ?? '').trim();Likely an incorrect or invalid review comment.
CLAUDE.md
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use proper markdown heading for the new section
The new "Multiple Claude Data Directories" section should follow the file’s established heading conventions (e.g., ## Multiple Claude Data Directories) instead of using bold text.
🤖 Prompt for AI Agents
In CLAUDE.md at line 49, replace the bold text "**Multiple Claude Data
Directories:**" with a proper markdown heading using the established convention,
such as "## Multiple Claude Data Directories". This change will ensure
consistency with the rest of the file's section headings.
src/data-loader.ts
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the failing test by properly mocking the module
The test is failing because the mocking approach isn't working correctly in the test environment. The issue is that vi.doMock doesn't affect already imported modules.
- it('handles directory existence checks deterministically with mocked isDirectorySync', async () => {
- const mockIsDirectorySync = vi.fn();
-
- // Mock the path-type module
- await vi.importActual('path-type');
- vi.doMock('path-type', () => ({
- isDirectorySync: mockIsDirectorySync,
- }));
+ it('handles directory existence checks deterministically with mocked isDirectorySync', async () => {
+ const { isDirectorySync } = await import('path-type');
+ const mockIsDirectorySync = vi.fn().mockImplementation((path: string) => {
+ if (path === '/mock/path1' || path === '/mock/path1/projects') return true;
+ if (path === '/mock/path2' || path === '/mock/path2/projects') return true;
+ if (path.includes('/mock/nonexistent')) return false;
+ return false;
+ });
+
+ vi.mocked(isDirectorySync).mockImplementation(mockIsDirectorySync);Alternatively, consider using a simpler approach by mocking at the function level rather than the entire module.
Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 GitHub Check: ci
[failure] 3793-3793: src/data-loader.ts > getClaudePaths > handles directory existence checks deterministically with mocked isDirectorySync
AssertionError: expected [ '/home/runner/.config/claude', …(1) ] to include '/mock/path1'
❯ src/data-loader.ts:3793:18
🪛 ESLint
[error] 3751-3751: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3752-3752: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3752-3752: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3752-3752: Unsafe member access .fn on an error typed value.
(ts/no-unsafe-member-access)
[error] 3755-3755: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3755-3755: Unsafe member access .importActual on an error typed value.
(ts/no-unsafe-member-access)
[error] 3756-3756: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3756-3756: Unsafe member access .doMock on an error typed value.
(ts/no-unsafe-member-access)
[error] 3757-3757: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3765-3765: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3765-3765: Unsafe member access .mockImplementation on an error typed value.
(ts/no-unsafe-member-access)
[error] 3785-3785: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3785-3785: Unsafe member access .stubEnv on an error typed value.
(ts/no-unsafe-member-access)
[error] 3793-3793: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3793-3793: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3793-3793: Unsafe member access .toContain on an error typed value.
(ts/no-unsafe-member-access)
[error] 3793-3793: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3793-3793: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3794-3794: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3794-3794: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3794-3794: Unsafe member access .toContain on an error typed value.
(ts/no-unsafe-member-access)
[error] 3794-3794: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3794-3794: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3795-3795: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3795-3795: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3795-3795: Unsafe member access .not on an error typed value.
(ts/no-unsafe-member-access)
[error] 3795-3795: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3795-3795: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3798-3798: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3798-3798: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3798-3798: Unsafe member access .toHaveBeenCalledWith on an error typed value.
(ts/no-unsafe-member-access)
[error] 3798-3798: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3798-3798: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3799-3799: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3799-3799: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3799-3799: Unsafe member access .toHaveBeenCalledWith on an error typed value.
(ts/no-unsafe-member-access)
[error] 3799-3799: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3799-3799: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3800-3800: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3800-3800: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3800-3800: Unsafe member access .toHaveBeenCalledWith on an error typed value.
(ts/no-unsafe-member-access)
[error] 3800-3800: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3800-3800: Unsafe member access .resolve on an error typed value.
(ts/no-unsafe-member-access)
[error] 3803-3803: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 3803-3803: Unsafe member access .doUnmock on an error typed value.
(ts/no-unsafe-member-access)
🪛 GitHub Actions: CI
[error] 3793-3793: Test failure in 'getClaudePaths' - handles directory existence checks deterministically with mocked isDirectorySync: AssertionError: expected [ '/home/runner/.config/claude', …(1) ] to include '/mock/path1'
🤖 Prompt for AI Agents
In src/data-loader.ts around lines 3751 to 3804, the test fails because
vi.doMock does not override already imported modules. To fix this, avoid using
vi.doMock for the entire module; instead, mock only the isDirectorySync function
directly using vi.spyOn or vi.fn before importing the module. This ensures the
mock is applied correctly and the test behaves deterministically. Also, ensure
to reset or restore mocks after the test to avoid side effects.
Add CLAUDE_CONFIG_DIRECTORIES and related constants to support multiple Claude data directories.
- Add getClaudePaths() function to support multiple Claude data directories - Support environment variable (comma-separated paths) - Support both new default (~/.config/claude) and old default (~/.claude) - Implement path normalization and duplicate removal - Update data loading functions to use multiple paths - Maintain backward compatibility with getDefaultClaudePath()
- Replace custom ensureArray implementation with @antfu/utils toArray - Update import paths to use .ts extensions for local modules - Remove obsolete utils.internal.ts file - Improve code maintainability and consistency
- Create both ~/.claude/projects and ~/.config/claude/projects in CI - Ensure tests run correctly with multiple Claude paths in CI environment - Support testing both legacy and new default Claude directories
- Document multiple Claude data directories support in README - Update CLAUDE.md with import convention (.ts extensions) - Explain environment variable and path priority - Add backward compatibility information - Update examples and usage instructions
Replace complex mocked test with simpler filesystem-based test Removes problematic vi.doMock that was causing test failures Uses real directory checks which are more reliable in CI environment
ad8b5fc to
b3acdf7
Compare
6f5a129 to
b58b655
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @ryoppippi!
I noticed ClaudeCode_Dashboard was removed from Related Projects in this commit.
Was there any issue with it?
Please let me know if I need to fix anything.
Thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OMG I failed to create a correct merge commit. I'm sorry
Could you send a PR again?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No problem! I'll send a new PR shortly 😊
feat: Support multiple Claude data directories to handle v1.0.30+ path change
Summary
fixes: #121
This PR adds support for multiple Claude data directories to handle different Claude Code installations and the breaking change where logs moved from ~/.claude to ~/.config/claude.
Key Features
• Multiple Path Support: Automatically searches both ~/.config/claude/projects/ (new default) and ~/.claude/projects/ (old default)
• Environment Variable: Set CLAUDE_CONFIG_DIR to specify custom path(s) - supports comma-separated multiple paths
• Data Aggregation: Usage data from all valid directories is automatically combined
• Backward Compatibility: Existing configurations continue to work without changes
Implementation Highlights
• Core Functionality: New getClaudePaths() function with path normalization and duplicate removal
• Environment Support: CLAUDE_CONFIG_DIR accepts single or comma-separated multiple paths
• Robust Testing: Comprehensive test coverage with CI improvements for multiple path scenarios
• Code Quality: Refactored imports to use .ts extensions, replaced custom utilities with @antfu/utils
Commit Organization
Each commit represents a logical grouping:
Breaking Changes
None - this is fully backward compatible. Existing users will see no changes in behavior.
Migration Path
• No Action Required: Existing ~/.claude installations continue working
• Optional: Set CLAUDE_CONFIG_DIR environment variable for custom paths
• Future-Proof: New ~/.config/claude installations are automatically detected
Test Plan
Summary by CodeRabbit
New Features
Documentation
Chores