Skip to content

Capability Matrix

Events

All five universal events are supported on all three hosts. Cursor's host-specific events normalize upward into the unified shape.

Unified eventClaudeCursorCodex
SessionStartSessionStartsessionStartSessionStart
PreToolUsePreToolUsepreToolUse, beforeShellExecution, beforeMCPExecution, beforeReadFilePreToolUse
PostToolUsePostToolUsepostToolUse, afterShellExecution, afterMCPExecution, afterFileEditPostToolUse
UserPromptSubmitUserPromptSubmitbeforeSubmitPromptUserPromptSubmit
StopStopstopStop

Cursor's specific events fold into PreToolUse / PostToolUse with a unified event.tool value:

Cursor eventUnified event.eventUnified event.tool
beforeShellExecutionPreToolUseBash
afterShellExecutionPostToolUseBash
beforeMCPExecutionPreToolUseMCP
afterMCPExecutionPostToolUseMCP
beforeReadFilePreToolUseRead
afterFileEditPostToolUseEdit

Codex's apply_patch is aliased to Edit.

Response fields

The unified IHookResponse:

ts
interface IHookResponse {
  decision?: "allow" | "deny" | "ask";
  reason?: string;
  user_message?: string;
  modified_input?: Record<string, unknown>;
  additional_context?: string;
}
FieldClaudeCursorCodex
decision: "allow"yesyes (permission events; continue: true on beforeSubmitPrompt)yes
decision: "deny"yes (exit 2)yes (exit 2)yes (exit 2)
decision: "ask"yesdowngraded to deny on Cursor 2.4.21+ (still broken on 3.2.16; opt out via cursorAskFallback: "ask")yes
reasonpermissionDecisionReason / reasonagent_message on permission events; dropped on beforeSubmitPromptpermissionDecisionReason / reason
user_messagedropped + warnuser_message on permission eventsdropped + warn
additional_contextSessionStart, PreToolUse, UserPromptSubmit, PostToolUsesessionStart, postToolUse; dropped on beforeSubmitPromptSessionStart, UserPromptSubmit, PostToolUse; systemMessage on Stop
modified_inputPreToolUse (as updatedInput); dropped + warn elsewherepreToolUse (as updated_input); dropped on specific eventsdropped + warn

Cursor beforeSubmitPrompt

Cursor's prompt-submit event response shape is allow/deny only:

jsonc
{
  "continue": false,
  "user_message": "secrets detected; not submitting"
}

It cannot inject additional_context for the model. If your handler returns additional_context on UserPromptSubmit:

  • Claude: surfaces via hookSpecificOutput.additionalContext
  • Cursor: dropped; bridge logs the drop to stderr
  • Codex: surfaces via hookSpecificOutput.additionalContext

For per-prompt context injection on Cursor, move the logic to SessionStart (project-level briefing) or PostToolUse (between turns).

Cursor permission: "ask" regression

A Cursor regression that started in 2.4.21 and is still present on 3.2.16 (last verified). The visible behavior changed across the regression window:

  • 2.4.21 through 2.x: ask is silently treated as deny. The agent sees the command refused with no explanation.
  • 3.x (verified through 3.2.16): ask is silently treated as allow. The command runs without ever prompting the user.

Either way the hook author's intent ("ask the user before running this") is dropped on the floor. The adapter reads cursor_version from _native and downgrades decision: "ask" to "deny" with a stderr warning, because that's the safer default on both eras.

To opt out:

ts
await run(hooks, { cursorAskFallback: "ask" });

"ask" will pass through to Cursor unchanged, where it will still be silently mishandled per the table above. Use this only if you'd rather Cursor's broken behavior surface than have the bridge override it.

Pre-2.4.21 Cursor is unaffected: ask passes through and worked as expected.

Exit codes

All three hosts agree:

CodeMeaning
0proceed (allow / ask / no decision)
2block (decision: "deny")
1bridge error (parse, unknown host, handler exception)

Host resolution

run() resolves the host in this order:

  1. Explicit host option to run(hooks, { host }).
  2. --host <id> token in argv. The install command writes this into every generated config.
  3. Stdin scoring (see Host Detection).

If none resolve, run() writes a stderr error and exits 1. There is no silent default.

Not affiliated with Anthropic, Anysphere, or OpenAI. Supported by LogicStar AI.