fix(file): follow symbolic links in findFilesByGlobs - #1802
Merged
Conversation
Symlinked skill directories and files were silently ignored because globbySync ran with followSymbolicLinks: false. Setting it to true lets users centralize shared skills in one location and reference them via symlinks across multiple directories without duplication.
- Add inline comment explaining why followSymbolicLinks: true is safe for callers and how it differs from git-client.ts (which skips symlinks during remote fetch for unrelated reasons) - Fix misleading test description comments - Expand the Symlinks-and-trust section in separate-input-root.md to explain that file discovery now follows symlinks and what the trust boundary is
Contributor
|
@saitota The CI checks on this pull request are currently failing. Please review the failing checks and push a fix. If you need help, leave a comment and a maintainer will follow up. |
Owner
|
@saitota Thank you! |
rudironsoni
pushed a commit
to rudironsoni/rulesync
that referenced
this pull request
Jun 13, 2026
… model Follow-ups from PR dyoshikawa#1802 review (issue dyoshikawa#1808): - Deduplicate findFilesByGlobs results by real path so directory symlink cycles (which globby follows up to the kernel ELOOP limit) no longer yield ~40x duplicated entries that get read and re-emitted (dyoshikawa#1) - Rewrite the findFilesByGlobs comment: git-client.ts skips symlinks as a security hardening for untrusted remote content (commit 51bf044), not because a bare clone makes them meaningless — it does a non-bare checkout (dyoshikawa#2) - Document the intentional trade-off of not enforcing realpath containment (it would break the issue dyoshikawa#1707 shared-file use case); record the decision in the comment and docs rather than adding a containment check (dyoshikawa#3) - Add a skills-processor test loading a symlinked skill directory (dyoshikawa#4) - Guard symlink unit tests with skipIf(win32) since fs.symlink needs admin / Developer Mode on Windows (dyoshikawa#5) - Add a feature-wide Symlinks section to docs/reference/file-formats.md and cross-link it from the input-root guide; sync skills/rulesync (dyoshikawa#6) Closes dyoshikawa#1808 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #1707
Summary
followSymbolicLinks: falsetotrueinfindFilesByGlobsScope
findFilesByGlobsis the single discovery function used by all features — rules, commands, subagents, hooks, and skills. This one-line fix covers every feature, not just skills.Two distinct symlink scenarios are resolved:
.rulesync/was not detected at all (original report by @mocyuto)Design note
The alternative — preserving the symlink itself in the output — was considered but does not fit the architecture.
findFilesByGlobsfeeds intoAiDir.collectOtherFiles, which reads every file as aBufferand re-writes it as a plain file viawriteFileContent. There is no layer in the pipeline that carries symlink metadata, so the output is always a regular file regardless. Following and copying is the natural behavior here.Test plan
pnpm vitest run src/utils/file.test.ts— added two tests: symlinked file is found, symlinked directory and files inside it are found