Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

empathic/clash

Open more actions menu

Repository files navigation

clash

Command Line Agent Safety Harness

Stop babysitting your coding agent, go touch grass.


Important

Clash is under heavy development. It's being used by engineers at Empathic and is quite productive, but the API is not stable and is subject to change. Please report bugs!

Agent Support

Clash is designed to be agent-agnostic — a universal safety harness for any coding agent that executes tools on your behalf. The policy language and capability model are agent-independent; only the integration layer is specific to each agent.

Agent Status Tracking
Claude Code Supported
Codex CLI Planned #195
Gemini CLI Planned #196
OpenCode Planned #197

Currently, the Claude Code integration is the most mature. If you'd like to help bring Clash to another agent, contributions are welcome!


The Problem

Coding agents operate with broad tool access — executing commands, editing files, and making network requests on your behalf. Their permission models tend to be all-or-nothing: either you allow a tool entirely or get prompted every time. You end up clicking "yes" hundreds of times a session, or giving blanket approval and hoping for the best.

Clash gives you granular control. Write policy rules that decide what to allow, deny, or ask about — then let the agent work freely on safe operations while blocking dangerous ones. On Linux, rules can generate kernel-enforced filesystem sandboxes so even allowed commands can only touch the files you specify.


Quick Start

There are two ways to run clash depending on what you're doing:

Install (use clash in your day-to-day work)

curl -fsSL https://raw.githubusercontent.com/empathic/clash/main/install.sh | bash
clash init
claude

This downloads the latest release binary to ~/.local/bin/ (Apple Silicon Mac, Linux x86_64, Linux aarch64). On Intel Mac or other platforms, install via Cargo:

cargo install clash

clash init writes a default policy, installs the Claude Code plugin from GitHub, installs the status line, and walks you through initial configuration. After init, every claude session automatically loads clash.

If you have the repo checked out, you can also use just install which registers the plugin from the local source tree instead of GitHub.

Develop (hack on clash itself)

just dev

This builds the binary, symlinks it into the source plugin directory, and launches a one-off Claude Code session with the plugin loaded directly from source. Changes to skills, hooks, or Rust code take effect on the next just dev — no install step needed.


Interactive Configuration

Once clash is running inside Claude Code, you have access to slash commands (skills) for managing your policy without leaving your session:

Skill What it does
/clash:onboard Interactively build your policy from scratch
/clash:edit Guided editing of your policy file
/clash:status Show current policy, rules, and enforcement status
/clash:describe Plain-English description of your active policy
/clash:explain See which rule matches a specific tool invocation
/clash:allow Quickly add an allow rule
/clash:deny Quickly add a deny rule
/clash:test Test your policy against hypothetical tool uses
/clash:audit View recent permission decisions from the audit log

If you're new, start with /clash:onboard — it walks you through creating a policy tailored to your workflow.


Policy Rules

Policies use s-expression syntax: (effect (capability ...)). Clash reads them on every tool invocation, so edits take effect immediately — no restart needed.

Policy Layers

Clash supports three policy levels, each automatically included and evaluated in order of precedence:

Level Location Purpose
User ~/.clash/policy.sexpr Your personal defaults across all projects
Project <project>/.clash/policy.sexpr Shared rules for a specific repository
Session Created via --scope session Temporary overrides for the current session

Layer precedence: Session > Project > User. Higher layers can shadow rules from lower layers — for example, a project-level deny overrides a user-level allow for the same capability. Use clash status to see all active layers and which rules are shadowed.

Example

; ~/.clash/policy.sexpr (user level)
(default ask "main")

(policy "main"
  (include "cwd-access")
  (allow (exec "cargo" *))          ; let it run cargo commands
  (allow (exec "git" *))            ; let it run git commands
  (deny (exec "git" "push" *))      ; never allow push
  (deny (exec "git" "reset" "--hard" *))
  (allow (net "github.com")))        ; allow github.com access

(policy "cwd-access"
  (allow (fs read (subpath (env PWD))))
  (allow (fs (or write create) (subpath (env PWD)))))

Effects: allow (auto-approve), deny (block), ask (prompt you)

Capabilities: exec (commands), fs (filesystem), net (network)

Precedence: deny always wins. More specific rules beat less specific. Within the same specificity, ask beats allow. Higher layers shadow lower layers at the same specificity. See Policy Semantics for the full algorithm.

Policy Blocks

Rules are organized into named policy blocks that can include other blocks, letting you compose reusable layers:

(policy "readonly"
  (allow (fs read (subpath (env PWD)))))

(policy "main"
  (include "readonly")              ; import rules from other blocks
  (allow (exec "git" *)))

Kernel Sandbox

Allowed exec rules can carry sandbox constraints that clash compiles into OS-enforced sandboxes (Landlock on Linux, Seatbelt on macOS):

(allow (exec "cargo" *)
  (sandbox "cargo-sandbox"))

(sandbox "cargo-sandbox"
  (fs read (subpath (env PWD)))
  (fs write (subpath "./target"))
  (net allow))

Even if a command is allowed by policy, the sandbox ensures it can only access the paths you specify.

Note: Exec rules (like (deny (exec "git" "push" *))) apply to the top-level command Claude runs. If an allowed command spawns a subprocess that runs a denied command, the exec rule does not fire. Kernel sandbox restrictions on filesystem and network access do apply to all child processes. See #136 for tracking deeper exec enforcement.

