给Claude 添加提示音

# Claude Code 提示音 Hook 配置迁移指南(Windows)

本文档说明如何把提示音配置从一台 Windows 电脑迁移到另一台 Windows 电脑。内容自包含:只需按步骤操作,无需复制原始文件。

> 适用环境:Windows 10 / 11,已安装 Claude Code。提示音使用 Windows 系统自带 WAV 文件,不依赖第三方软件。

## 1. 功能概览

| 场景 | Hook 事件 | Matcher | 声音 |
|——|———–|———|——|
| 计划中途提问、等待选择方案 | `PreToolUse` | `AskUserQuestion` | `Windows Notify Calendar.wav` |
| 计划完成、等待批准开工 | `PreToolUse` | `ExitPlanMode` | `Windows Notify Calendar.wav` |
| 每轮回复结束 | `Stop` | 无 | `tada.wav` |

说明:

– `AskUserQuestion` 弹出时整轮对话尚未结束,`Stop` 不会触发,因此必须单独用 `PreToolUse` 的 matcher 捕获。
– `Stop` 在每次回复结束时都触发,纯问答也会响,这是预期行为。

## 2. 需要准备的文件

“`
%USERPROFILE%\.claude\
├── settings.json # 合并其中的 hooks 段
└── hooks\
├── plan-notify.ps1
└── auto-done-notify.ps1
“`

– 两个脚本负责播放声音,需要创建。
– 音效文件使用系统自带的:
– `C:\Windows\Media\Windows Notify Calendar.wav`
– `C:\Windows\Media\tada.wav`

无需复制;文件不存在时脚本会自动退回蜂鸣(`Beep`)。
– `settings.json` 请使用**用户级**配置(`%USERPROFILE%\.claude\settings.json`),这样所有项目都会生效。

## 3. 配置步骤

### 步骤 1:创建 hooks 目录

打开 PowerShell,执行:

“`powershell
New-Item -ItemType Directory -Force “$env:USERPROFILE\.claude\hooks” | Out-Null
“`

### 步骤 2:创建两个提示音脚本

在 PowerShell 中执行下面两段命令(使用单引号 here-string,脚本内容不会被变量展开):

“`powershell
@’
try {
$null = [Console]::In.ReadToEnd()
$wav = ‘C:\Windows\Media\Windows Notify Calendar.wav’
if (Test-Path -LiteralPath $wav) {
(New-Object System.Media.SoundPlayer $wav).PlaySync()
} else {
[console]::Beep(1200, 300)
}
} catch { }
exit 0
‘@ | Set-Content -Encoding utf8 “$env:USERPROFILE\.claude\hooks\plan-notify.ps1”
“`

“`powershell
@’
try {
# 读取并丢弃 hook 传入的 JSON,避免 stdin 阻塞
$null = [Console]::In.ReadToEnd()
$wav = ‘C:\Windows\Media\tada.wav’
if (Test-Path -LiteralPath $wav) {
(New-Object System.Media.SoundPlayer $wav).PlaySync()
} else {
[console]::Beep(880, 400)
}
} catch { }
exit 0
‘@ | Set-Content -Encoding utf8 “$env:USERPROFILE\.claude\hooks\auto-done-notify.ps1”
“`

> 也可以手动创建这两个 `.ps1` 文件并粘贴上面的脚本内容,保存为 UTF-8。

### 步骤 3:配置 settings.json

把下面的内容合并到 `%USERPROFILE%\.claude\settings.json`。先把 `<用户名>` 替换为当前 Windows 用户名(可用 `$env:USERNAME` 查看):


“`json
{
“hooks”: {
“PreToolUse”: [
{
“matcher”: “AskUserQuestion|ExitPlanMode”,
“hooks”: [
{
“type”: “command”,
“command”: “C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File \”C:\\Users\\<用户名>\\.claude\\hooks\\plan-notify.ps1\””,
“timeout”: 15
}
]
}
],
“Stop”: [
{
“hooks”: [
{
“type”: “command”,
“command”: “C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File \”C:\\Users\\<用户名>\\.claude\\hooks\\auto-done-notify.ps1\””,
“timeout”: 15
}
]
}
]
}
}
“`

合并规则:

1. **目标文件不存在**:直接保存上面的内容(替换用户名后)为 `%USERPROFILE%\.claude\settings.json`。
2. **目标文件已存在**:保留原有内容,只添加/合并 `hooks` 键:
– 已有 `hooks.PreToolUse` 数组时,把 `AskUserQuestion|ExitPlanMode` 这一项加入数组;已有同名条目则跳过。
– 已有 `hooks.Stop` 数组时,把 `Stop` 这一项加入数组。
– 注意 JSON 逗号、引号必须合法,JSON 不支持注释。
3. JSON 中的 Windows 路径反斜杠必须写成双反斜杠 `\\`。

