# 🍳 I am cooking

> 你离开电脑时（比如去做饭🍳了），pi 继续自主干活。当它真正卡住、需要你时——或任务完成时——会**大声呼喊你**：声音、中文 TTS、桌面弹窗、**手机推送**，厨房里的你也能听到。

呼喊时 agent 说：**"Agent需要你！"**

[English version](docs/README.en.md)

## ✨ 功能

| 功能 | 说明 |
|---|---|
| 🧠 自主模式 | 离开时注入"自主推进，别干等"规则，agent 继续干活而不是停下来等你 |
| 🤖 Agent 自主开启 | 说"我去做饭了""我离开一下""I'm cooking"，agent 理解后自动开启（无需记命令） |
| 📣 多路呼喊 | 声音 + 中文 TTS + 桌面弹窗 + **手机推送** + TUI 横幅，总有一路能传到你 |
| 📣 状态栏动态指示 | 喊话时状态栏/横幅变 `📢 正在广播中...`，喊完自动恢复 `🍳 离开中 · ⚠N`；不想听了按 `Ctrl+Alt+M` 停止本次（下次照常） |
| 🎵 自定义铃声 | 三段式播放：短铃声 → Agent 语音 → 你自己的歌（`/i-am-cooking sound`），到点自动停 |
| 🗣️ Agent 自由语音 | 呼喊时 agent 可原样说出想说的话（`ttsText`），不限于默认模板 |
| 📱 手机推送 | ntfy.sh（免费，零配置）— 厨房场景的关键通道 |
| 🔔 完成通知 | agent 完成任务时喊：“叮咚！好消息！任务完成了！” |
| 🗣️ 自定义呼喊短语 | 默认"agent 需要你"，可改成你喜欢的话（支持占位符） |
| 🎭 可爱 Topic | 编程/算法风自动生成（如"幻觉的提示词-483726"），保证唯一 |
| 🎛️ 动态偏好 | 从你的话里自动切换：别喊了→静音 / 完成后喊我→完成才喊 / 随时汇报→积极模式 |
| 🚀 自主等级 | 该不该喊你的阈值：谨慎(遇墙就喊) / 平衡(默认) / 放手(能不喊就不喊) |
| 🤝 多 Agent 独立 | 多个 pi 同时离开时互不干扰：同一时刻只放一个声音；关闭某个 Agent 不影响其他 |
| 🛡️ 安全网 | agent 以"？"结尾等你回复时自动喊（放手等级下仅报错才喊） |
| 🔙 语义退出 | 说"我不离开了/保持在线"→ agent 理解后关闭；或手动 `/i-am-cooking off`（关闭即告知 agent 回到在线状态，停止离开模式行为） |
| 🔊 音量控制 | 可选：离开时自动拉高音量（含解除静音），回来恢复原值 |
| 🗣️ 交互式配置 | `/i-am-cooking setup` — 向导式，含 ntfy 引导 + 预览确认 + 配错可重填 |
| 🔐 Token 安全 | 配置值支持 `${ENV_VAR}`，token 不落盘明文 |
| 🧠 用户可编辑规则 | 行为规则是 `rules.md` 单一文件，随改随生效 |
| 💻 跨平台 | Windows / macOS / Linux |

## 🎯 工作流程

```mermaid
flowchart TD
    A[🏠 在岗] --> B{用户要离开?}
    B -->|手动| C["/i-am-cooking on 备注"]
    B -->|自然语言| D["说：我去做饭了，你继续"]
    C --> E[🍳 离开模式开启]
    D --> E
    E --> F[Agent 自主推进任务<br/>按自主等级决定要不要喊你]
    F --> G{遇到什么?}
    G -->|人类墙 / 需要决策| H["shout_for_user 喊你"]
    G -->|任务完成| I["完成通知 info 级"]
    G -->|可自主解决| F
    G -->|进度节点/定时| P["📈 进度汇报（可选）<br/>小阶段或定时"]
    H --> J[📣 多路呼喊<br/>短铃声/语音/歌曲 + 弹窗/手机推送]
    I --> J
    P --> J
    J --> K["⌨️ 回来打字：补充/问问题，agent 继续"]
    K --> F
    E --> M{用户明确结束?}
    M -->|说 我不离开了／保持在线| N["agent 调 exit_cooking_mode 关闭本会话"]
    M -->|手动 /off| N
    N --> A
```

