---
title: prs hook
description: CLI reference for the prs hook command (pre-edit and post-edit actions)
---

# prs hook

Low-level hook handler invoked by AI tool hook systems. Not intended for direct use — configure it via [`prs hooks install`](hooks.md).

## Synopsis

```
prs hook <action> [options]
```

## Description

`prs hook` is the binary entry point called by AI tool hook runners. It reads a JSON payload from stdin, acts on it, writes any messages to stderr, and exits with a code the tool interprets as pass or block.

There are two actions:

| Action      | Triggered by                  | Purpose                                           |
| ----------- | ----------------------------- | ------------------------------------------------- |
| `pre-edit`  | Tool is about to write a file | Block writes to PromptScript-generated files      |
| `post-edit` | Tool has written a file       | Trigger `prs compile` when a `.prs` file is saved |

## Actions

### pre-edit

```bash
prs hook pre-edit
```

Reads a JSON object from stdin describing the file the tool is about to edit. Checks whether that file contains a PromptScript generation marker. If it does, writes an explanatory message to stderr and exits 2. Otherwise exits 0.

**Stdin JSON format**

The exact field names vary by tool. `prs hook pre-edit` understands all of the following:

| Tool        | Stdin field carrying the file path          |
| ----------- | ------------------------------------------- |
| Claude Code | `tool_input.file_path` or `tool_input.path` |
| Factory AI  | `path`                                      |
| Cursor      | `path` or `file`                            |
| Windsurf    | `path` or `filePath`                        |
| Cline       | `path`                                      |
| Copilot     | `parameters.path` or `parameters.file`      |
| Gemini CLI  | `parameters.path`                           |

Unrecognised or missing path fields are treated as "no path" and the hook exits 0 (allow).

**Marker detection**

The hook reads the first 5 lines of the target file looking for the string `Generated by PromptScript`. Files that do not contain this string are passed through without intervention.

**Example stdin (Claude Code)**

```json
{
  "tool_name": "Edit",
  "tool_input": {
    "file_path": "CLAUDE.md",
    "old_string": "...",
    "new_string": "..."
  }
}
```

**Example stderr on block**

```
CLAUDE.md is generated by PromptScript. Edit .promptscript/project.prs instead,
then run `prs compile` (or let the post-edit hook do it automatically).
```

---

### post-edit

```bash
prs hook post-edit
```

Reads a JSON object from stdin describing the file that was just written. If the file has a `.prs` extension, runs `prs compile`. Forwards compiler stdout and stderr to the tool. Always exits 0 — the post-edit hook never blocks a save.

**Stdin JSON format**

Same field mapping as `pre-edit` above.

**Example stdin (Cursor)**

```json
{
  "path": ".promptscript/project.prs"
}
```

**Behaviour for non-.prs files**

If the edited file is not a `.prs` file, the hook exits 0 immediately without running the compiler.

## Exit Codes

| Code | Meaning        | Effect on tool                                     |
| ---- | -------------- | -------------------------------------------------- |
| 0    | Pass / success | Tool proceeds normally                             |
| 1    | Internal error | Tool may log a warning; edit is allowed            |
| 2    | Block          | Tool cancels the edit and shows stderr to the user |

!!! note
Exit code 2 is only used by `pre-edit`. `post-edit` always exits 0.

## Examples

```bash
# Simulate a pre-edit check (Claude Code payload)
echo '{"tool_name":"Edit","tool_input":{"file_path":"CLAUDE.md"}}' | prs hook pre-edit
echo $?   # 2 if CLAUDE.md is generated, 0 otherwise

# Simulate a post-edit trigger
echo '{"path":".promptscript/project.prs"}' | prs hook post-edit
echo $?   # always 0
```

## See Also

- [`prs hooks install`](hooks.md) — scaffold hook configs automatically
- [Hooks Guide](../../guides/hooks.md) — end-to-end setup and troubleshooting
