Skip to content

fix: resolve relative symlinks in rules files using realpath of parent directory#442

Open
p12tic wants to merge 1 commit into
Zoo-Code-Org:mainfrom
p12tic:fix-rules-symlinks
Open

fix: resolve relative symlinks in rules files using realpath of parent directory#442
p12tic wants to merge 1 commit into
Zoo-Code-Org:mainfrom
p12tic:fix-rules-symlinks

Conversation

@p12tic
Copy link
Copy Markdown
Contributor

@p12tic p12tic commented Jun 1, 2026

Related GitHub Issue

Closes: #440

Description

When a .roo/rules directory is itself a symlink to an external directory, and files inside are relative symlinks (e.g., ../1-project.txt), the symlink targets were incorrectly resolved relative to the access path instead of the real filesystem path.

Use fs.realpath() on the symlink's parent directory before resolving relative targets, matching how the OS resolves relative symlinks.

Test Procedure

Reproduced the filesystem structure shown in the issue, verified that issue exists by viewing "Modes -> Preview system prompt". The issue is reproducible before the bug fix and no longer is reproducible after the bug fix.

Pre-Submission Checklist

  • Issue Linked: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
  • Scope: My changes are focused on the linked issue (one major feature/fix per PR).
  • Self-Review: I have performed a thorough self-review of my code.
  • Testing: New and/or updated tests have been added to cover my changes (if applicable).
  • Documentation Impact: I have considered if my changes require documentation updates (see "Documentation Updates" section below).
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

Screenshots / Videos

None.

Documentation Updates

None.

Additional Notes

None.

Get in Touch

povilas_78868

Summary by CodeRabbit

  • Bug Fixes

    • Improved symbolic link resolution to correctly handle relative symlinks by using the canonical parent directory path, with a graceful fallback when canonicalization fails.
  • Tests

    • Added coverage for symlink resolution including relative targets and fallback behavior (platform-specific skips where applicable).

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

resolveSymLink now canonicalizes the symlink's parent directory via fs.realpath (with a fallback) before resolving relative symlink targets. Tests were added to mock realpath success and failure and assert loadRuleFiles reads the correct resolved paths.

Changes

Relative Symlink Resolution

Layer / File(s) Summary
Parent directory canonicalization in resolveSymLink
src/core/prompts/sections/custom-instructions.ts
resolveSymLink obtains the canonical path of the symlink's parent directory via fs.realpath (falls back to the original parent on error) and resolves the symlink target relative to that resolved parent.
Test mocks and validation for symlink resolution
src/core/prompts/sections/__tests__/custom-instructions.spec.ts
Tests add a realpathMock wired into the mocked fs/promises and include two non-Windows test cases: one asserting resolution uses the parent's realpath, and one asserting fallback behavior when realpath fails.

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰
Symlinks twist through root and sod,
Realpath hops in, clears the fog.
Canon paths guide each little hop,
No more files that silently stop.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: fixing relative symlink resolution in rules files using realpath of the parent directory.
Description check ✅ Passed The description follows the template structure with all required sections: linked issue, implementation details, test procedure, and completed checklist items.
Linked Issues check ✅ Passed The PR directly addresses issue #440 by implementing fs.realpath() on the symlink's parent directory before resolving relative targets, which resolves the reported bug where relative symlinks in symlinked rules directories were ignored.
Out of Scope Changes check ✅ Passed All changes are focused on fixing the symlink resolution issue in rules files; changes to custom-instructions.ts implementation and test coverage are directly related to resolving issue #440.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/core/prompts/sections/__tests__/custom-instructions.spec.ts

ESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox.

src/core/prompts/sections/custom-instructions.ts

ESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.


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.

@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 1, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

…t directory

When a .roo/rules directory is itself a symlink to an external directory,
and files inside are relative symlinks (e.g., ../1-project.txt), the
symlink targets were incorrectly resolved relative to the access path
instead of the real filesystem path.

Use fs.realpath() on the symlink's parent directory before resolving
relative targets, matching how the OS resolves relative symlinks.
@p12tic p12tic force-pushed the fix-rules-symlinks branch from 932ef72 to 729f917 Compare June 2, 2026 05:43
Copy link
Copy Markdown
Contributor

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/core/prompts/sections/__tests__/custom-instructions.spec.ts`:
- Around line 1730-1734: The test's expectation must match the mocked
path.resolve behavior: update the assertion that checks statCalls (from
statMock.mock.calls mapped to strings) to expect
"/project/.roo/rules/../1-project.txt" instead of "/project/.roo/1-project.txt"
since the mocked path.resolve does not collapse ".."; keep the negative
assertion that "/external/1-project.txt" is not present. Locate the assertions
around the statCalls mapping in the custom-instructions.spec.ts test and change
the expected string accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4be1a6cf-3927-4a16-aa22-75961ed357f8

📥 Commits

Reviewing files that changed from the base of the PR and between 932ef72 and 729f917.

📒 Files selected for processing (2)
  • src/core/prompts/sections/__tests__/custom-instructions.spec.ts
  • src/core/prompts/sections/custom-instructions.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/core/prompts/sections/custom-instructions.ts

Comment thread src/core/prompts/sections/__tests__/custom-instructions.spec.ts
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.

[BUG] Relative symlinks in rules files not resolved correctly when accessed through a symlinked directory

1 participant