amarbel-llc/clown
GitHub: amarbel-llc/clown
Clown 是一个用 Nix 包装 Claude Code 的工具,通过默认禁用 Bash、层级 prompt 注入和参数化插件加载来安全可控地定制 AI 编程助手的运行环境。
Stars: 0 | Forks: 0
# clown
一个围绕 [Claude Code](https://docs.anthropic.com/en/docs/claude-code) 的 Nix 包装器
它以层级结构注入自定义 system prompt,默认禁用 Bash,
并支持参数化插件加载。
## 安装
Clown 是一个 Nix flake。裸包装器(无插件)可以直接运行:
```
nix run github:amarbel-llc/clown
```
要构建带插件的 clown,请在你自己的 flake 中使用 `mkJuggler`(参见下文的
[插件](#plugins))。
## 它的功能
Clown 通过四项新增功能包装了 `claude` 二进制文件:
1. **默认禁用 Bash** — 每次调用时都会传入 `--disallowed-tools 'Bash(*)'`。
2. **禁用自动记忆且空闲会话无法静默自动继续** —
clown 携带了未打补丁的上游 `claude-code` 二进制文件(早期的方法通过打补丁让其从 clown 自己的 store 路径读取 managed-settings;该补丁已被移除),
而是传入一个内联的 `--settings` JSON
代码块:`CLAUDE_CODE_DISABLE_AUTO_MEMORY=1` 关闭 Claude 的自主
记忆写入(`CLAUDE.md`/`AGENTS.md` 文件不受影响),并且一个非常
大的 `CLAUDE_AFK_TIMEOUT_MS` 会阻止空闲确认提示
越过用户自动继续。如果你已经自己设置了该
变量,则每一项都会被跳过。
3. **层级化 system prompt 注入** — 从 `$PWD` 向上遍历至 `$HOME`,
沿途收集 `.clown/` 目录:
- **替换模式 (Replace mode)**:如果任何目录包含 `.clown/system-prompt`,最
深层的目录将完全替换 Claude 的 system prompt
(`--system-prompt-file`)。
- **追加模式 (Append mode)**:在 `.clown/system-prompt.d/`
目录中找到的所有 `.md` 文件将按从最浅到最深的顺序连接,并追加到 system
prompt(`--append-system-prompt-file`)。内置片段(位于
`system-prompt-append.d/`)始终前置于用户片段之前。
4. **Fish shell 补全** — 为所有 Claude Code flag 提供完整补全,
外加由 `clown sessions-complete` 子命令驱动的 `clown resume` URI 补全。
所有其他参数将原封不动地传递给 `claude`。
## 插件
Clown 默认不携带任何插件。使用者通过 `mkJuggler` 提供插件 flake input,
该函数会解析插件目录,并在构建时将 `--plugin-dir`
flag 烧入包装器中。
### mkJuggler
`clown.lib.${system}.mkJuggler` 接受一个带有
`plugins` 列表的单个属性集。每个插件定义有两个字段:
| 字段 | 类型 | 描述 |
|-------|------|-------------|
| `flake` | flake input | 插件的 flake input 值 |
| `dirs` | 字符串列表 | 相对于 flake 默认 package 输出的路径。支持字面路径或 glob 模式。 |
它返回 `{ packages.default, devShells.default, checks }`。
### 使用者示例
```
{
inputs = {
clown.url = "github:amarbel-llc/clown";
clown.inputs.nixpkgs.follows = "nixpkgs";
moxy.url = "github:amarbel-llc/moxy";
moxy.inputs.nixpkgs.follows = "nixpkgs";
bob.url = "github:amarbel-llc/bob";
bob.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = { self, nixpkgs, clown, moxy, bob, ... }:
let
system = "aarch64-darwin";
juggler = clown.lib.${system}.mkJuggler {
plugins = [
{ flake = moxy; dirs = [ "share/purse-first/moxy" ]; }
{ flake = bob; dirs = [ "share/purse-first/*" ]; }
];
};
in {
packages.${system}.default = juggler.packages.default;
};
}
```
### 插件目录要求
`dirs` 中的每个路径必须指向一个包含
`.claude-plugin/plugin.json` 且至少具有 `name` 字段的目录。Glob 模式
(`*`, `?`, `[`)会在构建时展开;非插件目录会被
静默跳过。匹配到零个插件的 glob 会导致构建失败。
### 版本输出
`clown version` 显示所有组件,包括动态加载的插件:
```
COMPONENT VERSION REV
bob/bob - 474d0c4fac8a084c5378dba51337fea45b86ee2d
bob/caldav - 474d0c4fac8a084c5378dba51337fea45b86ee2d
claude-code 1.0.46 b2b9662ffe1e9a5702e7bfbd983595dd56147dbf
clown 0.0.1 edc5db5...
codex 0.0.1-beta e2dde111aea2c0699531dc616112a96cd55ab8b5
moxy/moxy - a90e0dfbc830700efe28d2238bd2acb5bf8095dc
```
插件行使用 `/` 格式。Version 和 rev 分别来自
`plugin.json` 和 flake input。
有关完整规范,请参见 [RFC 0001](docs/rfcs/0001-parameterized-plugin-loading.md)。
### HTTP MCP 服务器 (`clown.json`)
插件可以声明基于 HTTP 的 MCP 服务器,clown 会自动启动
并管理它们。这使得能够使用无法通过 stdio 使用的 MCP 功能,包括
`notifications/tools/list_changed` 和服务器发起的请求。
插件在 `.claude-plugin/` 旁边附带一个 `clown.json`:
```
{
"version": 1,
"httpServers": {
"my-server": {
"command": "bin/my-server",
"transport": "streamable-http",
"healthcheck": {
"path": "/healthz",
"interval": "1s",
"timeout": "30s"
}
}
}
}
```
服务器必须实现 clown 插件协议:绑定到一个临时端口,
向 stdout 打印握手行(`1|1|tcp||streamable-http`),并
响应健康检查。有关
完整规范,请参见 [RFC 0002](docs/rfcs/0002-clown-plugin-protocol.md)。
### 后台监视器 (`clown.json`)
插件还可以在 `clown.json` 中声明后台 shell 监视器。每个条目
镜像了 Anthropic 的插件监视器 schema,并被原样注入到已编译的
`.claude-plugin/plugin.json` 中,以便 Claude Code(≥ v2.1.105)处理
生成、`${...}` 替换和生命周期。来自
监视器命令的每一行 stdout 都会作为通知
显示在聊天中。
```
{
"version": 1,
"monitors": [
{
"name": "error-log",
"command": "tail -F ${CLAUDE_PLUGIN_ROOT}/logs/error.log",
"description": "Application error log"
},
{
"name": "deploy-status",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/poll-deploy.sh",
"description": "Deployment status changes",
"when": "on-skill-invoke:debug"
}
]
}
```
Clown 不会生成或管理监视器 — 这是 Claude Code 做的。如果
`clown.json` 和同一插件的 `.claude-plugin/plugin.json` 同时
声明了 `monitors` 键,则会导致错误;请选择一个来源。有关完整
schema 和验证规则,请参见 `clown-json(5)`。
## .clown 目录
将 prompt 片段放置在目录层级的任意位置:
```
~/.clown/system-prompt.d/
00-global-rules.md # applied everywhere
~/projects/.clown/system-prompt.d/
00-coding-standards.md # applied in ~/projects and below
~/projects/myapp/.clown/system-prompt
# replaces system prompt entirely for myapp
```
- 追加片段(`.clown/system-prompt.d/*.md`)从最浅层到最深层堆叠 — 更广泛的规则在前,项目特定的规则在后。
- 替换文件(`.clown/system-prompt`)会短路默认的 system
prompt。只有最深层的文件才会生效。追加片段仍会应用在其之上。
## 构建
需要启用 flakes 的 Nix。
```
just build # nix build --show-trace
just clean # rm -rf result
```
## 许可证
MIT — 参见 [LICENSE](LICENSE)。
:clown_face: Sasha, Head Clown
标签:AI编程助手, Claude Code, EVTX分析, Homebrew安装, Nix, SOC Prime, 安全防护, 开发工具, 提示词工程, 策略决策点