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

2.8 KiB
Raw Blame History

Hook 与 CLI

Hook → 子命令映射

Claude Code 事件 子命令 作用
UserPromptSubmit notify save 记录前台窗口、prompt、WT 标签、调用方图标路径
Stop notify notify 弹"任务完成"通知(自动消失,聚焦时更短)
Notification notify input 弹"需要输入"通知(常驻),按类型分标题
PreToolUseAskUserQuestion/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}.jsonsession_id 做了文件名安全过滤)。

{
  "Hwnd": 329712,            // 触发时前台窗口句柄
  "Prompt": "重构通知模块",   // 完成通知正文
  "WtRuntimeId": "42.288...",// WT 当前标签 RuntimeId(非 WT 为空)
  "CallerExePath": "...\\WindowsTerminal.exe" // 调用方 App,用于取图标
}
  • notify/input 读它来填 NotifyMessage(含点击要激活的 TargetHwnd、要切的标签、要显示的图标)。
  • cleanup 删它。若 SessionEnd 没触发(崩溃等),文件会残留在 %TEMP%,无害。

消息清洗

notify/input 投递前会把正文里的换行 / 制表 / 多余空格折叠成单行,避免撑乱 toast 布局;超长部分由 toast 的两行省略号截断。