Skip to content

Conversation

@nyatinte
Copy link
Owner

@nyatinte nyatinte commented Jul 30, 2025

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

  • ccexp only scanned from current working directory downward
  • Project CLAUDE.md files were missed when running from subdirectories
  • Recursive option was inconsistently applied across scanners
  • Environment-specific hardcoding for project directories

To-Be

  • Always scan from HOME directory by default (with path override option)
  • Intelligent filtering to prioritize likely project directories
  • Consistent deep scanning behavior across all file types
  • Pattern-based and marker-based project detection

Changes

1. Remove Recursive Option from Type System

  • Removed recursive property from ScanOptions type
  • Updated all scanner function signatures to remove recursive parameter
  • Simplified API by eliminating confusing option

2. Default to HOME Directory Scanning

  • Changed default scan path from process.cwd() to homedir()
  • All scanner functions now default to HOME directory
  • Path parameter remains optional for specific directory scanning

3. Implement Intelligent Directory Filtering

  • Added isLikelyProjectDirectory() function with:
    • Pattern-based detection (dev, project, work, src, repos, etc.)
    • Marker file detection (.git, package.json, CLAUDE.md, etc.)
  • Added shouldExcludeDirectory() with comprehensive exclusions:
    • System/cache directories
    • OS-specific directories (Library, AppData, etc.)
    • Large media directories
    • Hidden config directories

4. Always Scan Deeply

  • Set maxDepth: 20 in fast-scanner for all operations
  • Removed conditional depth logic based on recursive flag
  • Ensures consistent discovery of nested project files

5. Update Tests for New Behavior

  • Removed all recursive parameter references from tests
  • Updated test expectations for deep scanning behavior
  • Fixed test cases to work with new default HOME scanning

Technical 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

⚠️ This PR includes breaking changes:

  • The recursive option has been completely removed from the API
  • Default scanning behavior now starts from HOME instead of current directory
  • External code using the recursive option will need to be updated

Fixes #69

Summary by CodeRabbit

  • New Features

    • Scanning now defaults to the user's home directory, with improved logic to intelligently search likely project directories while excluding system and irrelevant folders.
  • Bug Fixes

    • Removed the recursive option from all scanning functions, ensuring consistent and simplified scanning behavior across the application.
  • Refactor

    • Streamlined scanning logic and options, removing recursion control and related code for a more predictable and efficient file search process.
  • Tests

    • Updated test cases to reflect the new default scanning behavior and removal of the recursive option.

- 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.
@coderabbitai
Copy link

coderabbitai bot commented Jul 30, 2025

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Note

Other AI code review bot(s) detected

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

Walkthrough

The codebase refactors its file scanning logic by removing the recursive option from all relevant types, functions, and tests. Scanning now defaults to the user's home directory, with an enhanced, intelligent search strategy that prioritizes likely project directories and excludes irrelevant or system directories. All related tests and patterns are updated accordingly.

Changes

Cohort / File(s) Change Summary
Type Definitions
src/_types.ts
Removed recursive from ScanOptions; added a comment to the path property indicating it defaults to the HOME directory.
Claude File Scanning Logic
src/claude-md-scanner.ts
Refactored scanClaudeFiles to scan from HOME by default, added smart directory filtering, introduced project directory heuristics, removed recursion control, and updated helper functions and tests.
Fast Scanner and Related Functions
src/fast-scanner.ts
Removed recursive from CrawlerOptions and all usage; scanning now defaults to HOME with a fixed depth. Updated all scanner functions and related tests.
File Navigation Hook
src/hooks/useFileNavigation.tsx
Removed the recursive option from options handling and scanning logic.
File Navigation Hook Tests
src/hooks/useFileNavigation.test.tsx
Removed all { recursive: ... } test options; updated all test cases to reflect new scanning defaults.
Settings JSON Scanner
src/settings-json-scanner.ts
Removed recursive option and logic; scanning now defaults to HOME and does not scan recursively or include global Claude dir.
Slash Command Scanner
src/slash-command-scanner.ts
Removed recursive option and logic; scanning now defaults to HOME and always uses recursive patterns. Updated related tests.
Subagent Scanner Tests
src/subagent-scanner.ts
Removed recursive: true from test invocations only; no logic 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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Assessment against linked issues

