Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 12 additions & 12 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ members = [
resolver = "3"

[workspace.package]
version = "0.6.2"
version = "0.7.0"
edition = "2024"
rust-version = "1.94"
license = "Apache-2.0"
Expand Down Expand Up @@ -143,20 +143,20 @@ landlock = "0.4"
seccompiler = "0.4"

# Workspace crates (published)
clash-brush-builtins = { path = "clash-brush-builtins", version = "0.6.2" }
clash-brush-parser = { path = "clash-brush-parser", version = "0.6.2" }
clash-brush-core = { path = "clash-brush-core", version = "0.6.2" }
clash-brush-interactive = { path = "clash-brush-interactive", version = "0.6.2", features = [
clash-brush-builtins = { path = "clash-brush-builtins", version = "0.7.0" }
clash-brush-parser = { path = "clash-brush-parser", version = "0.7.0" }
clash-brush-core = { path = "clash-brush-core", version = "0.7.0" }
clash-brush-interactive = { path = "clash-brush-interactive", version = "0.7.0", features = [
"basic",
] }

# Workspace crate aliases (used by brush crates internally under original brush-* names)
brush-parser = { path = "clash-brush-parser", version = "0.6.2", package = "clash-brush-parser" }
brush-core = { path = "clash-brush-core", version = "0.6.2", package = "clash-brush-core" }
brush-parser = { path = "clash-brush-parser", version = "0.7.0", package = "clash-brush-parser" }
brush-core = { path = "clash-brush-core", version = "0.7.0", package = "clash-brush-core" }

# Workspace crates (internal only)
clash-lsp = { path = "clash-lsp", version = "0.6.2" }
clash-policy = { path = "clash-policy", version = "0.6.2" }
clash_notify = { path = "clash_notify", version = "0.6.2" }
clash_starlark = { path = "clash_starlark", version = "0.6.2" }
claude_settings = { path = "claude_settings", version = "0.6.2" }
clash-lsp = { path = "clash-lsp", version = "0.7.0" }
clash-policy = { path = "clash-policy", version = "0.7.0" }
clash_notify = { path = "clash_notify", version = "0.7.0" }
clash_starlark = { path = "clash_starlark", version = "0.7.0" }
claude_settings = { path = "claude_settings", version = "0.7.0" }
1 change: 0 additions & 1 deletion clash-lsp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ name = "clash-lsp"
version.workspace = true
edition.workspace = true
license.workspace = true
publish = false

[dependencies]
anyhow.workspace = true
Expand Down
88 changes: 88 additions & 0 deletions site/versions/v0.7.0/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
layout: base.njk
title: Clash
description: Write rules for your AI agent. Clash enforces them.
---

<div class="hero">
<h1 class="hero-title">clash</h1>
<p class="hero-tagline">Be an agentic engineer, not an agent babysitter.</p>
<p class="hero-subtitle">You define the capabilities. Clash enforces them. Your agent never sees a choice.</p>
</div>

<div class="divider"><span>Clash for Claude</span></div>

<div class="section">

Claude interrupts us constantly asking whether it's okay to run some command.
This is why `--dangerously-skip-permissions` is so powerful: we can achieve so
much more per unit prompt.

Every tool call your agent makes requires a decision. Right now, that decision
is yours - *every single time* or **not at all**.

Think of Clash as a new `--safely-skip-permissions` flag. A way to choose _how_
to run anything safely, not just whether Claude can run it **as *you***.

Clash intercepts every tool call Claude makes and runs it through your policy — before anything executes.

<div class="cards">
<div class="card card--green">
<h3>Match</h3>
<p>Every tool call is pattern-matched against your policy — commands, arguments, file paths, network targets. No AI judgment. Same input, same result, every time.</p>
</div>
<div class="card card--amber">
<h3>Decide</h3>
<p>The most specific matching rule determines the effect. <strong>Allow</strong> runs silently. <strong>Ask</strong> prompts you. <strong>Deny</strong> blocks invisibly — Claude never knows the capability existed.</p>
</div>
<div class="card card--red">
<h3>Sandbox</h3>
<p>The action executes inside an OS-level sandbox. File access, network scope, and process boundaries are enforced by the kernel, not by convention.</p>
</div>
</div>

</div>

<div class="divider"><span>Get Started</span></div>

<div class="section">

## Get started with Clash for Claude

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

Initialize:
```
clash init
```

Run w/ Claude:
```
claude
```

Three commands. One binary, one policy file, full enforcement. See the [Quick Start](/quick-start/) for details.

</div>

<div class="divider"><span>Agent Support</span></div>

<div class="section">

## Agent support

| Agent | Status |
|---|---|
| [Claude Code](https://docs.anthropic.com/en/docs/claude-code) | **Supported** |
| [Gemini CLI](https://github.com/google-gemini/gemini-cli) | **Protocol ready** |
| [Codex CLI](https://github.com/openai/codex) | **Protocol ready** |
| [Amazon Q CLI](https://github.com/aws/amazon-q-developer-cli) | **Protocol ready** |
| [OpenCode](https://github.com/opencode-ai/opencode) | **Protocol ready** |
| [Copilot CLI](https://github.com/github/copilot-cli) | **Protocol ready** |

Use `clash init --agent <name>` to set up any supported agent. [Contributions welcome](https://github.com/empathic/clash).

</div>
98 changes: 98 additions & 0 deletions site/versions/v0.7.0/pages/faq.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
layout: base.njk
title: FAQ
description: Frequently asked questions about Clash.
permalink: /faq/
---

<h1 class="page-title">FAQ</h1>
<p class="page-desc">Quick answers to common questions.</p>

## Is Clash only for AI agents?

No. Clash is a general-purpose sandboxing and policy engine. You can use `clash sandbox exec` to sandbox any command — build scripts, install scripts, untrusted binaries, anything. The AI agent integration is one application of the same underlying engine.

---

## How is this different from Docker or Firejail?

Clash is lighter and more targeted. It doesn't virtualize anything — it applies Landlock (Linux) or Seatbelt (macOS) restrictions directly to a process. No container images, no namespaces, no root required. You write a few rules about which paths and network access a command should have, and the kernel enforces them. It's closer to a fine-grained `sandbox-exec` than a container runtime.

---

## How is this different from Claude Code's built-in permissions?

Claude Code gives you per-tool toggles: allow a tool entirely, or get prompted every time. Clash gives you **pattern-matching rules within tools**: allow `git status` while denying `git push`, allow reads under your project while blocking writes to `.env`, allow network access to `github.com` while blocking everything else. Plus kernel-enforced sandboxes, policy composition, and per-project layering.

---

## Which agents does Clash support?

**Claude Code** is fully supported today. Gemini CLI, Codex CLI, Amazon Q CLI, OpenCode, and Copilot CLI have protocol-ready integrations. But Clash also works standalone — `clash sandbox exec` sandboxes any command, no agent required. The policy engine is agent-independent; only the hook layer is specific to each agent. See the [agent support table]({{ version.pathPrefix }}/#agent-support).

---

## Will it slow things down?

No. Policies compile into a decision tree at load time. Evaluation is in-process with no network round-trip. Sandbox setup adds a few milliseconds at process launch — then the kernel handles enforcement with zero runtime overhead.

---

## What happens if my policy has a bug?

Clash blocks **everything** when the policy fails to compile. A broken policy should never silently approve things. Run `clash policy validate` to find the error, or `clash init` to start over.

---

## Can I share policies with my team?

Yes. Commit a **project-level** policy at `<repo>/.clash/policy.star`. Team members pick it up automatically. Individuals can still override with user-level or session-level policies.

---

## How does the kernel sandbox work?

When a rule includes a sandbox, Clash generates OS-level restrictions:

- **Linux:** Landlock constrains filesystem access; seccomp + proxy filters network calls.
- **macOS:** Seatbelt profiles restrict filesystem and network access.

Restrictions are inherited by all child processes and cannot be bypassed. Run `clash sandbox check` to verify your platform supports it.

---

## Do rules apply to subprocesses?

Exec rules match only the **top-level command**. If `make deploy` internally runs `git push`, the deny rule for `git push` won't fire. However, **sandbox restrictions** on filesystem and network access are enforced on all child processes at the kernel level — that's the whole point.

---

## How do I turn it off temporarily?

```bash
CLASH_DISABLE=1 claude
```

Clash stays installed but becomes a pass-through — no enforcement, no prompts. Unset the variable to re-enable.

---

## Which platforms work?

- **macOS** — Apple Silicon and Intel
- **Linux** — x86_64 and aarch64
- **Windows** — not supported

Kernel sandboxing needs Landlock (Linux 5.13+) or Seatbelt (macOS). Clash works without sandboxing on older kernels, but sandbox rules will be ignored.

---

## How do I uninstall?

```bash
clash uninstall
```

This removes the Claude Code plugin, the status line, policy files (`~/.clash/`), and the binary — regardless of how it was installed. Use `clash uninstall -y` to skip confirmation prompts.

After uninstalling, Claude Code reverts to its built-in permission model.
Loading
Loading