# 通知 — Liu Terminal

> Liu Terminal 通知。当 AI 代理完成任务时收到通知，支持可配置钩子和声音提醒。

URL: https://liu.software/zh/docs/notify/  
Language: zh  
Updated: 2026-10-17

liu-notify 是一个可选的独立进程，但 Liu GUI 也可以在进程内托管同一服务器。它通过本地套接字接收 24 字节的 v1 标头或带可选元数据的 28 字节当前 v2 标头，使用令牌桶限流，对相同事件去重，并为每个（代理，事件）对路由声音或语音。

## 运行

```
# 与主应用一起构建
cmake --build build --target liu-notify

# 启动守护进程
./build/liu-notify daemon

# 发送一次性事件
./build/liu-notify send --tool=claude --event=stop
```

配置文件位于 ~/.config/liu/notify.conf —— 与主应用的 config.json 分离，因此即使 Liu 本身未运行，守护进程仍可保持可用。

When Liu is running, its GUI hosts the notification server in-process; the CLI does not need to start a second daemon. If no server is listening, send exits without delivering an event. Use the standalone daemon only when notifications must work without Liu.

## 支持的代理钩子

Liu 可以在应用运行期间为以下代理安装和移除生命周期钩子。钩子写入代理自己的配置，承载服务的 Liu 实例退出时会删除由其管理的条目。

| 代理 | 钩子位置 | 信号 | 说明 |
| --- | --- | --- | --- |
| Claude Code | `~/.claude/settings.json` | `start · notify · complete` | UserPromptSubmit drives the working state; Notification and Stop can alert you. |
| Codex | `~/.codex/config.toml` | `complete` | The Stop hook reports a completed turn. Run /hooks in Codex once to trust it. |
| Grok | `~/.grok/hooks/liu-notify.json` | `notify · complete` | Notification and top-level Stop events are handled; sub-agent completions stay silent. |
| OpenCode | `~/.config/opencode/plugins/liu-notify.js` | `complete` | The managed plugin listens for top-level session.idle events. |
| Antigravity | `~/.gemini/config/hooks.json` | `complete` | A named Stop hook reports when the top-level execution loop ends. |
| Command Code | `~/.commandcode/settings.json` | `complete` | Its Claude-compatible settings schema is wired to the top-level Stop event. |

Copilot 和 custom 可由底层通知协议和声音矩阵接受，但 Liu 目前尚未为它们安装自动生命周期钩子。其他代理仍可在 Liu 标签页中正常运行，只是不会收到自动钩子通知。

## 工具 × 事件矩阵

为任何组合配置声音规则。未设置的单元格将回退到通用规则。

|  | start | stop | notify | error | complete |
| --- | --- | --- | --- | --- | --- |
| claude | · | · | · | · | · |
| copilot | · | · | · | · | · |
| codex | · | · | · | · | · |
| custom | · | · | · | · | · |

## 帧格式

v1 标头为 24 字节；当前 v2 标头为 28 字节，因为增加了 meta\_len。完整帧上限为 4096 字节。tests/fuzz\_notify\_validate.c 对校验进行了模糊测试，格式错误的帧会安全拒绝，不会导致服务器停止。

```
offset  size  field
0       4     magic      ('N','T','F','Y')
4       2     version    (1 or current 2)
6       2     flags      (speak=1, bell=2)
8       1     tool_id    (claude=1, copilot=2, codex=3, custom=255)
9       1     event_id   (start=1, stop=2, notify=3, error=4, complete=5)
10      1     priority   (reserved)
11      1     source     (cli=0, stdin=1, test=2)
12      4     seq        (client nonce — for dedup)
16      4     title_len  (<= 256)
20      4     body_len   (<= 3072)
24      4     meta_len   (v2 only, <= 512)
payload         title, body, then metadata key=value lines
                total frame <= 4096 bytes
```

v2 元数据部分目前包含 cwd=、session= 和 agent= 行。钩子发送方用它将事件归因到正确面板；未知键会被忽略以保持向前兼容。

## 平台后端

相同的帧，不同的扬声器。macOS 使用 AVSpeechSynthesizer，Linux 调用 notify-send。每个后端都驻留在自己的文件中（platform\_notify\_macos.m、platform\_notify\_linux.c），因此更换或存根其中一个只需修改一个文件。

[下一步 配置 →](https://liu.software/zh/docs/config.md)
