Files
notify/docs/hooks-and-cli.md
T
chuan 5ce2c8a982 feat: Claude Code 原生 Windows 通知(C# / .NET 10 + Avalonia 12)
为 Claude Code 提供原生 Windows toast 通知:点击跳回原窗口、切回 Windows
Terminal 标签、跨虚拟桌面、调用方图标、非阻塞投递;NativeAOT 单文件分发。
2026-06-22 18:05:15 +08:00

61 lines
2.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Hook 与 CLI
## Hook → 子命令映射
| Claude Code 事件 | 子命令 | 作用 |
|------------------|--------|------|
| `UserPromptSubmit` | `notify save` | 记录前台窗口、prompt、WT 标签、调用方图标路径 |
| `Stop` | `notify notify` | 弹"任务完成"通知(自动消失,聚焦时更短) |
| `Notification` | `notify input` | 弹"需要输入"通知(常驻),按类型分标题 |
| `PreToolUse``AskUserQuestion`/`ExitPlanMode` | `notify input` | 提问 / 出 Plan 时弹常驻通知 |
| `SessionEnd` | `notify cleanup` | 删除该会话状态文件 |
`hooks/hooks.json`(插件形式)里命令为 `${CLAUDE_PLUGIN_ROOT}/bin/notify.exe <子命令>`;直连 `settings.json` 时可写 `notify <子命令>` 或绝对路径。
## stdin JSON
Claude Code 通过 **stdin** 把事件数据以 JSON 传入。`HookInput` 关心这几个字段:
| 字段 | 用途 |
|------|------|
| `session_id` | 状态文件隔离;为空则忽略本次 |
| `prompt` | UserPromptSubmit 的用户输入,用作"完成"通知正文 |
| `notification_type` | Notification 类型:`permission_prompt` / `idle_prompt` / `elicitation_dialog` / … |
| `message` | Notification / 提问的文本 |
| `tool_name` | PreToolUse 工具名:`AskUserQuestion` / `ExitPlanMode` |
> **注意**stdin 用 `OpenStandardInput()` 读**原始字节**再按 **UTF-8** 解码。不能用 `Console.In`——WinExe 下它不可靠,且会用控制台代码页(中文系统是 GBK)把中文解成乱码。
## 标题分流(input
| 条件 | 标题 |
|------|------|
| `tool_name == AskUserQuestion` | Claude is Asking |
| `tool_name == ExitPlanMode` | Plan Ready for Approval |
| `notification_type == permission_prompt` | Permission Required |
| `notification_type == idle_prompt` | Claude is Waiting |
| `notification_type == elicitation_dialog` | MCP Asks |
| 其它 | Input Required |
被**过滤**(不弹)的类型:`auth_success` / `elicitation_complete` / `elicitation_response`
## 状态文件
路径:`%TEMP%\claude-notify-{session_id}.json``session_id` 做了文件名安全过滤)。
```jsonc
{
"Hwnd": 329712, // 触发时前台窗口句柄
"Prompt": "重构通知模块", // 完成通知正文
"WtRuntimeId": "42.288...",// WT 当前标签 RuntimeId(非 WT 为空)
"CallerExePath": "...\\WindowsTerminal.exe" // 调用方 App,用于取图标
}
```
- `notify`/`input` 读它来填 `NotifyMessage`(含点击要激活的 `TargetHwnd`、要切的标签、要显示的图标)。
- `cleanup` 删它。若 `SessionEnd` 没触发(崩溃等),文件会残留在 `%TEMP%`,无害。
## 消息清洗
`notify`/`input` 投递前会把正文里的换行 / 制表 / 多余空格折叠成单行,避免撑乱 toast 布局;超长部分由 toast 的两行省略号截断。