**一句话版本**：你说要走（或直接说"我去做饭了"）→ 离开模式开启 → agent 自主干活，该喊时多路呼喊你；你回来打字补充不关闭（agent 继续），明确说"我不离开了"或 `/off` 才关闭本会话（不影响其他 Agent）。

## 📦 安装

```bash
# GitHub 安装（推荐）
pi install git:github.com/Nita121388/i-am-cooking

# npm 已发布
pi install npm:i-am-cooking

# 本地开发路径（从源码调试时用）
pi install /path/to/your/local/checkout
```

安装后 `/reload` 或重启 pi 生效。

## 🚀 快速开始

```bash
/i-am-cooking setup                     # ① 配置手机推送（交互式向导）
/i-am-cooking test                      # ② 测试所有通道（声音/TTS/弹窗/手机）
/i-am-cooking on 继续做登录模块          # ③ 开启离开模式，走人
/i-am-cooking off                       # ④ 结束离开模式（关闭即告知 agent 回到在线状态）
/i-am-cooking status                    # 查看状态
```

> 💡 **开启方式有两种**：
> - **自动**：直接说"我去做饭了，你继续"、"我离开一下，有事喊我"、"I'm cooking"，agent 会**理解你的意思并自主开启**（`enter_cooking_mode`）。仅在表达非常明确时才开启，不会误开。
> - **手动**：`/i-am-cooking on [备注]`（备注可带偏好，如 `on 完成后喊我`）。

> ⚠️ **离开状态不跨会话**：任何会话启动都从"在岗"开始。上次会话开启的离开模式不会自动恢复——需要时再次开启即可。

## 📖 命令

| 命令 | 说明 | 示例 |
|---|---|---|
| `/i-am-cooking on [备注]` | 开启离开模式。备注可带偏好和自主等级 | `on 完成后喊我` / `on 谨慎点继续调研` |
| `/i-am-cooking off` | 关闭离开模式（立即告知 agent 回到在线状态、停止离开模式行为；agent 结束时会自行总结） | `off` |
| `/i-am-cooking status` | 查看模式/待处理呼喊/通道/音量/偏好/等级/防打扰参数 | `status` |
| `/i-am-cooking setup` | 交互式配置向导（手机推送 + 音量 + 自主等级） | `setup` |
| `/i-am-cooking test` | 测试所有通道，逐通道汇报真实结果 | `test` |
| `/i-am-cooking stop-sound` | 停止本次播放（只停当前，下次照常；同 `Ctrl+Alt+M`） | `stop-sound` |
| `/i-am-cooking rules` | 查看当前生效的规则 | `rules` |
| `/i-am-cooking edit-rules` | 编辑规则文件（保存即生效） | `edit-rules` |
| `/i-am-cooking reset-rules` | 规则恢复出厂默认 | `reset-rules` |
| `/i-am-cooking level [档位]` | 自主等级：`conservative`/`balanced`/`autonomous`，不填则查看 | `level autonomous` |
| `/i-am-cooking limits` | 查看/调整防打扰参数（交互式中文菜单） | `limits` |
| `/i-am-cooking sound` | 自定义呼喊铃声（交互式中文菜单） | `sound` |
| `/i-am-cooking volume` | 音量控制：查看/手动调整/离开自动拉高（交互式中文菜单） | `volume` |

子命令支持 Tab 补全：输入 `/i-am-cooking ` 后按 Tab 弹出选项。

## 🤖 Agent 工具

除了你手动敲命令，**agent 自己也会调用 4 个工具**来理解你、喊你、调整行为。这些是"人机协作"的接口：

| 工具 | 作用 | Agent 何时调用 |
|---|---|---|
| `enter_cooking_mode` | 开启离开模式 | 你说"我去做饭了/我离开一下/I'm cooking"等**非常明确**的离开表达时；不确定不调用 |
| `set_shout_sound` | 设置呼喊铃声的自定义歌曲 | 你说"帮我换个铃声""用 xxx.mp3 当提醒音"并给了具体路径时 |
| `set_volume` | 调整系统音量 | 你说"音量调大点/小点声/静音"，或呼喊前发现系统静音需解除 |
| `shout_for_user` | 大声呼喊你 | 遇到必须你处理的事（决策/凭据/审批/澄清），**先准备好交接内容（刚好够用）再喊**，或任务完成时 |
| `set_calling_preference` | 调整呼喊偏好（响不响） | 你说"别喊了"→silence、"完成后喊我"→completion_only 等 |
| `set_autonomy_level` | 调整自主等级（该不该喊） | 你说"遇墙就喊"→conservative、"能不喊就不喊"→autonomous 等 |
| `exit_cooking_mode` | 关闭离开模式 | 你说"我不离开了/保持在线/先停一下"等**明确结束**表达时；临时补充/问问题不调用 |

