fix(cursor): manage hooks declaratively, fix GUI PATH timeout - #1839
Conversation
Cursor on macOS launches with a minimal PATH that excludes ~/.cargo/bin, ~/.nix-profile/bin, /opt/homebrew/bin, etc. The previous hooks.json used bare `git-ai`, so hooks failed with "command not found" and Cursor reported timeouts. - Restructure config/cursor/ to mirror config/codex/ (hooks/ subdir, scripts deployed via home.file) - Add with-env.sh wrapper that bootstraps PATH for shared scripts - Add cursor-flavored security.sh, notify.sh, pushover.sh - Wire events: beforeShellExecution (security, block-git-push, block-gh-settings, notify, pushover), afterFileEdit + beforeSubmitPrompt (git-ai checkpoint, absolute path), stop (notify, pushover)
|
|
Warning Gemini encountered an error creating the review. You can try again by commenting |
|
You do not have enough credits to review this pull request. Please purchase more credits to continue. |
📝 WalkthroughWalkthroughThis PR establishes a Cursor editor hook system that enforces pre-execution security checks, sets up environment variables for GUI app compatibility, and delivers work-status notifications through local and remote notification services. ChangesCursor Hook System with Security and Notifications
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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 `@config/cursor/hooks/notify.sh`:
- Around line 20-22: The early return in notify.sh currently exits when
PUSHOVER_API_TOKEN and PUSHOVER_USER_KEY are set, which silences local
notifications even if the Pushover client is missing; change the conditional so
it also verifies the actual notifier exists (e.g., check for the pushover-notify
executable with command -v or which) and only exit when both env vars are
present AND the pushover-notify command is available, leaving local
notifications as a fallback otherwise.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 06da0fea-d06c-4394-9edf-37c162825b11
📒 Files selected for processing (6)
config/cursor/default.nixconfig/cursor/hooks.jsonconfig/cursor/hooks/notify.shconfig/cursor/hooks/pushover.shconfig/cursor/hooks/security.shconfig/cursor/hooks/with-env.sh
There was a problem hiding this comment.
1 issue found across 6 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Three identical copies of rtk-rewrite.sh (claude/codex/copilot) and three near-identical copies of security.sh (codex/copilot/cursor) collapsed into one each under config/shared/hooks/. Claude's settings.json-driven security.sh stays separate since it has a different runtime model. - Move rtk-rewrite.sh to shared/hooks; delete agent-specific copies - Move security.sh to shared/hooks; extend extraction to include cursor's top-level .command; add PATH bootstrap so cursor GUI launches work - Add PATH bootstrap to shared block-git-push.sh and block-gh-settings.sh for the same reason; drop cursor's with-env.sh wrapper - Update settings.json/hooks.json/config.json to reference shared paths - Remove home.file declarations that deployed per-agent copies - Update sync-rtk-rewrite.sh and sync-codex-security.sh to target shared - Rename spec/codex_security_spec.sh to shared_security_spec.sh - Delete spec/codex_rtk_rewrite_spec.sh (redundant with rtk_rewrite_spec) - Update coverage_spec.sh entries
- security.sh: fail closed when jq is unavailable (was fail-open, a security antipattern — a hook that can't parse its input must block) - security.sh: replace xargs trim with pure-bash trim so deny patterns containing quotes/backslashes aren't reinterpreted - cursor notify/pushover: add /usr/sbin to PATH so scutil resolves and HOSTNAME reflects ComputerName instead of kebab-case hostname fallback - cursor notify/pushover stop handler: background the work since Cursor doesn't honor async on hooks; previously held the agent loop open for up to ~6s after every session - cursor notify: only suppress local notifications when pushover-notify binary is actually available, not just env vars set
Keeps the PATH string identical across all 5 hook scripts so future divergence is easier to spot. None of the shared scripts call scutil today, but the consistency matters more than the bytes saved.
Summary
config/cursor/to mirror theconfig/codex/pattern: ahooks/subdirectory with scripts deployed viahome.file, and an activation script that copieshooks.jsoninto~/.cursor/.hooks.jsonreferenced baregit-ai, but Cursor on macOS launches GUI apps with a minimal PATH that excludes~/.cargo/bin,~/.nix-profile/bin,/opt/homebrew/bin, etc. The binary wasn't found, so Cursor reported the hook as failing/hung.security.sh,notify.sh,pushover.sh, and awith-env.shPATH-bootstrap wrapper for invoking the shared hooks.Event wiring
beforeShellExecutionsecurity.sh,block-git-push.sh(viawith-env.sh),block-gh-settings.sh(viawith-env.sh),notify.sh,pushover.shafterFileEditgit-ai checkpoint cursor(absolute path)beforeSubmitPromptgit-ai checkpoint cursor(absolute path)stopnotify.sh,pushover.shWhy this fixes the hang
Every command now uses absolute
$HOME/...paths or routes throughwith-env.sh, which exports a full PATH (~/.cargo/bin,/etc/profiles/per-user/...,/opt/homebrew/bin, ...) so Cursor's minimal GUI env can resolvegit-ai,jq,gitleaks, andgit.Verified under
env -i PATH=/usr/bin:/bin:0sudo ls) emit cursor's blocking JSON ({permission: "deny", user_message, agent_message}) and exit2What's intentionally NOT ported
secret-guard.sh— Cursor has no pre-write hook (afterFileEditis non-blocking).rtk-rewrite.sh— Cursor's blocking output schema has no "modified command" field.dcg— Cursor'sbeforeShellExecutioninput schema isn't compatible with dcg's expected input.Test plan
notify.sh/pushover.shfire.git-ai checkpoint cursorruns.home-manager switch(ordarwin-rebuild switch) and confirm files match the manually-deployed copies in~/.cursor/.Summary by cubic
Manage Cursor hooks declaratively and fix macOS GUI PATH timeouts so hooks run reliably. Also consolidates
rtk-rewrite.shandsecurity.shintoconfig/shared/hooks/for Codex, Copilot, and Cursor, and switchesgit-aicalls to absolute paths.Bug Fixes
$HOME/...commands and a PATH bootstrap for GUI launches./usr/sbin) across sharedsecurity.sh,block-git-push.sh, andblock-gh-settings.shsoscutilresolves in notifications and scripts work consistently from Cursor; stop handlers now run in the background.pushover-notifyis actually available.security.shnow fails closed ifjqis missing and uses pure-bash trimming to avoidxargsquirks.New Features
rtk-rewrite.shandsecurity.shintoconfig/shared/hooks/; updated Claude/Codex/Copilot/Cursor to reference shared paths and removed per‑agent copies where applicable.home.fileand wiredbeforeShellExecution,afterFileEdit,beforeSubmitPrompt, andstop; addedconfig/cursor/hooks/notify.shandpushover.shfor stop events and risky‑command alerts.Written for commit f973a29. Summary will update on new commits. Review in cubic