Repository navigation
relay-guard: work when the plugin is reached through a symlinked folder - #57
darko-mijic wants to merge 1 commit into
Conversation
When Claude Code installs the plugin through a symlinked config folder, it runs the hook and the relay names the companion through the symlink, while Node gives the hook module its real path. The hook's entry check then never ran main(), and start --from-relay failed with 'the hook did not run'. Both the entry check and the companion match now compare paths with symlinks resolved. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cw9dodEyoUpvSEJQUeF1FJ
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Resolve paths for guard checks plugins/relay/scripts/hooks/relay-guard.mjs, tests/relay-guard.test.mjs |
The guard resolves paths before comparing companion and direct-execution script paths. The test checks that a symlink-launched hook parses the companion command and denies sw_vers -productVersion with exit status 0. |
Priority:
Estimated code review effort: 2 (Simple) | ~8 minutes
Change: Bug fix
Merge Risk: 
Minimal · up to 40c09
-
The symlink-aware path comparisons and test coverage address the stated behavior without an identified remaining merge risk.
Pre-merge checks: 
4 · 
1
-
Failed checks: 1 warning Passed checks: 4 passedFull details: Docstring Coverage
-
Explanation
Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 2 functions across 2 files.
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
-
Finishing Touches: 💡 1
-
📝 Generate docstrings: 💡
-
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
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.
A rabbit checks the paths at night
Through links, the guard sees each one right
The companion command comes through
The hook denies the tested call too
Then hops away beneath the moon
Comment @coderabbitai help to get the list of available commands.
What broke
A plugin can be installed through a symlinked Claude Code config folder, so its recorded install path runs through the symlink. Claude Code then runs
relay-guard.mjsthrough that path, and the relay names the companion through it too (node "<symlinked root>/scripts/companion.mjs" start --from-relay). Node, though, gives the hook module its real path inimport.meta.url.Two comparisons in
relay-guard.mjsmixed the two:process.argv[1]againstimport.meta.url) was false, somain()never ran and thePreToolUsehook did nothing at all;path.resolve(script) !== COMPANION) would not have recognised the start command either.Every
relay:jobthen failed at once:start --from-relay needs --relay-transcript and --relay-agent, which the relay hook adds. The hook did not run.The stop-time review gate was unaffected, because its own entry check already resolves both paths.The fix
Both comparisons resolve symlinks first (
fs.realpathSync, falling back topath.resolvefor a path that doesn't exist).Tests
a plugin reached through a symlinked folder: the hook runs, and knows the companion by either path. It parses a start command named through a symlink, and runs the hook as a process through the symlink, expecting its deny for a stray Bash command. It fails without the fix and passes with it.npm test: 598 pass, 0 fail, 1 skipped.The CHANGELOG entry goes in with the next release, as usual.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Cw9dodEyoUpvSEJQUeF1FJ
Summary by CodeRabbit


Confidence Score: 5/5
Safe to merge: the symlink regression, the affected test suite, and additional alias checks passed.Summary
Fixes
relay-guard.mjswhen the plugin is reached through a symlinked folder.No actionable issues found. The change is safe to merge based on the affected behavior checked.
Reviews (1) · Last reviewed commit: "relay-guard: compare resolved paths, so ..." · Reviewed by Greptile