Conversation
Restructure rdpath from flat command to subcommand pattern (path as default, find as new) for cross-platform file discovery within artifact directories. Uses Node 24 built-in fs.glob() with isPathInside() traversal protection. Extract validateCtx() and resolveBaseDir() helpers from assemblePath() for reuse. Backward compatible via isDefault: true.
Replace instanceof Error with getErrorMessage() from shared/errors.js for cross-realm ESM compatibility. Make resolveBaseDir a private function to prevent bypassing ctx validation.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e683eaae5d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Warning Rate limit exceeded
⌛ 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. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAdds a glob-based file discovery feature to rdpath via a new Changes
Sequence DiagramsequenceDiagram
participant CLI as rdpath CLI
participant Validator as validateCtx()
participant Resolver as resolveBaseDir()
participant Globber as findFiles (glob)
participant FS as Filesystem
CLI->>Validator: validate ctx string
alt invalid ctx
Validator-->>CLI: throw error
else valid ctx
Validator-->>CLI: return
end
CLI->>Resolver: resolve base dir (dir, ctx)
Resolver->>FS: stat/check directory exists
alt not found
FS-->>Resolver: not found
Resolver-->>CLI: throw "Directory not found"
else exists
FS-->>Resolver: ok
Resolver-->>CLI: return scoped dir
end
CLI->>CLI: validate pattern (reject "..")
alt invalid pattern
CLI-->>CLI: exit 1 with error
else valid pattern
CLI->>Globber: run glob in scoped dir
Globber->>FS: read directory tree
FS-->>Globber: files
Globber-->>CLI: sorted matches
CLI-->>CLI: print matches (one per line)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
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.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/claude-code-plugin/__tests__/rdpath-find-integration.test.ts`:
- Around line 42-44: The current proc.on('close', (code) => resolve({ stdout,
stderr, exitCode: code ?? 0 })) masks signal-based termination by treating null
code as success; update the handler in the test to use a non-zero default (e.g.,
exitCode: code ?? 1) and/or accept the second parameter (signal) from
proc.on('close', (code, signal) => ...) and include that signal in the resolved
object so tests can distinguish normal exits from killed processes.
In `@packages/claude-code-plugin/src/rdpath.ts`:
- Around line 12-18: The import/command block (symbols assemblePath, findFiles,
RdPathFindOptions, RdPathOptions, getErrorMessage, Command, program, pathCmd) is
misformatted according to the project's formatter; run the project's formatter
(npm run format) or apply the repo's formatting rules to this section so the
import lines and Command setup follow the configured style (fix spacing,
semicolons/newlines as needed) and commit the formatted file to resolve the CI
pipeline failure.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 9c56b918-69e1-450c-881d-a78b03fc7213
📒 Files selected for processing (5)
CLAUDE.mdpackages/claude-code-plugin/__tests__/rdpath-core.test.tspackages/claude-code-plugin/__tests__/rdpath-find-integration.test.tspackages/claude-code-plugin/src/rdpath-core.tspackages/claude-code-plugin/src/rdpath.ts
Deploying rundown with
|
| Latest commit: |
0a457d8
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://0505125f.rundown-7hl.pages.dev |
| Branch Preview URL: | https://rdpath-find.rundown-7hl.pages.dev |
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
packages/claude-code-plugin/__tests__/rdpath-find-integration.test.ts (1)
42-44:⚠️ Potential issue | 🟡 MinorDo not map signal termination to success in
runRdpath.Line 43 uses
code ?? 0, which treats signal exits as success and can hide real failures in integration tests.🔧 Suggested fix
- proc.on('close', (code) => { - resolve({ stdout, stderr, exitCode: code ?? 0 }); + proc.on('close', (code) => { + resolve({ stdout, stderr, exitCode: code ?? 1 }); });In Node.js `child_process`, for the `'close'` event callback `(code, signal)`, can `code` be `null` when terminated by signal, and is it recommended to treat that as non-zero failure in test harnesses?🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/claude-code-plugin/__tests__/rdpath-find-integration.test.ts` around lines 42 - 44, The test harness currently maps a null exit code to 0 in the proc.on('close', (code) => resolve({ stdout, stderr, exitCode: code ?? 0 })) callback, which treats signal-terminated processes as successful; change the logic in runRdpath (the proc.on('close' handler) to treat code === null as failure by setting exitCode to a non-zero value (e.g., 1) and include the signal in the resolved object (resolve({ stdout, stderr, exitCode: code !== null ? code : 1, signal })) so signal terminations are not masked as success.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/claude-code-plugin/src/rdpath-core.ts`:
- Around line 114-140: findings: findFiles() currently allows absolute glob
patterns (which bypass cwd scoping) and includes directories in results,
violating the JSDoc that promises "matching file paths". Fix: first reject
absolute patterns (use path.isAbsolute(pattern) and throw a clear error) in
addition to the existing TRAVERSAL_PATTERN check; then when iterating glob
results from fs.glob(pattern, { cwd: absoluteDir }), ensure only files are
returned by either passing a nodir-like option to fs.glob if available or by
stat-ing each absoluteMatch (using fs.stat or fs.lstat) and skipping entries
where stat.isDirectory() is true; keep the isPathInside(absoluteDir,
absoluteMatch) validation and push path.join(resolvedDir, match) only for
verified file matches so matches[] contains only files.
---
Duplicate comments:
In `@packages/claude-code-plugin/__tests__/rdpath-find-integration.test.ts`:
- Around line 42-44: The test harness currently maps a null exit code to 0 in
the proc.on('close', (code) => resolve({ stdout, stderr, exitCode: code ?? 0 }))
callback, which treats signal-terminated processes as successful; change the
logic in runRdpath (the proc.on('close' handler) to treat code === null as
failure by setting exitCode to a non-zero value (e.g., 1) and include the signal
in the resolved object (resolve({ stdout, stderr, exitCode: code !== null ? code
: 1, signal })) so signal terminations are not masked as success.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 34726f22-1131-43c2-a0f7-391adf12adbf
📒 Files selected for processing (4)
packages/claude-code-plugin/__tests__/rdpath-core.test.tspackages/claude-code-plugin/__tests__/rdpath-find-integration.test.tspackages/claude-code-plugin/src/rdpath-core.tspackages/claude-code-plugin/src/rdpath.ts
Address PR review feedback: - Reject absolute glob patterns that bypass cwd scoping - Filter glob results to files only (exclude directories) - Treat null exit code as failure in integration test harness
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/claude-code-plugin/__tests__/rdpath-core.test.ts`:
- Around line 203-233: Add a new test in rdpath-core.test.ts that creates a
dangling symlink inside testDir (symlink pointing to a non-existent target),
calls findFiles({ dir: testDir }, '*.md'), and asserts the expected behavior
(either that the dangling symlink is excluded or included according to project
convention); use the same pattern as the existing symlink tests (create files
with fs.writeFile / fs.symlink, call findFiles, and use
expect(results).toEqual(...) or expect(...).not.toContainEqual(...)) and
reference testDir and findFiles so the regression for broken links is pinned.
In `@packages/claude-code-plugin/src/rdpath-core.ts`:
- Around line 141-146: The glob loop that calls fs.realpath and fs.lstat (inside
the for-await over fs.glob with pattern/absoluteDir and using variables
absoluteMatch, realMatch, stat) needs a try-catch so a single FS error doesn't
abort findFiles; wrap the fs.realpath(realMatch) and fs.lstat(realMatch) calls
in a try block, catch errors and use the existing isNodeError(err) helper to
check err.code and continue the loop for expected recoverable codes (ENOENT,
EACCES, EPERM, ELOOP), but re-throw the error for anything else so unexpected
failures still surface.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 166631bd-8924-4f68-a86f-6da87283bd2a
📒 Files selected for processing (3)
packages/claude-code-plugin/__tests__/rdpath-core.test.tspackages/claude-code-plugin/__tests__/rdpath-find-integration.test.tspackages/claude-code-plugin/src/rdpath-core.ts
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/claude-code-plugin/__tests__/rdpath-core.test.ts`:
- Around line 108-112: Add a new test in rdpath-core.test.ts that exercises the
"existing path but not a directory" branch by calling findFiles with dir set to
a path that exists as a file (e.g., path.join(testDir, 'someFile.txt')) and
asserting the promise rejects with the "Not a directory" error; locate the
existing test named 'throws for nonexistent directory' and add a sibling it(...)
that uses await expect(findFiles({ dir: path.join(testDir, '<filename>' ) },
'*.md')).rejects.toThrow('Not a directory') to pin the Not a directory branch in
the findFiles codepath.
In `@packages/claude-code-plugin/src/rdpath-core.ts`:
- Around line 104-108: The TSDoc for findFiles omits the error case where the
provided dir exists but is not a directory; update the findFiles docblock to add
a `@throws` entry describing that an Error is thrown when the path specified by
options.dir exists but is not a directory (e.g., "When dir exists but is not a
directory"). Locate the JSDoc/TSDoc immediately above the findFiles function
declaration and add the concise `@throws` clause alongside the existing throws
about invalid ctx, traversal patterns, and missing directories so the exported
API contract accurately documents all failure paths.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 361ae13e-e9c4-4a09-824d-95438b4ae7e2
📒 Files selected for processing (2)
packages/claude-code-plugin/__tests__/rdpath-core.test.tspackages/claude-code-plugin/src/rdpath-core.ts
Symlinked matches could bypass the directory jail because isPathInside() only checked the lexical path while fs.stat() followed the symlink. Resolve each match with fs.realpath() before the containment check, and resolve the base directory too so both sides compare real paths.
Summary by CodeRabbit