Claude Code Supervisor
Bridge between Claude Code's lifecycle hooks and your agent harness.
Architecture
CODEBLOCK0
Quick Start
1. Install hooks into a project
CODEBLOCK1
Creates:
- -
.claude/hooks/supervisor/ — hook scripts + triage - INLINECODE1 — wired into Claude Code lifecycle
- INLINECODE2 — configuration (edit this)
2. Configure
Edit .claude-code-supervisor.yml:
CODEBLOCK2
3. Register a supervised session
Create ~/.openclaw/workspace/supervisor-state.json (or wherever your harness keeps state):
CODEBLOCK3
4. Launch Claude Code in tmux
CODEBLOCK4
Hooks fire automatically. Triage assesses. You get notified only when it matters.
How the Pre-Filter Works (Option D)
Not every hook event needs an LLM call. Bash catches the obvious cases first:
on-stop.sh
| Signal | Bash decision | LLM triage? |
|---|
| INLINECODE5 | Always needs attention | ✅ Yes |
| INLINECODE6 + shell prompt back |
Agent might be done | ✅ Yes |
|
end_turn + no prompt | Agent is mid-work | ❌ Skip |
|
stop_sequence | Normal | ❌ Skip |
on-error.sh
| Signal | Bash decision | LLM triage? |
|---|
| API 429 / rate limit | Transient, will resolve | ❌ Log only |
| API 500 |
Agent likely stuck | ✅ Yes |
| Other tool error | Unknown severity | ✅ Yes |
on-notify.sh
| Signal | Bash decision | LLM triage? |
|---|
| INLINECODE9 | Internal, transient | ❌ Skip |
| INLINECODE10 |
Needs decision | ✅ Yes |
|
idle_prompt | Agent waiting | ✅ Yes |
Triage Classifications
The LLM returns one of:
| Verdict | Meaning | Typical action |
|---|
| FINE | Agent is working normally | Log silently, no notification |
| NEEDS_NUDGE |
Transient error, should continue | Send "continue" to tmux |
|
STUCK | Looping or not progressing | Try different approach or escalate |
|
DONE | Task completed successfully | Report to human |
|
ESCALATE | Needs human judgment | Notify human with context |
Handling Notifications (for agent harness authors)
Wake events arrive with the prefix cc-supervisor: followed by the classification:
CODEBLOCK5
Nudging via tmux
CODEBLOCK6
Escalation format
See references/escalation-rules.md for when to nudge vs escalate and quiet hours.
Watchdog (Who Watches the Watchman?)
Hooks depend on Claude Code being alive. If the session hard-crashes, hits account
limits, or the process gets OOM-killed, no hooks fire. The watchdog catches this.
INLINECODE14 is a pure bash script (no LLM, no Claude Code dependency) that:
- 1. Reads
supervisor-state.json for all "running" sessions - Checks: is the tmux socket alive? Is the session there? Is Claude Code still running?
- If something is dead and no hook reported it → notifies via the configured command
- Updates
lastWatchdogAt in state for tracking
Run it on a timer. Choose your poison:
System cron:
CODEBLOCK7
OpenClaw cron:
CODEBLOCK8
systemd timer, launchd, or whatever runs periodically on your box.
The watchdog is deliberately dumb — no LLM, no complex logic, just "is the process still
there?" This means it works even when the triage model is down, the API is melting, or
your account hit its limit. Belts and suspenders.
Files
- -
scripts/install-hooks.sh — one-command setup per project - INLINECODE19 — Stop event handler with bash pre-filter
- INLINECODE20 — PostToolUseFailure handler with bash pre-filter
- INLINECODE21 — Notification handler with bash pre-filter
- INLINECODE22 — LLM triage (called by hooks for ambiguous cases)
- INLINECODE23 — shared config loading and notification functions
- INLINECODE24 — dead session detector (pure bash, no LLM dependency)
- INLINECODE25 — terminal output pattern matching guide
- INLINECODE26 — when to nudge vs escalate vs wait
- INLINECODE27 — example configuration
Claude Code 监督器
连接 Claude Code 生命周期钩子与您的代理框架之间的桥梁。
架构
Claude Code(在 tmux 中)
│ 停止 / 错误 / 通知
▼
Bash 预过滤器(选项 D)
│ 明显情况直接处理
│ 模糊情况传递下去
▼
快速 LLM 分类(使用 Haiku 的 claude -p,或本地 LLM)
│ 分类:正常 | 需要提示 | 卡住 | 完成 | 升级
│ 正常 → 静默记录
▼
通知命令(可配置)
│ openclaw 唤醒、webhook、ntfy、脚本等
▼
代理框架决策并执行
│ 提示(向 tmux 发送按键)、等待、升级给人类
快速开始
1. 将钩子安装到项目中
bash
{baseDir}/scripts/install-hooks.sh /path/to/your/project
创建:
- - .claude/hooks/supervisor/ — 钩子脚本 + 分类
- .claude/settings.json — 接入 Claude Code 生命周期
- .claude-code-supervisor.yml — 配置(编辑此文件)
2. 配置
编辑 .claude-code-supervisor.yml:
yaml
triage:
command: claude -p --no-session-persistence # 或:ollama run llama3.2
model: claude-haiku-4-20250414
notify:
command: openclaw gateway call wake --params # 或:curl, ntfy, 脚本
3. 注册受监督的会话
创建 ~/.openclaw/workspace/supervisor-state.json(或您的框架保存状态的任何位置):
json
{
sessions: {
my-task: {
socket: /tmp/openclaw-tmux-sockets/openclaw.sock,
tmuxSession: my-task,
projectDir: /path/to/project,
goal: 修复问题 #42,
successCriteria: 测试通过,已提交,
maxNudges: 5,
escalateAfterMin: 60,
status: running
}
}
}
4. 在 tmux 中启动 Claude Code
bash
SOCKET=/tmp/openclaw-tmux-sockets/openclaw.sock
tmux -S $SOCKET new -d -s my-task
tmux -S $SOCKET send-keys -t my-task cd /path/to/project && claude 修复问题 #42 Enter
钩子自动触发。分类进行评估。只有在必要时您才会收到通知。
预过滤器如何工作(选项 D)
并非每个钩子事件都需要 LLM 调用。Bash 首先捕获明显的情况:
on-stop.sh
| 信号 | Bash 决策 | LLM 分类? |
|---|
| maxtokens | 总是需要关注 | ✅ 是 |
| endturn + shell 提示符返回 |
代理可能已完成 | ✅ 是 |
| end_turn + 无提示符 | 代理正在工作中 | ❌ 跳过 |
| stop_sequence | 正常 | ❌ 跳过 |
on-error.sh
| 信号 | Bash 决策 | LLM 分类? |
|---|
| API 429 / 速率限制 | 临时性,会自行解决 | ❌ 仅记录 |
| API 500 |
代理可能卡住 | ✅ 是 |
| 其他工具错误 | 严重程度未知 | ✅ 是 |
on-notify.sh
| 信号 | Bash 决策 | LLM 分类? |
|---|
| auth* | 内部,临时性 | ❌ 跳过 |
| permissionprompt |
需要决策 | ✅ 是 |
| idle_prompt | 代理在等待 | ✅ 是 |
分类结果
LLM 返回以下之一:
| 判定 | 含义 | 典型操作 |
|---|
| 正常 | 代理正常工作 | 静默记录,不通知 |
| 需要提示 |
临时错误,应继续 | 向 tmux 发送继续 |
|
卡住 | 循环或没有进展 | 尝试不同方法或升级 |
|
完成 | 任务成功完成 | 向人类报告 |
|
升级 | 需要人类判断 | 附上上下文通知人类 |
处理通知(供代理框架开发者使用)
唤醒事件以 cc-supervisor: 前缀开头,后跟分类:
cc-supervisor: 需要提示 | error:api_500 | cwd=/home/user/project | ...
cc-supervisor: 完成 | stopped:endturn:promptback | cwd=/home/user/project | ...
通过 tmux 发送提示
bash
tmux -S $SOCKET send-keys -t $SESSION 继续 — API 错误是临时性的 Enter
升级格式
请参阅 references/escalation-rules.md 了解何时提示、何时升级以及静默时段。
看门狗(谁来监视监视者?)
钩子依赖于 Claude Code 保持运行。如果会话硬崩溃、达到账户限制或进程被 OOM 杀死,则不会触发任何钩子。看门狗负责捕获这种情况。
scripts/watchdog.sh 是一个纯 bash 脚本(无 LLM,无 Claude Code 依赖),它:
- 1. 读取 supervisor-state.json 中所有运行中的会话
- 检查:tmux 套接字是否存活?会话是否存在?Claude Code 是否仍在运行?
- 如果某些内容已死亡且没有钩子报告 → 通过配置的命令通知
- 更新状态中的 lastWatchdogAt 用于跟踪
定时运行它。选择您的方式:
系统 cron:
bash
/15 * /path/to/claude-code-supervisor/scripts/watchdog.sh
OpenClaw cron:
json
{
schedule: { kind: every, everyMs: 900000 },
payload: { kind: systemEvent, text: cc-supervisor: watchdog — 运行 /path/to/scripts/watchdog.sh 并报告 },
sessionTarget: main
}
systemd 定时器、launchd 或任何在您的机器上定期运行的程序。
看门狗故意设计得简单 — 无 LLM,无复杂逻辑,只检查进程是否还在?这意味着即使分类模型宕机、API 熔断或您的账户达到限制,它也能工作。双重保险。
文件
- - scripts/install-hooks.sh — 每个项目一键设置
- scripts/hooks/on-stop.sh — 带 Bash 预过滤器的停止事件处理器
- scripts/hooks/on-error.sh — 带 Bash 预过滤器的 PostToolUseFailure 处理器
- scripts/hooks/on-notify.sh — 带 Bash 预过滤器的通知处理器
- scripts/triage.sh — LLM 分类(由钩子调用处理模糊情况)
- scripts/lib.sh — 共享配置加载和通知函数
- scripts/watchdog.sh — 死会话检测器(纯 bash,无 LLM 依赖)
- references/state-patterns.md — 终端输出模式匹配指南
- references/escalation-rules.md — 何时提示、何时升级、何时等待
- supervisor.yml.example — 示例配置