Cursor hooks: verify the event names and output schema against the current Cursor hooks documentation

Author: OthmanAdiCreated Sep 17, 2026Updated Sep 17, 2026
Labelsbughelp wanted

Problem

The Cursor hook configuration in this repository (.cursor/hooks.json and .cursor/hooks.windows.json) was written against an early hooks preview. Cursor's current documentation at https://cursor.com/docs/agent/hooks describes a different surface, and two of our four hooks do not exist in that shape:

  • There is no userPromptSubmit event. The prompt-time event is beforeSubmitPrompt, and its output is only continue and user_message; it cannot inject context. The events that can inject context are sessionStart (additional_context, added to the conversation's initial context) and postToolUse (additional_context, injected after the tool result).
  • preToolUse answers with permission ("allow" or "deny"), not decision. The docs state that invalid JSON or a response that does not match the hook's schema blocks the action, so {"decision": "allow"} may block instead of allowing.
  • stop still answers with followup_message, which matches our stop hooks. sessionEnd, preCompact (user_message output) and afterFileEdit exist as well.

This was not verified against a running Cursor build, only against the documentation as of 2026-09-17. Pre-existing since the hooks were added in v2.23.1; PR #251 (Windows named-plan resolution) does not change the event names or the output shape, and its shared resolve-plan-context.ps1 helper is what a corrected set of hooks would reuse.

What a fix looks like

  1. Confirm the behaviour in a current Cursor build: does userPromptSubmit fire at all, and does {"decision": "allow"} from preToolUse block the tool?
  2. If the documentation is right, move the plan injection to sessionStart (additional_context with the same framed plan block the other routes inject), keep the write reminder as postToolUse additional_context, keep stop with followup_message, and consider preCompact for the flush-progress reminder. Make preToolUse return {"permission": "allow"} or drop it (Cursor's preToolUse cannot inject context, so the 30-line recitation has no channel there).
  3. Keep both twins (.sh and .ps1) in step and keep PLANNING_DISABLED=1, PLAN_ID, PWF_PLAN_ROOT and the fail-closed rules from resolve-plan-context.ps1.
  4. Update docs/cursor.md and the tests under tests/test_cursor_*.py to the confirmed schema.

Scope

Cursor only. No other host reads these files. Anyone with a current Cursor install who can run the two checks in step 1 would unblock this; a comment with the observed behaviour is enough to start.

Source: OthmanAdi/planning-with-files