**`shout_for_user` 参数说明**：

| 参数 | 必填 | 说明 |
|---|---|---|
| `message` | ✅ | **交接说明（一次性最终版）**：需你做什么 + 必需的材料/凭据/步骤（仅列必要的） |
| `urgency` | ✅ | `info`（完成通知）/ `normal` / `urgent`（紧急） |
| `category` | ❌ | 分类：decision / credential / approval / clarification / help |
| `ttsText` | ❌ | **自由语音**：TTS 原样念这段，不走默认模板 |

> 这些工具在离开模式关闭时会安全降级（如 `shout_for_user` 会提示"用户就在电脑前"），不会误发呼喊。

### Agent 不能设置什么（安全边界）

| 配置 | 设置方式 | 为什么不交给 agent |
|---|---|---|
| 📱 手机推送（ntfy/webhook + token） | `/i-am-cooking setup` 向导 / 手动改 config.json | 敏感凭据，只应人工配置 |
| 🔊 音量提升开关 | `/i-am-cooking setup` 向导 | 系统级改动，需用户明确允许 |
| 🛡️ 防打扰参数 | `/i-am-cooking limits` | 护栏参数，默认值已合理，避免被误改 |
| 🧠 规则文件 rules.md | `/i-am-cooking edit-rules` / 手动编辑 | 规则是用户的意志，agent 不应自我修改 |
| 🔘 开关（sound/tts/toast） | `/i-am-cooking sound` 菜单「开关」 | 可选开关，命令已支持 |
| 🔙 离开模式退出 | `exit_cooking_mode` 工具（agent 语义判断）或 `/off` 命令 | 需用户明确结束表达才关闭，不误关 |

## 🧠 用户可编辑规则

agent 离开模式的行为规则不是写死的，你可以自己改：

```
/i-am-cooking edit-rules    # 打开编辑器改规则（保存即生效）
/i-am-cooking rules         # 查看当前生效规则
/i-am-cooking reset-rules   # 恢复出厂默认（从 rules.default.md 拷贝）
```

规则文件在 `~/.pi/i-am-cooking/rules.md`（Markdown），**首次启动插件时自动创建**（从出厂默认模板拷贝）——直接去这个文件夹改就行，任何编辑器都能编辑，它就是唯一生效的规则。

**出厂默认模板**在仓库里：`extensions/i-am-cooking/rules.default.md`（进 git，随插件版本更新）。开发时直接看/改这份文件；用户首次运行时会自动拷贝一份到 `~/.pi/i-am-cooking/rules.md`，之后完全由用户接管。

### ⏰ 什么时候生效？

规则**每回合实时读取、零缓存**——`before_agent_start` 时插件重新读文件并注入 system prompt。所以：

```
你在任何编辑器里改 rules.md → 保存
  ↓ 无需重启 / 无需 /reload / 无需重新 on
下一次 agent 回合开始 → 新规则生效
```

| 你改的内容 | 效果 |
|---|---|
| 加一条"不修改生产代码" | 下次离开回合起 agent 遵守（取决于 LLM 理解） |
| 删掉"什么时候需要喊我"段落 | 喊我时机交给自主等级指南（等级是机制层，不受影响） |
| 清空整个文件 | 只剩底线规则 + 等级指南，agent 仍不会干等 |
| 改文件但不在离开模式 | **不生效**（规则只在离开模式下注入） |
| 改仓库 `rules.default.md` | 不影响已生成的用户 rules.md；只影响未来首次安装 / `reset-rules` |

> ⚠️ 规则**只在离开模式下注入**（`before_agent_start` 会检查 `config.cooking`），普通对话中改规则不会影响 agent。

> ⚠️ 有一条**底线规则**永远追加、无法删除：*"绝不要默默结束回合等用户回复"*——防止规则被删空导致 agent 干等。

## 🧠 动态呼喊偏好

呼喊偏好管"**喊得响不响**"。agent 从你的话里自动判断，**两种方式并行**：

1. **文字匹配**（扩展代码，毫秒级）：你说"别喊了" → 立即静音，不依赖 agent
2. **语义理解**（agent）：你说"我睡会儿" → 理解为静音，调用 `set_calling_preference`

