Skip to content

Grok agent hooks

Project lifecycle hooks for Grok coding sessions. They keep agent turns formatted and checked, format files as they are edited, and require human approval before deploys or other high-side-effect scripts.

Hooks live under .grok/hooks/ and are version-controlled with the repo.

Enable once per machine

Project hooks only run after the folder is trusted:

text
/hooks-trust

Or launch with --trust. Trust is stored in Grok’s folder-trust store (same gate as repo-local MCP).

Command / UIPurpose
/hooksExtensions modal → Hooks tab
r (in Hooks tab)Reload hooks from disk after edits
SpaceEnable / disable a single hook
/hooks-listList hooks loaded this session

If hooks never fire: check trust, reload with r, and confirm the files under .grok/hooks/ are present.

Layout

.grok/hooks/
  post-agent-quality.json   # Stop
  format-on-edit.json       # PostToolUse
  pre-tool-safety.json      # PreToolUse
  bin/
    post-agent-quality.sh
    format-on-edit.sh
    pre-tool-safety.sh

JSON registers the event; scripts do the work. Paths in command are relative to the JSON file (so bin/… resolves correctly).

Stop — post-agent quality gate

When: the agent finishes a turn (reason: end_turn). Session-end observe fires are ignored.

Runs a project script chain, typically:

  1. pnpm run post-agent — Prettier write → ESLint → tsc --noEmit → unit tests
  2. A changed-files dead-code / complexity audit vs merge-base

On failure: the stop is blocked and truncated log output is fed back to the model so it can fix issues and continue (Grok caps stop-hook continuations per turn).

Timeout: 600 seconds (format + lint + types + tests can take a while on a cold cache).

Manual equivalent: run the same scripts locally.

PostToolUse — format on edit

When: a file edit tool completes (search_replace, Write, Edit, …).

Runs: prettier --write on that file only (via pnpm exec prettier).

Skips:

  • Missing paths
  • Non-source extensions
  • Vendor / build / generated paths (node_modules/, .next/, dist/, lockfiles, typegen dumps)

Timeout: 30 seconds. Failures are silent (do not block the agent).

PreToolUse — shell safety and deploy approval

When: a shell tool is about to run (run_terminal_command / Bash).

Hard deny (no dialog)

These patterns are always blocked:

  • rm -rf / or rm -rf ~ (and similar)
  • git push --force / -f
  • git reset --hard
  • git clean -f / -fd
  • mkfs, dd if=, classic fork-bomb

The hook returns decision: deny and the command does not run.

User approval (macOS dialog)

These require an Allow / Deny dialog (default Deny, 120s timeout):

KindExample commands
Production deploy (Vercel)pnpm run deploy, vercel --prod, vercel deploy …
Nested app deployPackage-specific deploy scripts
Data seed / write scriptspnpm run *:seed-*, node scripts/seed-…

On Allow, the command proceeds. On Deny or timeout, the agent is told the user refused.

Non-GUI environments (no osascript) fail closed — side-effect commands are denied with instructions.

One-off override

Skip the dialog only when you intentionally want that:

bash
ALLOW_DEPLOY=1 pnpm run deploy
GROK_HOOK_ALLOW_SIDE_EFFECTS=1 pnpm run some-side-effect

The hook recognises those assignments:

  • On the hook process environment, or
  • In the command string (so ALLOW_DEPLOY=1 pnpm run deploy works even though the prefix env is not visible to the hook process)

Prefer clicking Allow for normal deploys.

What is not hooked

Script / actionWhy
dev, nested servers, docs, watchLong-running servers
e2e suite, full production buildSlow / heavy for every agent turn
Silent auto-fix on StopPrefer explicit fixes
Interactive codegen / e2e UIHuman-driven

Day-to-day flow

Troubleshooting

SymptomCheck
Hooks never run/hooks-trust; Hooks tab shows Project hooks; reload r
Stop always blocksRun post-agent and the audit script locally; fix failures
Dialog never appearsYou are on macOS GUI session; not SSH-only; timeout not already fired
Deploy blocked without dialogNo GUI → fail closed; use ALLOW_DEPLOY=1 only if you accept the risk
Format-on-edit no-opFile extension not in allowlist, or path is generated/vendor

Frontend Corner — agent ops, tooling, and decision records