Hooks in Windows

Do you have some example of how creating a hook in Windows and return 0? My created hooks exit with 1 and the logs are displayed as if the hook had failed.

Also, what would be the best solution for running hooks in a cross platform way? (like running the same command in windows and linux)

2 Likes

On Windows, Cursor hooks are just external commands defined in hooks.json that must:

  1. start correctly in whatever shell Cursor uses, and
  2. print a valid JSON object to stdout, then exit with code 0.

To create cross platform hooks use Cursor on Windows through WSL as that is Linux.

Minimal “return 0” hook on Windows using PowerShell (not WSL)

The safest pattern on Windows right now is to call PowerShell explicitly from your hook, and have the script emit the JSON and then exit 0.

hooks.json (user-global or project-level):

```jsonc
{
  "version": 1,
  "hooks": {
    "beforeSubmitPrompt": [
      {
        "command": "powershell -NoProfile -ExecutionPolicy Bypass -Command \"Write-Output '{\\\"continue\\\":true,\\\"permission\\\":\\\"allow\\\"}'\""
      }
    ]
  }
}
```

This command:

  • Uses PowerShell regardless of your default terminal profile.
  • Writes a single JSON line to stdout.
  • Lets PowerShell exit with code 0 (unless something fails), which Cursor interprets as a successful hook.

If you prefer a .ps1:

```powershell
# .cursor-hooks.ps1
Write-Output '{\"continue\":true,\"permission\":\"allow\"}'
exit 0
```

and in hooks.json:

```jsonc
{
  "version": 1,
  "hooks": {
    "beforeSubmitPrompt": [
      {
        "command": "powershell -NoProfile -ExecutionPolicy Bypass -File .cursor-hooks.ps1 beforeSubmitPrompt"
      }
    ]
  }
}
```

Why you see “exit code: 1” even with trivial hooks

Several current Windows-specific issues can make even a trivial hook “fail” with exit code 1 even though the command works in a regular terminal:

  • Shell mismatch / PowerShell snippet sent to Bash:
    If your integrated terminal profile is Git Bash, Cursor’s internal PowerShell-based hook bootstrap is sent to Bash and explodes with syntax errors like [Convert]::FromBase64String, causing an exit 1 before your script runs.

  • Launcher bug for hooks on Windows:
    There are cases where a minimal echo '{\"continue\":true,...}' hook works in a normal terminal but fails from Cursor with a low-level error and exit code 1. That failure happens in Cursor’s hook launcher layer, not in the script.

  • Project-level hooks not executing / no output:
    Hooks are recognized and “processed” but don’t actually run, yielding no stdout and appearing as failed.

Given that, a few pragmatic steps:

  1. Force PowerShell in the command
    Always start your hook with powershell -NoProfile -ExecutionPolicy Bypass ... instead of relying on the default terminal profile.

  2. Return JSON and exit 0 explicitly

    • JSON to stdout (single object, no extra noise): e.g. {"continue":true,"permission":"allow"}.
    • Explicit exit 0 at the end of the script, especially in .ps1 or .bat.
  3. Check Cursor’s Hooks output panel

    • View → Output → select “Hooks”.
    • If you see PowerShell/Bash syntax errors or low-level launcher errors, the launcher is failing before your script; in that case your code is fine and you’re hitting a Cursor bug.
  4. Work around known Windows bugs

    • Temporarily use user-global hooks instead of project-level if the latter are flaky in your build.
    • Try switching Cursor’s integrated terminal profile to PowerShell in settings, at least while debugging hooks.