Skip to content
DOCS

Hook reference

Loupe uses only documented hooks. There is no proxy in front of the model, no injected extension and no accessibility permission.

TOOLEVENTWHAT IT SENDSWHAT IT RETURNS
Claude CodeUserPromptSubmitPrompt text (redacted), repo, branch, commit, model, session idhookSpecificOutput.additionalContext — the nudge, when one is due
Claude CodeSessionStartSession id, working directory, agent versionNothing
Claude CodeStopTurn outcome and durationNothing
Claude CodeSessionEndSession close, final commit and PR if one existsNothing
CursorbeforeSubmitPromptPrompt text (redacted), repo, branch, commit, model, conversation idcontinue: false — only to refuse a prompt carrying a credential
CursorsessionStartConversation id, workspace rootNothing
CursorstopTurn outcomefollowup_message — the nudge, when one is due
CodexUserPromptSubmitPrompt text (redacted), repo, branch, commit, model, session idhookSpecificOutput.additionalContext — the nudge, when one is due
CodexSessionStartSession id, working directory, agent versionNothing
CodexStopTurn outcome and durationNothing
CodexSessionEndSession close, final commit and PR if one existsNothing

Why a bad network cannot stall your editor

Claude Code caps UserPromptSubmit at 30 seconds, and Loupe asks for far less than that. Each hook redacts the prompt, appends it to an on-disk spool, and only then tries to upload with a 2.5-second ceiling. A failed or slow upload leaves the turn on the spool for the next hook to carry, so the worst case is a missing nudge rather than a stalled prompt.

Every hook exits 0 whatever happens. A non-zero exit is a signal to the editor — Claude Code reads 2as “block this prompt” — so a bug in telemetry must never be able to stop somebody working. Cursor’s hooks are registered with failClosed: false for the same reason.

Timeouts are ours to set, not the defaults. Codex allows 600 seconds on most events and caps SessionEnd at three; Loupe asks for ten on a prompt and less elsewhere, so a wedged agent is a pause somebody notices rather than one they wait out.

How a nudge gets back in

The server answers each upload with any verdict it has for that session, and the agent caches it on disk. The next hook returns it synchronously, which is why coaching lands on the turn after the one that earned it. A verdict is shown once and then cleared, so a nudge never repeats itself into being ignored.

UserPromptSubmit response
{
  "hookSpecificOutput": {
    "hookEventName": "UserPromptSubmit",
    "additionalContext": "Loupe: this is turn 5 on the same task. Name the file and the done-condition."
  }
}

Where a nudge appears in Cursor

Cursor renders nothing a hook returns on submit, so a nudge that only came back through the hook would never be seen. When the workspace enables desktop nudges the agent also raises a native notification — Notification Center, notify-send, or a Windows toast — fired and forgotten so it cannot delay a prompt. Claude Code and Codex both show the nudge inline, as developer context on the next turn.

Refusing a credential

When block credential leaks is on, a prompt carrying an AWS key, a provider token or a private key is stopped on the laptop and never sent. The developer sees which kind of secret was found; Loupe records that it happened, and never the secret. Lower-severity matches — customer identifiers and your own regexes — are redacted rather than refused, because they are not worth interrupting somebody for.

Codex asks before it runs anything

Codex will not run a command hook it has not been shown. After the entries are written, each developer runs /hooks in Codex once and trusts the Loupe rows. Until they do, Codex prints a review warning at startup and skips the hooks — Coverage reports that device as untrusted rather than as broken, because the files are exactly where they should be.

Trust is recorded against a hash of the hook definition, so an agent upgrade that rewrites the command asks again. Loupe keeps the committed command stable for this reason: it resolves the runtime through the git root rather than embedding a version, so a new build replaces the artefact without touching the line Codex hashed.

The way around the prompt is not to work around it. Hooks delivered as managed configuration — MDM, cloud policy, or a system requirements.toml — are trusted by policy, cannot be switched off from the hook browser, and need nothing from the developer. That is the only zero-touch route, and the reason Codex is opt-in rather than on by default.

Tamper detection

Every heartbeat carries a SHA-256 of each hook file. If an entry disappears or changes, the device shows as tampered on the Coverage page and, if enabled, raises an alert. Nothing is silently reinstalled — an admin decides.