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.wavC:\Windows\Media\tada.wav
无需复制;文件不存在时脚本会自动退回蜂鸣(
Beep)。 -
settings.json请使用用户级配置(%USERPROFILE%\.claude\settings.json),这样所有项目都会生效。
3. 配置步骤
步骤 1:创建 hooks 目录
打开 PowerShell,执行:
New-Item -ItemType Directory -Force "$env:USERPROFILE\.claude\hooks" | Out-Null
步骤 2:创建两个提示音脚本
在 PowerShell 中执行下面两段命令(使用单引号 here-string,脚本内容不会被变量展开):
@'
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"
@'
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 查看):
<!– hooks-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
}
]
}
]
}
}
合并规则:
- 目标文件不存在:直接保存上面的内容(替换用户名后)为
%USERPROFILE%\.claude\settings.json。 - 目标文件已存在:保留原有内容,只添加/合并
hooks键:- 已有
hooks.PreToolUse数组时,把AskUserQuestion|ExitPlanMode这一项加入数组;已有同名条目则跳过。 - 已有
hooks.Stop数组时,把Stop这一项加入数组。 - 注意 JSON 逗号、引号必须合法,JSON 不支持注释。
- 已有
- JSON 中的 Windows 路径反斜杠必须写成双反斜杠
\\。
安全提醒:
settings.json里可能有env段(例如ANTHROPIC_AUTH_TOKEN、代理或模型配置),这些属于本机专属配置,不要随提示音配置一起复制或分享。本指南只迁移hooks段。
步骤 4:重新加载配置
- 重启 Claude Code;或
- 在 Claude Code 中打开一次
/hooks菜单(会重新加载配置)。
之后可用 /hooks 查看已加载的 hooks。
4. 验证
4.1 校验 JSON 语法
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,只是读取并丢弃:
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 的提示音。
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 实际场景验证
- 在计划模式中,Claude 用提问让你选择中间方案时 → 应响提示音。
- 计划完成、等待你批准时 → 应响提示音。
- 任意一轮回复结束 → 应响
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. 卸载 / 禁用
- 打开
%USERPROFILE%\.claude\settings.json,删除hooks.PreToolUse中的AskUserQuestion|ExitPlanMode条目、hooks.Stop中的对应条目;若没有其他 hooks,可删除整个hooks键。 - 删除文件:
%USERPROFILE%\.claude\hooks\plan-notify.ps1%USERPROFILE%\.claude\hooks\auto-done-notify.ps1
- 重启 Claude Code 或打开
/hooks使配置生效。
附:声音与脚本对照
| 脚本 | 用途 | 主要音效 | 回退 |
|---|---|---|---|
plan-notify.ps1 |
计划提问 / 计划批准 | Windows Notify Calendar.wav |
Beep(1200, 300) |
auto-done-notify.ps1 |
每轮回复结束 | tada.wav |
Beep(880, 400) |