> **安全提醒**:`settings.json` 里可能有 `env` 段(例如 `ANTHROPIC_AUTH_TOKEN`、代理或模型配置),这些属于本机专属配置,**不要**随提示音配置一起复制或分享。本指南只迁移 `hooks` 段。

### 步骤 4:重新加载配置

– 重启 Claude Code;或
– 在 Claude Code 中打开一次 `/hooks` 菜单(会重新加载配置)。

之后可用 `/hooks` 查看已加载的 hooks。

## 4. 验证

### 4.1 校验 JSON 语法

“`powershell
python -c “import json,os; json.load(open(os.path.join(os.environ[‘USERPROFILE’], ‘.claude’, ‘settings.json’), encoding=’utf-8′)); print(‘JSON OK’)”
“`

若没有 Python,可跳过此步,改为在 `settings.json` 报错时检查逗号和引号。

### 4.2 模拟触发两个脚本

以下命令在 PowerShell 中执行。使用 `cmd /c` 管道是为了规避 Windows PowerShell 5.1 给管道文本加 UTF-8 BOM 的问题;脚本本身不解析 stdin,只是读取并丢弃:

“`powershell
cmd /c ‘echo {“hook_event_name”:”PreToolUse”,”tool_name”:”AskUserQuestion”}| powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File “%USERPROFILE%\.claude\hooks\plan-notify.ps1″‘
“`

应听到 `Windows Notify Calendar.wav` 的提示音。

“`powershell
cmd /c ‘echo {“hook_event_name”:”Stop”}| powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File “%USERPROFILE%\.claude\hooks\auto-done-notify.ps1″‘
“`

应听到 `tada.wav` 的提示音。

### 4.3 实际场景验证

1. 在计划模式中,Claude 用提问让你选择中间方案时 → 应响提示音。
2. 计划完成、等待你批准时 → 应响提示音。
3. 任意一轮回复结束 → 应响 `tada.wav`。

## 5. 故障排查

| 现象 | 排查方向 |
|——|———-|
| 完全没有声音 | 确认 `%USERPROFILE%\.claude\hooks\` 下两个 `.ps1` 存在;确认 `settings.json` 里的用户名路径正确;运行 4.2 的模拟命令定位问题 |
| 模拟命令有声,但 Claude Code 里不响 | 配置未加载:重启 Claude Code 或打开 `/hooks`;确认修改的是用户级 `%USERPROFILE%\.claude\settings.json`,而不是项目里的 `.claude\settings.json` |
| `settings.json` 修改后所有设置失效 | JSON 语法错误(最常见是多余/缺失逗号、路径未写 `\\`、使用了注释);用 4.1 校验 |
| 只在部分场景响 | 检查 matcher 是否为 `AskUserQuestion|ExitPlanMode`(区分大小写与拼写);`Stop` 条目不需要 matcher |
| 脚本被 PowerShell 拦截 | 配置命令已带 `-ExecutionPolicy Bypass`,一般无需修改系统执行策略;若被安全软件拦截,需放行 powershell.exe |
| 没有系统 WAV 音效 | 脚本会回退为蜂鸣声;也可以把脚本里的 `$wav` 改成其他存在的 WAV 路径 |
| 声音太小或听不到 | 检查系统音量、音量合成器以及是否处于静音/专注模式 |

## 6. 卸载 / 禁用

1. 打开 `%USERPROFILE%\.claude\settings.json`,删除 `hooks.PreToolUse` 中的 `AskUserQuestion|ExitPlanMode` 条目、`hooks.Stop` 中的对应条目;若没有其他 hooks,可删除整个 `hooks` 键。
2. 删除文件:
– `%USERPROFILE%\.claude\hooks\plan-notify.ps1`
– `%USERPROFILE%\.claude\hooks\auto-done-notify.ps1`
3. 重启 Claude Code 或打开 `/hooks` 使配置生效。

## 附:声音与脚本对照

| 脚本 | 用途 | 主要音效 | 回退 |
|——|——|———-|——|
| `plan-notify.ps1` | 计划提问 / 计划批准 | `Windows Notify Calendar.wav` | `Beep(1200, 300)` |
| `auto-done-notify.ps1` | 每轮回复结束 | `tada.wav` | `Beep(880, 400)` |