-
-
Notifications
You must be signed in to change notification settings - Fork 10
fix: remove recursive option and always scan from HOME directory (#69) #70
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
base: main
Are you sure you want to change the base?
Conversation
- Remove recursive option from ScanOptions type - Change default scan path to HOME directory instead of cwd - Always scan deeply with maxDepth: 20 in fast-scanner - Add intelligent filtering when scanning from HOME: - Prioritize likely project directories by name patterns - Check for marker files (.git, package.json, etc.) - Exclude system/cache/media directories - Update all scanner functions to use HOME as default - Fix tests to work with new scanning behavior This ensures CLAUDE.md files are discovered even when ccexp is run from subdirectories, addressing the core issue in #69.
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughThe codebase refactors its file scanning logic by removing the Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant scanClaudeFiles
participant HOME
participant findClaudeFiles
participant isLikelyProjectDirectory
participant shouldExcludeDirectory
User->>scanClaudeFiles: Call (options)
scanClaudeFiles->>HOME: Get home directory path
scanClaudeFiles->>findClaudeFiles: Scan ~/.claude (if exists)
scanClaudeFiles->>HOME: List all top-level directories
loop For each directory in HOME
scanClaudeFiles->>shouldExcludeDirectory: Check exclusion
alt Not excluded
scanClaudeFiles->>isLikelyProjectDirectory: Check if likely project
alt Is likely project
scanClaudeFiles->>findClaudeFiles: Recursively scan directory
else Not likely project
scanClaudeFiles->>findClaudeFiles: Scan for CLAUDE.md, CLAUDE.local.md at top level only
end
end
end
scanClaudeFiles-->>User: Return found files
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Assessment against linked issues
Poem
✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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 @nyatinte, 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 fundamentally re-architects the file scanning mechanism to improve discoverability of project files, particularly CLAUDE.md files, regardless of where the application is executed. It achieves this by standardizing the scan origin to the user's HOME directory and implementing smart filtering to efficiently locate relevant project directories, while also simplifying the public API by removing a redundant option.
Highlights
- API Simplification: Removal of 'recursive' option: The
recursiveoption has been completely removed from theScanOptionstype (src/_types.ts, lines 61-62) and all scanner function signatures. This simplifies the API by eliminating a confusing and inconsistently applied option, making scanning behavior more predictable. - Default Scan Path: Always from HOME directory: The default scanning behavior for all scanner functions (e.g.,
scanClaudeFiles,findClaudeFiles,findSlashCommands) has been changed fromprocess.cwd()tohomedir()(src/claude-md-scanner.ts, line 26;src/fast-scanner.ts, line 50). This ensures thatCLAUDE.mdfiles are discovered regardless of the current working directory, addressing the original issue. - Intelligent Directory Filtering and Deep Scanning: When scanning from the HOME directory, new intelligent filtering logic has been introduced (
src/claude-md-scanner.ts, lines 187-285). This includesisLikelyProjectDirectory()(pattern-based and marker-file detection) andshouldExcludeDirectory()(comprehensive exclusion list for system, cache, and large media directories). Additionally, all scanning operations now consistently use amaxDepthof 20 (src/fast-scanner.ts, line 54), ensuring deep discovery of nested project files without relying on arecursiveflag. - Test Suite Updates: The test suites across
src/claude-md-scanner.ts,src/fast-scanner.ts,src/hooks/useFileNavigation.test.tsx,src/settings-json-scanner.ts,src/slash-command-scanner.ts, andsrc/subagent-scanner.tshave been updated to remove all references to therecursiveparameter and to reflect the new default deep scanning behavior from the HOME directory.
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 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 or fill out our survey 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. ↩
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.
Code Review
This pull request is a significant and well-executed refactoring of the file scanning logic. Removing the recursive option and defaulting to an intelligent HOME directory scan simplifies the API and correctly solves the issue of discovering project files from subdirectories. The introduction of helper functions like isLikelyProjectDirectory and shouldExcludeDirectory is a great way to encapsulate the new filtering logic.
The code changes are clean, and the tests have been updated accordingly. I have a few suggestions to further improve performance and maintainability, but overall, this is a solid contribution that improves the tool's usability and robustness.
| const claudeMdPath = join(dirPath, 'CLAUDE.md'); | ||
| if (existsSync(claudeMdPath)) { | ||
| files.push(claudeMdPath); | ||
| } | ||
|
|
||
| // 3. Scan first-level subdirectories in home for CLAUDE.md files | ||
| // This finds project-level CLAUDE.md files without deep recursion | ||
| try { | ||
| const homeContents = await readdir(homeDir, { withFileTypes: true }); | ||
| const directoriesToSkip = new Set([ | ||
| '.cache', | ||
| '.npm', | ||
| '.yarn', | ||
| '.pnpm', | ||
| 'node_modules', | ||
| '.git', | ||
| '.svn', | ||
| '.hg', | ||
| 'Library', | ||
| 'Applications', | ||
| '.Trash', | ||
| '.local', | ||
| '.config', | ||
| '.vscode', | ||
| '.idea', | ||
| ]); | ||
|
|
||
| // Common project directories that should be scanned deeper | ||
| const projectDirectories = new Set([ | ||
| 'my_programs', | ||
| 'projects', | ||
| 'dev', | ||
| 'development', | ||
| 'workspace', | ||
| 'work', | ||
| 'code', | ||
| 'repos', | ||
| 'git', | ||
| 'Documents', | ||
| 'Desktop', | ||
| 'src', | ||
| 'source', | ||
| ]); | ||
|
|
||
| for (const entry of homeContents) { | ||
| if ( | ||
| entry.isDirectory() && | ||
| !directoriesToSkip.has(entry.name) && | ||
| !entry.name.startsWith('.') | ||
| ) { | ||
| const dirPath = join(homeDir, entry.name); | ||
|
|
||
| // Check for CLAUDE.md in this directory | ||
| const claudeMdPath = join(dirPath, 'CLAUDE.md'); | ||
| if (existsSync(claudeMdPath)) { | ||
| files.push(claudeMdPath); | ||
| } | ||
|
|
||
| // Also check for CLAUDE.local.md | ||
| const claudeLocalPath = join(dirPath, 'CLAUDE.local.md'); | ||
| if (existsSync(claudeLocalPath)) { | ||
| files.push(claudeLocalPath); | ||
| } | ||
|
|
||
| // For project directories, scan recursively but with constraints | ||
| if (projectDirectories.has(entry.name)) { | ||
| try { | ||
| // Use findClaudeFiles to recursively scan project directories | ||
| const projectFiles = await findClaudeFiles({ | ||
| path: dirPath, | ||
| recursive: true, | ||
| includeHidden: false, | ||
| }); | ||
| files.push(...projectFiles); | ||
| } catch (error) { | ||
| // If we can't scan the directory, just skip it | ||
| console.warn( | ||
| `Failed to scan ${entry.name} subdirectories:`, | ||
| error, | ||
| ); | ||
| } | ||
| } | ||
| const claudeLocalPath = join(dirPath, 'CLAUDE.local.md'); | ||
| if (existsSync(claudeLocalPath)) { | ||
| files.push(claudeLocalPath); |
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.
This block for checking CLAUDE.md and CLAUDE.local.md contains duplicated logic. It could be made more maintainable and less repetitive by using a loop.
More importantly, the filenames are hardcoded here. If a new file pattern (e.g., CLAUDE.dev.md) is supported in the future, it would need to be manually added here as well, making it a potential point of failure. Using an array of filenames to check would be more robust.
// For other directories, just check the first level
const claudeFilesToCheck = ['CLAUDE.md', 'CLAUDE.local.md'];
for (const fileName of claudeFilesToCheck) {
const filePath = join(dirPath, fileName);
if (existsSync(filePath)) {
files.push(filePath);
}
}| const namePatterns = [ | ||
| /^(dev|develop|development)$/i, | ||
| /^(proj|project|projects)$/i, | ||
| /^(work|workspace|code|src|source)$/i, | ||
| /^(repo|repos|repositories)$/i, | ||
| /^(git|github|gitlab)$/i, | ||
| /^my_programs$/i, // Keep specific known directories | ||
| ]; | ||
|
|
||
| if (namePatterns.some((pattern) => pattern.test(dirName))) { | ||
| return true; | ||
| } | ||
|
|
||
| // 2. Marker file detection | ||
| const markers = [ | ||
| '.git', | ||
| 'package.json', | ||
| 'Cargo.toml', | ||
| 'go.mod', | ||
| 'requirements.txt', | ||
| '.claude', | ||
| 'CLAUDE.md', | ||
| 'pyproject.toml', | ||
| 'composer.json', | ||
| 'Gemfile', | ||
| 'pom.xml', | ||
| 'build.gradle', | ||
| 'CMakeLists.txt', | ||
| ]; |
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.
For performance, constant arrays like namePatterns and markers should be defined at the module level, outside the function. This avoids re-creating them on every function call. Since isLikelyProjectDirectory is called within a loop, this optimization could be beneficial.
The same principle applies to the excludePatterns array in the shouldExcludeDirectory function.
| path: fixture.getPath('my-app'), // Run from project root | ||
| }); |
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.
This comment, "Should find CLAUDE.md files from parent directories", appears to be incorrect. The implementation of scanClaudeFiles with a specific path argument scans downwards from that path; it does not scan parent directories. The new default behavior (without a path) scans from HOME, which solves the problem of running from a subdirectory, but this specific test case provides a path, so it will only scan downwards.
Please consider updating the comment to accurately reflect what the test is asserting.
|
|
||
| const _patterns = getSlashCommandPatterns(recursive); | ||
| const _patterns = getSlashCommandPatterns(); |
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.
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/claude-md-scanner.ts (1)
121-149: Consider removing the unusedrecursiveparameter.The
getSearchPatternsfunction still has arecursiveparameter that defaults totrue. Since the PR removes recursive options throughout the codebase and this function is only used internally with the default value, consider removing this parameter entirely for consistency.-const getSearchPatterns = ( - type?: ClaudeFileType, - recursive = true, -): string[] => { +const getSearchPatterns = ( + type?: ClaudeFileType, +): string[] => { const patterns: string[] = []; - const prefix = recursive ? '**/' : ''; + const prefix = '**/';
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
src/_types.ts(1 hunks)src/claude-md-scanner.ts(4 hunks)src/fast-scanner.ts(7 hunks)src/hooks/useFileNavigation.test.tsx(3 hunks)src/hooks/useFileNavigation.tsx(2 hunks)src/settings-json-scanner.ts(1 hunks)src/slash-command-scanner.ts(3 hunks)src/subagent-scanner.ts(0 hunks)
💤 Files with no reviewable changes (1)
- src/subagent-scanner.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (CLAUDE.md)
**/*.{ts,tsx}: All TypeScript code must use 'type' instead of 'interface' for type definitions.
Regular (non-component) functions must be defined using arrow function syntax.
Avoid default exports except for page components.
Never use the 'any' type; it is strictly forbidden.
Avoid 'as' type assertions; use proper type guards instead.
Remove unused imports and exports immediately to keep dependencies clean.
All TypeScript code must pass with zero type errors (strict mode enforced).
All code must pass Biome lint/format checks with zero errors.
All code must have zero unused dependencies, exports, or types (enforced by Knip).
All code must use immutable design with 'readonly' properties throughout TypeScript code.
All optional properties in TypeScript must use 'exactOptionalPropertyTypes: true' (no '| undefined' on optional props).
Array access in TypeScript must account for 'noUncheckedIndexedAccess: true' (array access returns 'T | undefined').
All code paths in TypeScript functions must return a value ('noImplicitReturns: true').
Files:
src/settings-json-scanner.tssrc/hooks/useFileNavigation.tsxsrc/fast-scanner.tssrc/hooks/useFileNavigation.test.tsxsrc/slash-command-scanner.tssrc/_types.tssrc/claude-md-scanner.ts
**/*.tsx
📄 CodeRabbit Inference Engine (CLAUDE.md)
React components must be defined using the 'function' declaration syntax.
Files:
src/hooks/useFileNavigation.tsxsrc/hooks/useFileNavigation.test.tsx
src/hooks/*.test.tsx
📄 CodeRabbit Inference Engine (CLAUDE.md)
All React hooks must be tested, with tests co-located in files ending with '.test.tsx' alongside the hook files.
Files:
src/hooks/useFileNavigation.test.tsx
**/*.test.{ts,tsx}
📄 CodeRabbit Inference Engine (CLAUDE.md)
All tests must pass with 100% success rate for React components and business logic.
Files:
src/hooks/useFileNavigation.test.tsx
🧠 Learnings (6)
src/hooks/useFileNavigation.tsx (3)
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to **/*.{ts,tsx} : Remove unused imports and exports immediately to keep dependencies clean.
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to **/*.{ts,tsx} : Avoid default exports except for page components.
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to **/*.{ts,tsx} : All code must have zero unused dependencies, exports, or types (enforced by Knip).
src/fast-scanner.ts (4)
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to **/*.{ts,tsx} : Remove unused imports and exports immediately to keep dependencies clean.
Learnt from: nyatinte
PR: #33
File: CLAUDE.md:265-282
Timestamp: 2025-07-21T18:07:28.502Z
Learning: Bun supports the ECMAScript resource management proposal including the await using syntax, so examples using await using fixture = await createFixture(fileTree); are valid and will compile correctly.
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to src/_utils.ts : Tests for utility functions must be defined using the InSource Testing pattern (tests live alongside the source code in the same file).
Learnt from: nyatinte
PR: #33
File: CLAUDE.md:265-282
Timestamp: 2025-07-21T18:07:28.502Z
Learning: Bun has supported the ECMAScript resource management proposal including the using and await using syntax since January 2024 (merged in PR #8151). Examples using await using fixture = await createFixture(fileTree); are valid and will compile correctly in Bun.
src/hooks/useFileNavigation.test.tsx (10)
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to **/*.{ts,tsx} : Remove unused imports and exports immediately to keep dependencies clean.
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to **/*.{ts,tsx} : All code must have zero unused dependencies, exports, or types (enforced by Knip).
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to src/hooks/*.test.tsx : All React hooks must be tested, with tests co-located in files ending with '.test.tsx' alongside the hook files.
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to src/_utils.ts : Tests for utility functions must be defined using the InSource Testing pattern (tests live alongside the source code in the same file).
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to **/*.{ts,tsx} : Avoid default exports except for page components.
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to **/*.test.{ts,tsx} : All tests must pass with 100% success rate for React components and business logic.
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to **/*.{ts,tsx} : All optional properties in TypeScript must use 'exactOptionalPropertyTypes: true' (no '| undefined' on optional props).
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to **/*.{ts,tsx} : All code must pass Biome lint/format checks with zero errors.
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to **/*.{ts,tsx} : All TypeScript code must pass with zero type errors (strict mode enforced).
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to src/components/**/*.test.tsx : All React components must be tested, with tests co-located in files ending with '.test.tsx' alongside the component files.
src/slash-command-scanner.ts (2)
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to src/_utils.ts : Tests for utility functions must be defined using the InSource Testing pattern (tests live alongside the source code in the same file).
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to src/hooks/*.test.tsx : All React hooks must be tested, with tests co-located in files ending with '.test.tsx' alongside the hook files.
src/_types.ts (2)
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to **/*.{ts,tsx} : All optional properties in TypeScript must use 'exactOptionalPropertyTypes: true' (no '| undefined' on optional props).
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to **/*.{ts,tsx} : All code must use immutable design with 'readonly' properties throughout TypeScript code.
src/claude-md-scanner.ts (4)
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to src/_utils.ts : Tests for utility functions must be defined using the InSource Testing pattern (tests live alongside the source code in the same file).
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to src/hooks/*.test.tsx : All React hooks must be tested, with tests co-located in files ending with '.test.tsx' alongside the hook files.
Learnt from: CR
PR: nyatinte/ccexp#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-27T15:51:39.333Z
Learning: Applies to **/*.test.{ts,tsx} : All tests must pass with 100% success rate for React components and business logic.
Learnt from: nyatinte
PR: #33
File: CLAUDE.md:265-282
Timestamp: 2025-07-21T18:07:28.502Z
Learning: Bun supports the ECMAScript resource management proposal including the await using syntax, so examples using await using fixture = await createFixture(fileTree); are valid and will compile correctly.
🔇 Additional comments (22)
src/_types.ts (1)
61-61: LGTM - Clear documentation of new default behavior.The comment clearly indicates that the default path is now the HOME directory, which aligns perfectly with the PR objective to change scanning behavior from current working directory to HOME directory.
src/hooks/useFileNavigation.tsx (3)
69-69: LGTM - Properly removes recursive option from destructuring.The destructuring correctly extracts only the
pathproperty, removing therecursiveoption as intended by the PR.
73-73: LGTM - Consistent scanOptions object without recursive property.The scanOptions object correctly excludes the recursive property and will be passed consistently to all scanner methods.
169-169: LGTM - useEffect dependencies correctly updated.The dependency array appropriately removes
recursivesince it's no longer part of the options, maintaining correct React hook dependency tracking.src/settings-json-scanner.ts (2)
48-49: LGTM - Correct implementation of HOME directory default.The import of
homedirand its use as the default path correctly implements the PR objective to change scanning from current working directory to HOME directory.
52-52: LGTM - Updated comment reflects new scanning behavior.The comment accurately describes the simplified scanning logic that now scans from the specified path without recursive complexity.
src/hooks/useFileNavigation.test.tsx (3)
29-29: LGTM - Test correctly removes recursive option.The TestComponent properly calls
useFileNavigationwith an empty options object, removing the recursive option as intended by the PR.
603-603: LGTM - Consistent test pattern without recursive option.TestEmptyGroupsComponent correctly follows the same pattern of calling
useFileNavigationwithout the recursive option.
829-829: LGTM - All test components consistently updated.TestGroupOrderComponent maintains the same pattern, ensuring all test components are consistently updated to remove the recursive option.
src/slash-command-scanner.ts (4)
17-17: LGTM - Correct default path change to HOME directory.The default path is properly changed from
process.cwd()tohomedir(), implementing the core objective of this PR.
19-19: LGTM - Simplified function call without recursive parameter.The call to
getSlashCommandPatterns()correctly removes the recursive parameter, aligning with the function signature simplification.
60-61: LGTM - Function simplified to always return recursive patterns.The
getSlashCommandPatternsfunction is correctly simplified to always return recursive glob patterns (**/), removing the need for conditional logic based on a recursive parameter.
170-174: LGTM - Test properly updated for new function signature.The test correctly calls
getSlashCommandPatterns()without parameters and verifies the expected recursive patterns are returned.src/fast-scanner.ts (4)
8-39: LGTM! Clean removal of recursive option.The removal of the
recursiveproperty fromCrawlerOptionsand the simplifiedcreateBaseCrawlerimplementation align perfectly with the PR objectives.
47-71: LGTM! Proper implementation of HOME directory default.The function now defaults to scanning from the HOME directory with a fixed depth of 20, which aligns with the PR objectives to ensure CLAUDE.md files are discovered regardless of execution location.
76-177: LGTM! Consistent scanner implementations.All scanner functions (
findSlashCommands,findSubAgents,findSettingsJson) now consistently default to the HOME directory with a fixed depth of 20, ensuring uniform behavior across the codebase.
241-263: LGTM! Tests properly updated for deep scanning behavior.The test correctly validates that the scanner always performs deep scanning, expecting to find both the root and nested CLAUDE.md files without needing a recursive option.
src/claude-md-scanner.ts (5)
19-91: Well-structured implementation of intelligent HOME directory scanning.The refactored
scanClaudeFilesfunction implements the multi-step intelligent search strategy as described in the PR objectives:
- Scans
~/.claudedirectory- Checks for
CLAUDE.mdat HOME level- Intelligently filters and scans subdirectories based on project likelihood
The special handling for HOME directory scanning vs other paths is appropriate.
188-230: Excellent implementation of project directory detection.The
isLikelyProjectDirectoryfunction implements comprehensive heuristics for identifying project directories through:
- Pattern-based directory name matching
- Marker file detection across multiple languages and build systems
This aligns perfectly with the PR's intelligent filtering objectives.
233-285: Well-designed directory exclusion logic.The
shouldExcludeDirectoryfunction implements comprehensive exclusion patterns covering:
- System/cache directories
- OS-specific directories
- Large media directories
- Build/temp directories
- Package manager directories
The special handling for
.claudedirectory is correctly implemented.
299-327: Tests confirm recursive patterns are always expected.All tests for
getSearchPatternsexpect recursive patterns (with**/prefix) and don't pass therecursiveparameter, which supports the suggestion to remove this unused parameter from the function signature.
469-571: Comprehensive test coverage for new scanning behavior.The new test suite thoroughly validates:
- Discovery of CLAUDE.md files from subdirectories
- Intelligent filtering of project directories
- Proper exclusion of system and hidden directories
- Deep scanning behavior (finding nested files)
Excellent test coverage for the refactored scanning logic.
Overview
This PR addresses issue #69 where project CLAUDE.md files were not discovered when ccexp was run from subdirectories. The solution implements a fundamental change to the scanning behavior: removing the recursive option entirely and always scanning from the HOME directory by default with intelligent filtering.
As-Is
To-Be
Changes
1. Remove Recursive Option from Type System
recursiveproperty fromScanOptionstype2. Default to HOME Directory Scanning
process.cwd()tohomedir()3. Implement Intelligent Directory Filtering
isLikelyProjectDirectory()function with:shouldExcludeDirectory()with comprehensive exclusions:4. Always Scan Deeply
maxDepth: 20in fast-scanner for all operations5. Update Tests for New Behavior
recursiveparameter references from testsTechnical Details
The key improvement is the HOME directory scanning with intelligent filtering when no specific path is provided. This ensures CLAUDE.md files are discovered regardless of where ccexp is executed, while maintaining performance through smart directory filtering.
Breaking Changes
recursiveoption has been completely removed from the APIrecursiveoption will need to be updatedFixes #69
Summary by CodeRabbit
New Features
Bug Fixes
recursiveoption from all scanning functions, ensuring consistent and simplified scanning behavior across the application.Refactor
Tests
recursiveoption.