Skip to content

fix(setup): recognize plugin hooks reported through a symlinked CODEX_HOME - #134

Open
behruznassre wants to merge 1 commit into
sendbird:mainfrom
behruznassre:fix/hook-trust-symlinked-plugin-root
Open

behruznassre wants to merge 1 commit into
sendbird:mainfrom
behruznassre:fix/hook-trust-symlinked-plugin-root

Conversation

@behruznassre

Copy link
Copy Markdown
Contributor

Summary

  • pathIsInsideRoot() resolves symlinks on both ROOT_DIR and the hook's sourcePath before the containment check, so setup now counts hooks that Codex reports through a symlinked CODEX_HOME
  • it reuses canonicalPath from scripts/lib/codex-paths.mjs (now exported), the same realpathSync.native-with-fallback that resolvePluginCacheInstallInfo already uses
  • hooks whose real file is outside the plugin root are still rejected

Root cause

path.resolve does not follow symlinks. When a second profile's plugins dir links to the shared cache, hooks/list reports <alt CODEX_HOME>/plugins/cache/sendbird/cc/<ver>/hooks/hooks.json while the companion runs from the canonical cache path. The lexical path.relative check fails for every cc hook, found is 0, and setup tells the user to trust hooks that /hooks already shows as trusted.

Validation

  • new integration test setup recognizes trusted plugin hooks reported through a symlinked plugin root: the fake hooks/list reports three trusted cc hooks through a symlink to PROJECT_ROOT, plus one untrusted cc@sendbird hook from a real file outside it
    • on main (19e5651) it fails with found: 0, the same output as the real installation
    • with the fix it passes with found: 3 ("already trusted (3)"), and no hooks.state write happens, so the outside-root hook is not trusted
  • npm run check: unit 514 passed, integration 46 passed, Codex E2E 23 passed; lint, typecheck, version-sync and changelog OK

Fixes #133

🤖 Generated with Claude Code

…_HOME

pathIsInsideRoot compared ROOT_DIR with path.resolve(sourcePath), which does
not follow symlinks. When a second Codex profile links its plugins dir to the
shared cache, hooks/list reports the alias path, every cc hook fails the
containment check, and setup reports found=0 and asks the user to trust hooks
that are already trusted.

Canonicalize both sides with the existing canonicalPath helper from
codex-paths.mjs. Hooks from real files outside the plugin root stay rejected.

Fixes sendbird#133

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-12T18:55:06.399445Z 00c7558 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 00c75583ca

ℹ️ 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".

// An alternate CODEX_HOME whose plugins dir symlinks to the shared cache:
// hooks/list reports the alias path, the companion runs from the real path.
const aliasRoot = path.join(testEnv.rootDir, "alias-plugin-root");
fs.symlinkSync(PROJECT_ROOT, aliasRoot, "dir");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use a junction for the Windows directory alias

On native Windows without Developer Mode or CreateSymbolicLink privilege, fs.symlinkSync(..., "dir") throws EPERM before this test enters its try/finally, so the repository-required npm run check now fails on an otherwise supported platform and leaves the temporary test environment behind. Use a junction on win32, as the existing cross-platform symlink tests do.

AGENTS.md reference: AGENTS.md:L3-L3

Useful? React with 👍 / 👎.

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.

setup falsely reports missing hooks when an alternate CODEX_HOME symlinks the plugin cache

1 participant