feat: add Cursor hooks support to install command#196
Open
imkarrer wants to merge 2 commits intotirth8205:mainfrom
Open
feat: add Cursor hooks support to install command#196imkarrer wants to merge 2 commits intotirth8205:mainfrom
imkarrer wants to merge 2 commits intotirth8205:mainfrom
Conversation
added 2 commits
April 9, 2026 15:21
Install user-level Cursor hooks (~/.cursor/hooks.json + shell scripts) that mirror the three Claude Code hook behaviors: 1. afterFileEdit: auto-update graph via code-review-graph update --skip-flows 2. sessionStart: show graph status via code-review-graph status 3. beforeShellExecution: detect changes before git commit All hooks fail gracefully (exit 0) since they're user-level and will run for all projects. Hooks are installed when running install/init with --platform cursor or --platform all, unless --no-hooks is passed. New functions in skills.py: - generate_cursor_hooks_config(): returns hooks.json config dict - _cursor_hook_scripts(): returns 3 shell script contents - install_cursor_hooks(): writes config + scripts, merges with existing 18 new tests covering config generation, script content, installation, merge behavior, idempotency, and error handling.
Match MCP behavior: only install Cursor hooks when ~/.cursor exists, consistent with how PLATFORMS['cursor']['detect'] gates MCP config.
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.
Summary
~/.cursor/hooks.json+ shell scripts in~/.cursor/hooks/) that mirror all three Claude Code hook behaviors: auto-update graph after file edits, show graph status on session start, and detect changes before git commitsinstall/initwith--platform cursoror--platform all, unless--no-hooksis passedRelated Issues & PRs
--platformfiltering for hooks/skills; this PR respects the sametargetfiltering pattern for Cursor hooksChanges
code_review_graph/skills.pygenerate_cursor_hooks_config()— returns Cursorhooks.jsonconfig dict (version 1) with hooks forafterFileEdit,sessionStart, andbeforeShellExecution_cursor_hook_scripts()— returns 3 shell script contents (crg-update.sh,crg-session-start.sh,crg-pre-commit.sh) that consume stdin per Cursor protocol and emit JSON on stdoutinstall_cursor_hooks()— writes~/.cursor/hooks.json(merging with existing config), creates~/.cursor/hooks/with executable scriptscode_review_graph/cli.pyinstall_cursor_hooks()in_handle_init()when target isallorcursor, gated by--no-hooksloggermodule-level variable for consistent loggingtests/test_skills.pyTestCursorHooksConfig(6 tests): config structure, event types, pathsTestCursorHookScripts(7 tests): script content, shebang, exit codes, commandsTestInstallCursorHooks(5 tests): file creation, executability, merge, idempotency, error handlingHook Behaviors
afterFileEditcrg-update.shcode-review-graph update --skip-flowssessionStartcrg-session-start.shcode-review-graph statusbeforeShellExecution(matcher:^git\s+commit)crg-pre-commit.shcode-review-graph detect-changes --briefTesting
All 48 tests pass (30 existing + 18 new). Ruff and mypy clean.
Checklist (per CONTRIBUTING.md)
feature/cursor-hooksuv run pytest tests/test_skills.py(48/48)ruff checkwith rules E, F, I, N, Wmypy --ignore-missing-imports --no-strict-optional