Objective Addressed Explanation
Discover project CLAUDE.md files regardless of execution location (#69)
Scan from HOME directory with intelligent filtering and project detection heuristics (#69)
Remove environment-specific hardcoding and use pattern/marker-based project detection (#69)
Exclude system, cache, and irrelevant directories during scanning (#69)

Poem

In burrows deep, the scanner hops,
From home it starts, it never stops.
No more recursion, nor lost in a loop—
It sniffs out projects, skips the gloop!
CLAUDE.md, we see you now,
Thanks to a clever bunny’s know-how! 🐇✨

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/#69/scan-all-file

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@gemini-code-assist gemini-code-assist bot left a 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 recursive option has been completely removed from the ScanOptions type (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 from process.cwd() to homedir() (src/claude-md-scanner.ts, line 26; src/fast-scanner.ts, line 50). This ensures that CLAUDE.md files 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 includes isLikelyProjectDirectory() (pattern-based and marker-file detection) and shouldExcludeDirectory() (comprehensive exclusion list for system, cache, and large media directories). Additionally, all scanning operations now consistently use a maxDepth of 20 (src/fast-scanner.ts, line 54), ensuring deep discovery of nested project files without relying on a recursive flag.
  • 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, and src/subagent-scanner.ts have been updated to remove all references to the recursive parameter 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

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

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jul 30, 2025

Open in StackBlitz

npm i https://pkg.pr.new/nyatinte/ccexp@70

commit: 5ef5f95

@nyatinte nyatinte marked this pull request as draft July 30, 2025 15:15
Copy link

@gemini-code-assist gemini-code-assist bot left a 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.

Comment on lines +70 to +77
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);

Choose a reason for hiding this comment

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

medium

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);
              }
            }

Comment on lines +193 to +221
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',
];

Choose a reason for hiding this comment

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

medium

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.

Comment on lines +476 to +477
path: fixture.getPath('my-app'), // Run from project root
});

Choose a reason for hiding this comment

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

medium

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();

Choose a reason for hiding this comment

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

medium

The _patterns variable is assigned but never used. It can be safely removed to clean up the code.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/claude-md-scanner.ts (1)

121-149: Consider removing the unused recursive parameter.

The getSearchPatterns function still has a recursive parameter that defaults to true. 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

📥 Commits

Reviewing files that changed from the base of the PR and between 0dff0ce and 2edc157.

📒 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.ts
  • src/hooks/useFileNavigation.tsx
  • src/fast-scanner.ts
  • src/hooks/useFileNavigation.test.tsx
  • src/slash-command-scanner.ts
  • src/_types.ts
  • src/claude-md-scanner.ts
**/*.tsx

📄 CodeRabbit Inference Engine (CLAUDE.md)

React components must be defined using the 'function' declaration syntax.

Files:

  • src/hooks/useFileNavigation.tsx
  • src/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 path property, removing the recursive option 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 recursive since 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 homedir and 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 useFileNavigation with 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 useFileNavigation without 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() to homedir(), 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 getSlashCommandPatterns function 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 recursive property from CrawlerOptions and the simplified createBaseCrawler implementation 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 scanClaudeFiles function implements the multi-step intelligent search strategy as described in the PR objectives:

  1. Scans ~/.claude directory
  2. Checks for CLAUDE.md at HOME level
  3. 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 isLikelyProjectDirectory function 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 shouldExcludeDirectory function implements comprehensive exclusion patterns covering:

  • System/cache directories
  • OS-specific directories
  • Large media directories
  • Build/temp directories
  • Package manager directories

The special handling for .claude directory is correctly implemented.


299-327: Tests confirm recursive patterns are always expected.

All tests for getSearchPatterns expect recursive patterns (with **/ prefix) and don't pass the recursive parameter, 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Project CLAUDE.md files not discovered when ccexp is run from subdirectories

2 participants