Skip to content

Conversation

@roomote
Copy link
Contributor

@roomote roomote bot commented Aug 21, 2025

This PR attempts to address Issue #7282 by adding support for symbolic links in the .roo/commands directory.

Problem

Users were unable to use symbolic links to markdown files in the .roo/commands directory. When a slash command markdown file was copied as a symbolic link, Roo Code would not recognize it as a valid command.

Solution

Modified the scanCommandDirectory function in src/services/command/commands.ts to check for both regular files and symbolic links using entry.isSymbolicLink() in addition to entry.isFile().

Changes

  • Modified command loading logic to recognize symbolic links as valid command files
  • Added comprehensive test coverage for symbolic link functionality including:
    • Loading commands from symbolic links
    • Handling mix of regular files and symbolic links
    • Gracefully handling broken symbolic links
    • Ensuring project symbolic links override global commands

Testing

  • Added new test suite symlink-commands.spec.ts with 5 test cases
  • All existing tests continue to pass
  • Linting and type checking pass successfully

Fixes #7282

Feedback and guidance are welcome!


Important

Adds support for symbolic links in .roo/commands by updating scanCommandDirectory to recognize them as valid command files, with comprehensive test coverage.

  • Behavior:
    • scanCommandDirectory in commands.ts now checks for symbolic links using entry.isSymbolicLink() in addition to entry.isFile().
    • Handles regular files, symbolic links, broken symbolic links, and symbolic links pointing to directories.
    • Project symbolic links override global commands.
  • Testing:
    • New test suite symlink-commands.spec.ts with 5 test cases covering various scenarios of symbolic link handling.
    • All existing tests pass.
  • Misc:

This description was created by Ellipsis for 90e983e. You can customize this summary. It will automatically update as commits are pushed.

- Modified scanCommandDirectory to check for both regular files and symbolic links
- Added comprehensive test coverage for symbolic link functionality
- Ensures symbolic links to markdown files are properly loaded as commands

Fixes #7282
@roomote roomote bot requested review from cte, jr and mrubens as code owners August 21, 2025 14:46
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. enhancement New feature or request labels Aug 21, 2025
Copy link
Contributor Author

@roomote roomote bot left a comment

Choose a reason for hiding this comment

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

Reviewing my own code is like debugging in a mirror - everything looks backwards but the bugs are still mine.

for (const entry of entries) {
if (entry.isFile() && isMarkdownFile(entry.name)) {
// Check for both regular files and symbolic links
if ((entry.isFile() || entry.isSymbolicLink()) && isMarkdownFile(entry.name)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is this approach intentional? I notice we're explicitly checking for symbolic links here in scanCommandDirectory, but the tryLoadCommand function (lines 54-112) doesn't have this explicit check. While fs.readFile follows symlinks automatically, this creates an inconsistency in how we handle symlinks across the codebase. Should we add a similar check in tryLoadCommand for consistency?

for (const entry of entries) {
if (entry.isFile() && isMarkdownFile(entry.name)) {
// Check for both regular files and symbolic links
if ((entry.isFile() || entry.isSymbolicLink()) && isMarkdownFile(entry.name)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Security consideration: Symbolic links can point to files outside the commands directory. While this flexibility might be useful, could it potentially allow access to sensitive files if a malicious symlink is placed in the commands directory? Should we consider validating that symlinks resolve to paths within expected boundaries?

for (const entry of entries) {
if (entry.isFile() && isMarkdownFile(entry.name)) {
// Check for both regular files and symbolic links
if ((entry.isFile() || entry.isSymbolicLink()) && isMarkdownFile(entry.name)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Consider adding a comment here explaining that symbolic links are now supported. Something like:

Suggested change
if ((entry.isFile() || entry.isSymbolicLink()) && isMarkdownFile(entry.name)) {
// Check for both regular files and symbolic links to support command aliasing
if ((entry.isFile() || entry.isSymbolicLink()) && isMarkdownFile(entry.name)) {

This would help future maintainers understand the design decision.


// Mock fs and path modules
vi.mock("fs/promises")
vi.mock("../../roo-config", () => ({
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The mock path here uses ../../roo-config while the existing test file frontmatter-commands.spec.ts uses ../roo-config. Should we make this consistent?

Suggested change
vi.mock("../../roo-config", () => ({
vi.mock("../roo-config", () => ({

})
})
})
})
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great test coverage! This test suite thoroughly covers the symbolic link functionality including edge cases like broken links. Consider also adding a test that explicitly verifies tryLoadCommand works with symbolic links (even though it should work via fs.readFile).

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Aug 21, 2025
@daniel-lxs daniel-lxs moved this from Triage to PR [Needs Prelim Review] in Roo Code Roadmap Aug 22, 2025
@hannesrudolph hannesrudolph added PR - Needs Preliminary Review and removed Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. labels Aug 22, 2025
- Check if symbolic links point to files before processing
- Prevent attempting to read directories as files
- Add test coverage for symlinks pointing to directories
Copy link
Member

@daniel-lxs daniel-lxs left a comment

Choose a reason for hiding this comment

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

LGTM

@daniel-lxs daniel-lxs moved this from PR [Needs Prelim Review] to PR [Needs Review] in Roo Code Roadmap Aug 25, 2025
@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Aug 25, 2025
@daniel-lxs
Copy link
Member

Closing due to security concerns - symbolic links could potentially allow reading files outside the workspace without proper permission grants. This needs security review before implementation.

@daniel-lxs daniel-lxs closed this Aug 25, 2025
@github-project-automation github-project-automation bot moved this from PR [Needs Review] to Done in Roo Code Roadmap Aug 25, 2025
@github-project-automation github-project-automation bot moved this from New to Done in Roo Code Roadmap Aug 25, 2025
@daniel-lxs daniel-lxs deleted the feature/support-symlinks-in-commands branch August 25, 2025 21:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request lgtm This PR has been approved by a maintainer PR - Needs Review size:L This PR changes 100-499 lines, ignoring generated files.

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Create Slash command under .roo/commands with symbolic link

4 participants