
Reflex makes AI coding agents prod-safe for infra teams: an open-source pre-execution hook for
Claude Code, Codex CLI, opencode and pi that judges every shell command by where it points and what
it will change, then lets it run, asks a human, or blocks it.
Documentation website: https://ursuciprian.github.io/reflex/

A real Claude Code session in a scratch repository; how to reproduce it.
What it adds to the agents' built-in permission rules:
- Plan-aware terraform gate.
terraform apply without a saved plan asks for
terraform plan -out=tfplan. With infra.terraform_show on, Reflex reads the saved plan with
terraform show -json and denies any delete or replace, naming stateful resources such as
aws_db_instance first. It is off by default and needs a provider plugin cache, because
terraform show starts the provider binaries in .terraform, which an agent could have written.
- Environment awareness. A command is judged with the AWS profile, kube context, Terraform
workspace, git branch and production paths such as
envs/prod: kubectl delete namespace asks in
a dev context and is denied in a prod one.
- One policy across agents. A committed
.reflex/policy.json gives every teammate the same
extra rules, production markers, always-human patterns and freezes in Claude Code, Codex CLI,
opencode, pi and Hermes. It can only tighten; its fast lane and webhook apply only after each
teammate runs reflex trust ..
- Change freeze. A window such as Friday after 15:00 in
Europe/Bucharest, or a date range,
makes production commands that are not read-only ask or be denied, in shadow and enforce mode.
- Audit export and webhook.
reflex audit writes one row per decision (agent, cwd, production
tier, redacted command, decision, rule, who approved it) as csv, json or jsonl for SOC 2 and
ISO 27001 change management evidence. A Slack or json webhook gets denies, asks or production
decisions without delaying the hook.
- Fail-closed hooks. In enforce mode a hook that crashes while loading or deciding answers ask
(Claude Code) or deny (Codex) instead of letting the command run unchecked.
It starts keyless, with local rules in shadow mode, and it also scans what the agent reads for
prompt injection. It gates shell commands, not file edits or MCP calls, and it does not replace a
sandbox or least-privilege credentials.
Install
Claude Code plugin
Reflex is a Claude Code plugin with its own marketplace in this repository. Inside Claude Code:
/plugin marketplace add ursuciprian/reflex
/plugin install reflex@reflex
Or from your shell: claude plugin marketplace add ursuciprian/reflex, then
claude plugin install reflex@reflex. Restart the session (or run /reload-plugins).
The plugin adds the same Claude Code hooks as reflex setup (the PreToolUse command gate on
Bash|Task|Agent, MCP tools and file writes, the post-tool and permission records, conditional instructions and the prompt
injection guard), plus read-only commands: /reflex:status, /reflex:check <command>,
/reflex:report, /reflex:replay, /reflex:queue and /reflex:suggest. reflex is on the Bash
PATH while the plugin is enabled. It needs Node.js 18+ as node on the PATH Claude Code runs
with; no build step, no npm install, no API key. Without saved settings it runs the local engine in
shadow mode, the same default as reflex setup, and it reads the same ~/.config/reflex/config.json
and Keychain item when you have them.
The plugin changes no settings of its own. If reflex setup hooks are also in
~/.claude/settings.json, those run and the plugin's hooks exit at once, so no command is judged
twice; reflex doctor says which one is active. Two things only reflex setup does: it adds
permission rules that make Claude Code ask before editing Reflex's files and settings, and it sizes
the hook timeout to System 2 in the autonomous profile. See
docs/SETUP.md: Claude Code plugin.
Codex CLI plugin
The same repository is a Codex CLI plugin marketplace. From your shell:
codex plugin marketplace add ursuciprian/reflex
codex plugin add reflex@reflex
Then open codex, run /hooks and trust the Reflex entries; Codex runs no plugin hook until you
do. The plugin adds the same Codex hooks as reflex setup --agent codex: the PreToolUse command
gate on Bash and spawn_agent, the post-tool records, conditional instructions on
UserPromptSubmit and the prompt injection guard on Bash and MCP results and on prompts. It needs
Node.js 18+ as node on the PATH Codex runs with, and no API key: without saved settings it runs
the local engine in shadow mode. If reflex setup hooks are also in ~/.codex/hooks.json, those
run and the plugin's hooks exit at once, so no command is judged twice; reflex doctor says which
one is active. See docs/SETUP.md: Codex CLI plugin.
opencode plugin
The npm package is an opencode plugin. Add it to ~/.config/opencode/opencode.json:
{ "plugin": ["@ursuciprian/reflex"] }
opencode installs it at its next start. It registers the same hooks as the plugin file
reflex setup --agent opencode writes: the gate on tool.execute.before for bash and task,
instructions on chat.message, and the injection guard on tool results and prompts. It needs
Node.js 18+ as node on the PATH opencode runs with. If that setup file is also in
~/.config/opencode/plugins/, the npm plugin registers nothing, so no command is judged twice. See
docs/SETUP.md: opencode plugin.
Every agent: package runner or install script
npx @ursuciprian/reflex setup
pnpm dlx @ursuciprian/reflex setup
bunx @ursuciprian/reflex setup
yarn dlx @ursuciprian/reflex setup # yarn 2+
Or with the install script:
curl -fsSL https://raw.githubusercontent.com/ursuciprian/reflex/main/install.sh | bash
Requirements: Node.js 18+ on macOS or Linux (including WSL). Native Windows is not supported yet.
No runtime dependencies; the optional LiteLLM routing hook needs Python 3.9+, and the optional Laya
engine Python 3.10+.
The installer copies the package to ~/.local/share/reflex, links the reflex command into
~/.local/bin, and adds hooks to every supported agent it finds, in shadow mode, with the local
engine. Pass options after bash -s -- or setup:
curl -fsSL https://raw.githubusercontent.com/ursuciprian/reflex/main/install.sh | bash -s -- --agents claude,codex
npx @ursuciprian/reflex setup --mode enforce
npx @ursuciprian/reflex setup --engine jev # hosted classification with a TypeSafe API key
npx @ursuciprian/reflex setup --dry-run # preview configuration changes
To use Jev, create a TypeSafe API key; macOS setup can store it
in the Keychain. See docs/SETUP.md for all options, per-agent notes and
uninstalling.
In one minute