| 你说 | 模式 | 效果 |
|---|---|---|
| （不说） | `normal`（默认） | 需要你 + 完成都喊 |
| "别喊了" / "安静" / "静音" | `silence` | 全静音，只剩横幅 |
| "完成后喊我" / "干完通知我" | `completion_only` | 只有完成才响铃 |
| "只有紧急才找我" | `urgent_only` | 只有 urgent 才响铃 |
| "随时汇报" / "每步告诉我" | `eager` | 需要你 / 完成 / 进度都喊 |

## 🚀 自主等级（autonomy level）

自主等级管"**该不该喊你**"——遇到阻塞（比如**人类墙**：验证码 / 登录 / 手动点击等必须你手动处理的事）时，agent 自己解决还是喊你。**与呼喊偏好正交**：等级决定"要不要喊"，偏好决定"喊多响"，自由组合。

```
/i-am-cooking level                   # 查看当前等级
/i-am-cooking level conservative      # 谨慎：遇墙就喊
/i-am-cooking level balanced          # 平衡（默认）：有点难度才喊
/i-am-cooking level autonomous        # 放手：能不喊就不喊
```

| 等级 | 行为 |
|---|---|
| `conservative` 谨慎 | 遇到任何人类墙（验证码 / 登录 / 手动点击等）立即喊你；需要决策 / 审批 / 凭据 / 澄清先喊你确认；需求模糊先问清楚；只自主做完全确定无风险的部分 |
| `balanced` 平衡（默认） | 人类墙才喊你；普通决策 / 模糊处用最合理默认方案自主推进并注明假设；只有"自主尝试后仍无法推进"或"选错代价很大"才喊 |
| `autonomous` 放手 | 尽量不喊你；所有决策、假设自己定并记录；只有任务彻底无法继续（无权限 / 外部服务故障 / 违反硬性约束）才喊 |

> 三个等级都内置**保证质量**要求（自主 ≠ 降低标准，拿不准选最稳妥方案）。

**切换方式**（与偏好相同，4 种）：
- 命令：`/i-am-cooking level autonomous`
- `on` 备注：`on 谨慎点继续`
- 直接说："遇墙就喊我" / "能不喊就不喊"（文字匹配保险丝）
- agent 语义理解：`set_autonomy_level`

等级**持久化**（存在 config.json，跨离开会话保留），不同于偏好（偏好是会话级的）。

## 🔊 自定义呼喊铃声（高级设置）

呼喊声音按 **短铃声 → Agent 语音 → 自定义歌曲** 顺序播放，总时长到点自动停止：

```
/i-am-cooking sound
```

中文菜单支持：查看当前设置 / 设置自定义歌曲 / 试听 / 设置总时长上限（默认 60 秒）/ 清除歌曲。

**设置歌曲两种方式**：
- **文件浏览**：从 `~/Music` 开始逐级浏览（📁 文件夹 / 🔊 音频文件），选中的文件即为铃声，不用记路径
- **手动输入**：直接输入完整路径（如 `~/Music/闹铃.mp3`）

也可以直接对 agent 说"帮我换个铃声"并给出路径，agent 会调用 `set_shout_sound` 工具帮你设置。

| 环节 | 说明 |
|---|---|
| ① 短铃声 | 系统哔哔（默认 4 声） |
| ② Agent 语音 | 中文 TTS。Agent 调用 `shout_for_user` 时可带 `ttsText` **原样念自己想说的话**（如“叮咚！方案 A 和 B 我拿不准，快回来看看！”）；不填则用默认模板 |
| ③ 自定义歌曲 | 你指定的音频文件（macOS 支持 mp3/wav/m4a；Linux wav/ogg；Windows 建议 wav） |
| ⏱ 总时长 | 默认 60 秒，到点强制停止，可调（1-300 秒） |

> 格式建议：**wav 全平台通用**，mp3 在 macOS/Linux 最佳。

**三种消息，三种通道**：

| 消息 | 通道 | 例子 |
|---|---|---|
| 🚨 需要你 | 完整三段式响铃：哔哔 4 声 + 语音 + 你的歌曲（最醒目）+ 弹窗/横幅/手机 | "需要你决定方案 A 还是 B" |
| ✅ 整个完成 | 哔哔 2 声 + 完成语音（不播歌曲，安静报喜）+ 弹窗/横幅/手机 | "所有任务都完成了！" |
| 📈 进度（小阶段/定时） | **只推手机**（不响铃/不弹窗/不进横幅），本地仅一条轻提示 | "已下载 3/10 个文件" |

