Write hooks as small TypeScript files.
Clooks runs them in Claude and Codex for you
rm -rf ~/ crashed.An agent ran rm -rf tests/ patches/ plan/ ~/ and the trailing ~/ wiped the Mac. A guard hook was meant to catch it, but threw an exception and exited with a error code. Some agents read errors as success, so the command ran.
In Clooks, a crashed hook blocks the action by default.
Claude Code only blocks on exit code 2. A guard hook that crashes - a typo, a missing dep - doesn't prevent the action. The action runs as if the hook never ran.
Native hooks are bash strings inside your hook.json. Every hook is a one-liner you quote by hand or write a new bash script for.
All agents run native hooks differently, some in parallel, some sequentially. There's no standard way for ordering, no pipeline, no way for one hook to modify input before another sees it.
A hook you wrote for one repo lives in that repo's settings file. Copying it to the next project means repasting bash strings and recommitting script files. And you might not want every hook enabled.
The best hooks are gists linked in Discord threads. Sharing only works through Claude or Codex Marketplaces, which can open up update injection vectors.
On the left, a Claude Code session. On the right, the hook file.
Each file exports one ClooksHook object, which can handle one or more events. Every event you handle is a method with a typed context and a typed return. Hover a row below to see where it lives in the source.
A hook's meta.config is its public interface. Here's no-destructive-git configured to suit each repositories use case without having to write three separate hooks.
Recorded from actual Claude Code transcripts.
no-rm-rf hook returns ctx.block({ reason }). Claude reads the reason, stops, and surfaces it back to the user..clooks/clooks init writes a self-contained folder. Only the entrypoint script is registered into .claude/settings.json. A teammate cloning the repo gets the same hooks as they're checked in.
Claude Code runs every matching hook in parallel. Nothing stops a slow hook when a fast one already said no — and any short-circuit logic has to be duplicated into every hook that needs it.
Clooks parallelizes and orders hooks. Expensive checks only run when the cheap ones passed — no duplicated short-circuit logic in every hook.
Each layer adds its own hooks and can override the ones beneath. Personal defaults in home, team rules in the repo, and a gitignored local file for the exceptions only you need.
js-package-manager-guard stops agents from reaching for the wrong package manager. The block reason tells agents what to do instead — it self-corrects on the next tool call.
Add the plugin, then run setup inside Codex to install Clooks and configure your project.
Global mode: run clooks init --global --agent all to use hooks from ~/.clooks/ across Claude Code and Codex projects.
Claude Code and Codex plugins help you install and configure Clooks. The runtime is a standalone binary with shared configuration.
At startup, the plugin reminds you if setup is needed. Install optional hook packs through your agent's plugin manager; update their hooks with clooks update.