{
"env": {
"ANTHROPIC_BASE_URL": "https://api.deepseek.com/anthropic",
"ANTHROPIC_API_KEY": "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"API_TIMEOUT_MS": "3000000",
"BASH_DEFAULT_TIMEOUT_MS": "300000",
"CLAUDE_AUTOCOMPACT_PCT_OVERRIDE": "80",
"CLAUDE_CODE_ATTRIBUTION_HEADER": "0",
"CLAUDE_CODE_AUTO_COMPACT_WINDOW": "120000",
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1",
"CLAUDE_CODE_NO_FLICKER": "true",
"DISABLE_ERROR_REPORTING": "1",
"DISABLE_TELEMETRY": "1",
"ENABLE_PROMPT_CACHING_1H": "1",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "deepseek-v4-flash",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "deepseek-v4-pro",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "deepseek-v4-pro[1m]",
"skipDangerousModePermissionPrompt": "true"
},
"model": "opus",
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "~/.claude/notify.sh '⏳ 需要你的输入' && afplay /System/Library/Sounds/Hero.aiff"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "~/.claude/notify.sh '✅ 任务完成' && afplay /System/Library/Sounds/Glass.aiff"
}
]
}
]
},
"skipDangerousModePermissionPrompt": true
}
#!/bin/bash
# ~/.claude/notify.sh
# 用法: notify.sh <消息> <事件类型: stop|waiting>
message="$1"
event_type="${2:-stop}"
activate_app() {
local app_name="$1"
if [ -n "$app_name" ]; then
osascript -e "tell application \"$app_name\" to activate" >/dev/null 2>&1
fi
}
focus_apple_terminal_tty() {
local target_tty="${TTY:-$(tty 2>/dev/null)}"
[ -n "$target_tty" ] || return 1
TARGET_TTY="$target_tty" osascript >/dev/null 2>&1 <<'APPLESCRIPT'
set targetTty to system attribute "TARGET_TTY"
tell application "Terminal"
repeat with terminalWindow in windows
repeat with terminalTab in tabs of terminalWindow
if tty of terminalTab is targetTty then
set selected tab of terminalWindow to terminalTab
set index of terminalWindow to 1
activate
return
end if
end repeat
end repeat
end tell
error "No matching Terminal tab"
APPLESCRIPT
}
focus_iterm_tty() {
local target_tty="${TTY:-$(tty 2>/dev/null)}"
[ -n "$target_tty" ] || return 1
TARGET_TTY="$target_tty" osascript >/dev/null 2>&1 <<'APPLESCRIPT'
set targetTty to system attribute "TARGET_TTY"
tell application "iTerm2"
repeat with terminalWindow in windows
repeat with terminalTab in tabs of terminalWindow
repeat with terminalSession in sessions of terminalTab
if tty of terminalSession is targetTty then
select terminalSession
select terminalTab
set index of terminalWindow to 1
activate
return
end if
end repeat
end repeat
end repeat
end tell
error "No matching iTerm session"
APPLESCRIPT
}
return_to_origin_app() {
# Claude Code hooks inherit the terminal environment, so TERM_PROGRAM is the
# best lightweight signal for returning to the app that started the task.
case "$TERM_PROGRAM" in
Apple_Terminal)
focus_apple_terminal_tty && return
activate_app "Terminal" && return
;;
iTerm.app)
focus_iterm_tty && return
activate_app "iTerm" && return
activate_app "iTerm2" && return
;;
WezTerm)
activate_app "WezTerm" && return
;;
vscode)
activate_app "Cursor" && return
activate_app "Visual Studio Code" && return
;;
esac
# Fallback for Cursor-launched tasks or any environment where TERM_PROGRAM
# is missing/ambiguous.
activate_app "Cursor" || activate_app "Terminal"
}
# 获取项目名
if git rev-parse --is-inside-work-tree &>/dev/null; then
repo_name=$(basename "$(git rev-parse --show-toplevel 2>/dev/null)")
else
repo_name=$(basename "$(pwd)")
fi
# 后台发送通知,避免 Claude Code hook/手动命令被 afplay 或 say 阻塞。
(
# ① 任务完成时直接回到发起任务的应用;识别不到时回到 Cursor。
return_to_origin_app
# ② 声音提示
if [ "$event_type" = "stop" ]; then
afplay /System/Library/Sounds/Hero.aiff
else
afplay /System/Library/Sounds/Glass.aiff
fi
# ③ 语音播报(修正:Tingting 无连字符)
# 可替换为 Meijia(台湾)或 Sinji(粤语)
if [ "$event_type" = "stop" ]; then
say -v Tingting "Claude 任务完成,请查看 $repo_name"
else
say -v Tingting "Claude 需要你的输入"
fi
) >/dev/null 2>&1 &
exit 0
{ "env": { "ANTHROPIC_BASE_URL": "https://api.deepseek.com/anthropic", "ANTHROPIC_API_KEY": "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "API_TIMEOUT_MS": "3000000", "BASH_DEFAULT_TIMEOUT_MS": "300000", "CLAUDE_AUTOCOMPACT_PCT_OVERRIDE": "80", "CLAUDE_CODE_ATTRIBUTION_HEADER": "0", "CLAUDE_CODE_AUTO_COMPACT_WINDOW": "120000", "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1", "CLAUDE_CODE_NO_FLICKER": "true", "DISABLE_ERROR_REPORTING": "1", "DISABLE_TELEMETRY": "1", "ENABLE_PROMPT_CACHING_1H": "1", "ANTHROPIC_DEFAULT_HAIKU_MODEL": "deepseek-v4-flash", "ANTHROPIC_DEFAULT_SONNET_MODEL": "deepseek-v4-pro", "ANTHROPIC_DEFAULT_OPUS_MODEL": "deepseek-v4-pro[1m]", "skipDangerousModePermissionPrompt": "true" }, "model": "opus", "hooks": { "Notification": [ { "matcher": "", "hooks": [ { "type": "command", "command": "~/.claude/notify.sh '⏳ 需要你的输入' && afplay /System/Library/Sounds/Hero.aiff" } ] } ], "Stop": [ { "hooks": [ { "type": "command", "command": "~/.claude/notify.sh '✅ 任务完成' && afplay /System/Library/Sounds/Glass.aiff" } ] } ] }, "skipDangerousModePermissionPrompt": true }