> 📈 **进度汇报模式（三选一）**：每次手动开启离开模式时会问"进度汇报"——① 小阶段完成时（默认）/ ② 定时（每 15 分钟，即使无进展也汇报）/ ③ 不汇报。**进度类只推送手机**（锁屏可见，不打扰）；紧急/完成通知不受影响。**任务完成（收到 ✅ 完成通知）后，定时汇报自动停止**，不再继续催进度。

### 🗣️ 自定义呼喊短语

所有呼喊文案里的"agent 需要你"（TTS / 弹窗 / 手机推送 / 横幅）可以改成任何你想听的话。改 `config.json` 里的 `shoutPhrase`：

```json
{ "shoutPhrase": "快来救我" }
```

TTS 模板里用 `{shoutPhrase}` 占位（默认 `叮咚！{shoutPhrase}！{message}`），改一处全生效。

### 📣 状态栏动态指示 & 停止本次播放

离开模式下状态栏（底部）和编辑区上方横幅保持极简，只做“信号灯”：

| 状态 | 状态栏 | 横幅 |
|---|---|---|
| 离开中、安静 | `🍳 离开中 · ⚠N 待处理` | `🍳 离开中 · ⚠N 待处理 · /status 看全部` |
| **正在喊话（响铃中）** | `📢 正在广播中...（Ctrl+Alt+M 静音）`（高亮） | 同上加一行 `📢 正在广播中...` |
| 喊完 / 被停止 | 自动恢复 `🍳 离开中 · ⚠N 待处理` | 同步恢复 |

**设计原则**：横幅只显示“计数 + 状态”，不塞具体内容——方案、进度、任务总结等详情都在对话历史里（agent 完成任务后会有总结），看 `/i-am-cooking status` 也能查全部待处理明细。所以横幅正常 1 行、响铃时最多 2 行，不占屏幕。

**你打字补充信息 = 已响应**：离开模式下你打字（回复呼喊 / 给新指示 / 补充要求），正在响的铃声会立即停止，之前的呼喊自动标记“已处理”并从横幅清掉（agent 继续自主干活；之后的呼喊是新信号，照常显示/响铃）。

**停止本次播放**（不想听这次响铃，但保留待处理呼喊）：

- 快捷键：`Ctrl+Alt+M`（M = Mute；可在 `~/.pi/agent/keybindings.json` 自定义绑定）
- 命令：`/i-am-cooking stop-sound`

停止**只掐断当前正在播放的声音**——不改任何配置、不关声音开关、不清除待处理呼喊，所以**下次呼喊照常响铃**。

> ⚠️ 说明：pi 的终端状态栏不支持鼠标点击，所以用快捷键替代“点击关闭”；按键只影响当前这个终端里正在播的声音（多 Agent 各停各的）。

**人在厨房也能远程静音（手机点按钮）**：开启离开模式后，插件会在本机启动一个小型停止端点（随机端口 + 随机 token），呼喊推送上自动带一个 **「🔕 停止响铃」按钮**——手机和电脑在同一局域网时，点一下即静音（旧呼喊同时标记已处理），agent 继续干活。仅 ntfy 推送通道支持；`off` / 会话关闭即停服并作废 token。不想用可把 `config.json` 里的 `remoteStop` 改为 `false`。

## 📱 手机推送配置

### 交互式向导（推荐）

```
/i-am-cooking setup
```

会引导你：了解 ntfy 是什么 → 装 app → 填 topic → 自动随机 topic 建议 → 预览确认（填错了可重填）→ 测试推送。

> 🎭 **Topic 自动生成**：随机组合编程/算法风可爱名字 + 6 位数字（如 `i-am-cooking-幻觉的提示词-483726`），共 5.28 亿种组合，全局唯一。不想用可以手动改。

### 手动配置

`~/.pi/i-am-cooking/config.json`：

```json
{
  "phonePush": true,
  "pushProvider": "ntfy",
  "ntfyTopic": "i-am-cooking-你的随机topic",
  "ntfyToken": "${NTFY_TOKEN}",
  "autonomyLevel": "balanced",
  "soundSeconds": 60
}
```

> 其余字段（beeps / soundPath / repeatIntervalMinutes 等）都有默认值，一般无需手改——用对应命令调整即可：`/i-am-cooking level`、`/i-am-cooking sound`、`/i-am-cooking limits`。

**ntfy 安装**：Android/iOS 搜 "ntfy" 安装 → Subscribe → 填入 topic 名即可。