For the full rule syntax, see the Policy Writing Guide.


Useful Commands

clash init                                   # set up clash with a safe default policy
clash allow bash                             # allow command execution
clash allow edit                             # allow file editing in project
clash allow web                              # allow web access
clash deny '(exec "rm" *)'                   # deny rm commands
clash ask bash                               # require approval for bash commands
clash status                                 # see all layers, rules, and shadowing
clash doctor                                 # diagnose common setup issues
clash update                                 # update clash to the latest release
clash update --check                         # check for updates without installing
clash explain bash "git push"                # see which rule matches a command
clash policy list                            # list all rules with level tags
clash policy remove '(deny (exec "rm" *))'   # remove a rule
clash edit                                   # interactive policy editor

For the full command reference, see the CLI Reference.


Status Line

Clash can display a live scoreboard in Claude Code's status bar, giving you ambient visibility into policy enforcement without interrupting your workflow.

⚡clash ✓12 ✗3 ?1 · ✗ Bash(touch ...)
  allow with: clash allow '(exec "touch" *)'

The status line shows:

  • Counts: allowed, denied, ? asked — color-coded green/red/yellow
  • Last action: the most recent policy decision with tool name and input summary
  • Allow hint: when the last action was denied, a second line shows the narrowest rule to allow it

Setup

clash statusline install     # add status line to Claude Code settings
clash statusline uninstall   # remove it

After installing, the status line appears automatically in your next Claude Code session.


Requirements

  • macOS (Apple Silicon or Intel) or Linux (x86_64 or aarch64)
  • A supported coding agent installed
  • Rust toolchain (for building from source)
  • Windows is not supported

Troubleshooting

Run clash doctor to automatically diagnose common setup issues:

clash doctor

It checks policy files, plugin registration, PATH, file permissions, and sandbox support, reporting actionable fix instructions for each problem.

"command not found: clash"

Make sure the install directory is on your PATH:

# If installed via the install script
export PATH="$HOME/.local/bin:$PATH"

# If installed via cargo
export PATH="$HOME/.cargo/bin:$PATH"

Double-prompting (clash asks, then Claude Code asks)

This means Claude Code's built-in permissions are still active. Re-run init — it sets bypassPermissions: true in your Claude Code user settings by default so clash is the sole permission handler:

clash init

Policy not working as expected

Use clash explain to see exactly which rule matches:

clash explain bash "git push origin main"

Or use the /clash:explain skill inside Claude Code for an interactive walkthrough.

All actions blocked — policy error

If every tool use is being denied with a "policy failed to compile" message, your policy file has a syntax error. Clash blocks all actions when it can't compile the policy rather than silently degrading.

To diagnose:

clash policy validate

This will show which policy file has the error and suggest how to fix it. If you want to start fresh:

clash init

Disabling & Uninstalling

You're always in control of whether clash is active.

Disable for one session

CLASH_DISABLE=1 claude

Clash stays installed but becomes a complete pass-through — no policy enforcement, no sandbox, no prompts. clash status and the status line will reflect the disabled state. Set CLASH_DISABLE=0 or unset the variable to re-enable.

Uninstall completely

# 1. Remove the Claude Code plugin
claude plugin uninstall clash

# 2. Remove the binary
cargo uninstall clash          # if installed via cargo
rm -f ~/.local/bin/clash       # if installed via the install script

# 3. (Optional) Remove the plugin marketplace entry
claude plugin marketplace remove clash

# 4. (Optional) Remove the status line — only needed if you skipped step 2
clash statusline uninstall

# 5. (Optional) Clean up configuration and logs
rm -rf ~/.clash       # user-level policy and logs
rm -rf .clash         # project-level policy (per repo)

After removing the plugin, Claude Code reverts to its built-in permission model. Policy files are left in place so you can pick up where you left off if you reinstall.


Documentation


Development

How it works

Clash integrates with coding agents via their plugin or extension system. For each supported agent, an integration layer intercepts tool calls and evaluates them against your policy before the agent executes them.

Agent → integration hook → clash binary → policy evaluation → allow / deny / ask

Claude Code (current integration): The plugin lives in clash-plugin/ and registers hooks that intercept every tool call. It consists of hook definitions, skill definitions (slash commands), and the clash binary. In dev mode, just dev symlinks the freshly-built binary into clash-plugin/bin/ and points Claude Code at the source directory. In install mode, just install stages a self-contained copy and registers it via the marketplace.

Recipes

just dev         # build + launch Claude Code with plugin from source
just install     # build + install system-wide via marketplace
just uninstall   # remove installed plugin and binary
just check       # fmt + test + clippy
just clester     # end-to-end tests (YAML-based hook simulation)
just ci          # full CI (check + clester)
just release 0.4.0  # bump versions, commit, tag (push to trigger release)

Project Structure

clash/
├── clash/              # CLI binary + library (Rust)
├── clash-plugin/       # Claude Code plugin (hooks, skills, bin/)
├── clash_notify/       # Notification support (desktop, Zulip)
├── claude_settings/    # Claude Code settings library
├── clester/            # End-to-end test harness
└── docs/               # Documentation

License

Apache License 2.0

About

Command Line Agent Safety Harness. Stop babysitting your agents, go touch grass.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.