也支持 Webhook（Bark / 企业微信机器人 / Server酱），见 [完整文档](docs/README.en.md)。

## 🔊 音量控制（可选）

### 手动调整 & 查看

```
/i-am-cooking volume
```

交互式中文菜单：查看当前系统音量 / 立即把音量调到指定值（0-100）/ 设置"离开时拉高到多少" / 开关"离开自动拉高"。

**Agent 也会调整音量**（`set_volume` 工具）：你说"音量调大点""小点声""静音"时，agent 帮你调；呼喊前发现系统静音也会先解除静音保证你能听到。

### 离开自动拉高（可选）

离开时自动拉高音量（防止静音听不到呼喊），回来恢复。

setup 向导里会明确问你"允许吗"，默认关闭。允许后每次 `on` 自动拉高，`off` 恢复原值。

| 平台 | 实现 |
|---|---|
| Windows | Core Audio API（PowerShell，零依赖） |
| macOS | `osascript`（系统自带，同时还原音量+静音状态） |
| Linux | `pactl`（PulseAudio） |

> macOS 细节：静音状态下（含 Mute 键触发的 muted=true），`on` 会自动解除静音并拉高音量，`off` 恢复原来的音量和静音状态。

## 🛡️ 防打扰机制（默认护栏，可调）

> 需要你 / 整个完成 / 进度（小阶段·定时）是**三种不同消息**，各自走各自的通道与限制，互不影响。

| 限制 | 作用于 | 默认值 | 调整方式 |
|---|---|---|---|
| 同一任务完成只通知一次 | ✅ 整个完成 | 不重复喊 | 固定 |
| 每次离开最多通知几次完成 | ✅ 整个完成（不同任务累计） | 3 次 | `/i-am-cooking limits` |
| 小阶段完成提醒 | 📈 小阶段完成 | ① 小阶段完成时（默认，开启时询问）；只推手机 | 开启时询问 |
| 定时汇报进度 | ⏰ 进度 | 关闭（选②时每 15 分钟）；只推手机；完成后自动停止 | 开启时询问 |
| 普通呼喊重复 | ⚠️ 普通呼喊 | **3 分钟**一次（只重复一次） | `/i-am-cooking limits` |
| 紧急呼喊反复喊 | 🚨 紧急呼喊 | **1 分钟**一次，直到你回来 | `/i-am-cooking limits` |
| 10 分钟内不重复同内容 | 所有消息 | 自动去重 | 固定 |

运行 `/i-am-cooking limits` 弹中文菜单即可调整（无需记英文参数）。

## 🤝 多 Agent 场景（多个 pi 同时离开）

同时开多个 pi（比如两个终端 / 一个终端一个 RPC）并都进入离开模式时，**各 Agent 完全独立、互不干扰**：

| 能力 | 行为 |
|---|---|
| 🔊 音频互斥 | 多个 Agent 同时喊时，同一时刻**只放一个声音**——后到的跳过声音（只留弹窗/推送/横幅），避免重叠听不清；用户主动 `/i-am-cooking test` 或试听可**抢占** |
| 🔙 独立关闭 | 关闭某个 Agent（说"我不离开了"或 `/i-am-cooking off`）**只影响它自己**，其他 Agent 继续工作，无需重新开启 |

> 崩溃恢复：Agent 进程崩溃留下的音频锁会被自动检测（进程存活检查）并抢占；超时（75 秒）兜底防误判。

## 🖥️ 平台支持

| 平台 | 声音 | 中文 TTS | 自定义歌曲 | 桌面通知 | 手机推送 | 音量控制 |
|---|---|---|---|---|---|---|
| Windows | ✅ | ✅ | ✅ wav | ✅ Toast | ✅ | ✅ |
| macOS | ✅ | ✅ say Tingting | ✅ mp3/wav/m4a | ✅ osascript | ✅ | ✅ |
| Linux | ✅¹ | ✅¹ espeak-ng | ✅¹ wav/ogg | ✅¹ notify-send | ✅ | ✅¹ |

¹ Linux：需安装对应包（canberra-gtk-play / espeak-ng / paplay / notify-send / pactl）。

## ✅ 验证清单

发布前请通过 [docs/VERIFICATION.md](docs/VERIFICATION.md)。

## 📄 许可

MIT — 详见 [LICENSE](LICENSE)。

---

**English users**: see [docs/README.en.md](docs/README.en.md) for the full English documentation.
