Skip to content

Commit dd140d4

Browse files
committed
feat: add Claude event alert hooks
1 parent fbbbe6d commit dd140d4

10 files changed

Lines changed: 607 additions & 152 deletions

File tree

README.md

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,19 @@ Desktop notifications for AI coding tools - get alerts when tasks complete or in
1313
<img src="assets/multi-tools-support-02.png" width="48%" alt="All tools enabled"/>
1414
</p>
1515

16-
[![Version](https://img.shields.io/badge/version-1.7.3-blue.svg)](https://github.com/mylee04/code-notify/releases)
16+
[![Version](https://img.shields.io/badge/version-1.7.4-blue.svg)](https://github.com/mylee04/code-notify/releases)
1717
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
1818
[![macOS](https://img.shields.io/badge/macOS-supported-green.svg)](https://www.apple.com/macos)
1919
[![Linux](https://img.shields.io/badge/Linux-supported-green.svg)](https://www.linux.org/)
2020
[![Windows](https://img.shields.io/badge/Windows-supported-green.svg)](https://www.microsoft.com/windows)
2121

2222
---
2323

24-
## What's New in v1.7.3
24+
## What's New in v1.7.4
2525

26-
- **Claude hook detection is stricter now**: `cn on claude` no longer treats arbitrary `Notification` or `Stop` entries as if code-notify were already installed
27-
- **Existing Claude hooks are preserved**: enabling or disabling code-notify now adds or removes only the managed Claude Notification/Stop commands instead of overwriting unrelated hooks
28-
- **Unix and Windows Claude config behavior stay aligned**: both runtimes now preserve custom hook entries and have regression coverage for the merge/remove path
26+
- **Claude agent/team event alerts**: `cn alerts` can now opt into `SubagentStop`, `TeammateIdle`, `TaskCompleted`, and related Claude hook events
27+
- **Less noisy subagent workflows**: Claude event hooks get their own rate-limit bucket via `CODE_NOTIFY_EVENT_RATE_LIMIT_SECONDS`
28+
- **npm package metadata fixed**: npm global install now keeps the `cn`, `cnp`, and `code-notify` binaries when published
2929

3030
---
3131

@@ -156,6 +156,14 @@ When enabled, it adds hooks that call the notification script when tasks complet
156156
{ "type": "command", "command": "notify.sh notification claude" }
157157
]
158158
}
159+
],
160+
"SubagentStop": [
161+
{
162+
"matcher": "",
163+
"hooks": [
164+
{ "type": "command", "command": "notify.sh SubagentStop claude" }
165+
]
166+
}
159167
]
160168
}
161169
}
@@ -170,18 +178,26 @@ By default, notifications only fire when the AI is idle and waiting for input (`
170178
```bash
171179
cn alerts # Show current config
172180
cn alerts add permission_prompt # Also notify on tool permission requests
181+
cn alerts add SubagentStop # Also notify when Claude subagents finish
173182
cn alerts remove permission_prompt # Remove permission notifications
174183
cn alerts reset # Back to default (idle_prompt only)
175184
```
176185

177-
| Type | Description |
178-
| -------------------- | -------------------------------------- |
179-
| `idle_prompt` | AI is waiting for your input (default) |
180-
| `permission_prompt` | AI needs tool permission (Y/n) |
181-
| `auth_success` | Authentication success |
182-
| `elicitation_dialog` | MCP tool input needed |
186+
| Type | Description |
187+
| -------------------- | ---------------------------------------------- |
188+
| `idle_prompt` | AI is waiting for your input (default) |
189+
| `permission_prompt` | AI needs tool permission (Y/n) |
190+
| `auth_success` | Authentication success |
191+
| `elicitation_dialog` | MCP tool input needed |
192+
| `SubagentStart` | Claude subagent started |
193+
| `SubagentStop` | Claude subagent completed |
194+
| `TeammateIdle` | Claude teammate is waiting for input |
195+
| `TaskCreated` | Claude agent-team task was created |
196+
| `TaskCompleted` | Claude agent-team task completed |
197+
198+
Alert-type matching applies to Claude Code notification hooks and Gemini CLI notification hooks. Claude Code agent/team events are separate hook events and are opt-in via `cn alerts add SubagentStop`, `cn alerts add TeammateIdle`, or `cn alerts add TaskCompleted`.
183199

184-
Alert-type matching currently applies to Claude Code and Gemini CLI notification hooks. Codex currently uses completion events from `notify`, so `permission_prompt` and `idle_prompt` settings do not change Codex behavior.
200+
Agent-team and subagent workflows can be noisy if `permission_prompt` is enabled. If you only want idle pings, run `cn alerts remove permission_prompt && cn on`. Codex currently uses completion events from `notify`, so `permission_prompt` and `idle_prompt` settings do not change Codex behavior.
185201

186202
## Troubleshooting
187203

bin/code-notify

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
set -e
77

88
# Version
9-
VERSION="1.7.3"
9+
VERSION="1.7.4"
1010

1111
# Determine the directory where the script is located (resolve symlinks)
1212
SCRIPT_PATH="${BASH_SOURCE[0]}"

lib/code-notify/commands/global.sh

Lines changed: 63 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -971,7 +971,7 @@ show_alerts_status() {
971971
echo " Matcher: ${CYAN}$current${RESET}"
972972
echo ""
973973

974-
echo " Active types:"
974+
echo " Claude Notification subtypes:"
975975
if is_notify_type_enabled "idle_prompt"; then
976976
echo " ${CHECK_MARK} ${GREEN}idle_prompt${RESET} - AI is waiting for your input (60+ sec idle)"
977977
else
@@ -996,14 +996,48 @@ show_alerts_status() {
996996
echo " ${MUTE} ${DIM}elicitation_dialog${RESET}"
997997
fi
998998

999+
echo ""
1000+
echo " Claude agent/team hook events:"
1001+
if is_notify_type_enabled "SubagentStart"; then
1002+
echo " ${CHECK_MARK} ${GREEN}SubagentStart${RESET} - A Claude subagent started"
1003+
else
1004+
echo " ${MUTE} ${DIM}SubagentStart${RESET}"
1005+
fi
1006+
1007+
if is_notify_type_enabled "SubagentStop"; then
1008+
echo " ${CHECK_MARK} ${GREEN}SubagentStop${RESET} - A Claude subagent completed"
1009+
else
1010+
echo " ${MUTE} ${DIM}SubagentStop${RESET}"
1011+
fi
1012+
1013+
if is_notify_type_enabled "TeammateIdle"; then
1014+
echo " ${CHECK_MARK} ${GREEN}TeammateIdle${RESET} - A Claude teammate is idle"
1015+
else
1016+
echo " ${MUTE} ${DIM}TeammateIdle${RESET}"
1017+
fi
1018+
1019+
if is_notify_type_enabled "TaskCreated"; then
1020+
echo " ${CHECK_MARK} ${GREEN}TaskCreated${RESET} - An agent-team task was created"
1021+
else
1022+
echo " ${MUTE} ${DIM}TaskCreated${RESET}"
1023+
fi
1024+
1025+
if is_notify_type_enabled "TaskCompleted"; then
1026+
echo " ${CHECK_MARK} ${GREEN}TaskCompleted${RESET} - An agent-team task completed"
1027+
else
1028+
echo " ${MUTE} ${DIM}TaskCompleted${RESET}"
1029+
fi
1030+
9991031
echo ""
10001032
info "Examples:"
10011033
echo " ${CYAN}cn alerts add permission_prompt${RESET} # Also notify on tool permission requests"
1034+
echo " ${CYAN}cn alerts add SubagentStop${RESET} # Notify when Claude subagents finish"
10021035
echo " ${CYAN}cn alerts add auth_success${RESET} # Also notify on auth success"
10031036
echo " ${CYAN}cn alerts remove permission_prompt${RESET} # Stop permission notifications"
10041037
echo " ${CYAN}cn alerts reset${RESET} # Back to idle_prompt only"
10051038
echo ""
1006-
dim "Alert-type matching currently applies to Claude Code and Gemini CLI hooks."
1039+
dim "Alert-type matching applies to Claude Code and Gemini CLI hooks."
1040+
dim "Claude agent/team events are separate hooks and are opt-in."
10071041
dim "Codex currently exposes completion events through notify, so permission_prompt/idle_prompt settings do not change Codex behavior."
10081042
echo ""
10091043
dim "After changing, run 'cn on' to apply the new settings."
@@ -1016,23 +1050,28 @@ show_available_alert_types() {
10161050
echo " ${CYAN}permission_prompt${RESET} - AI needs tool permission (can be noisy)"
10171051
echo " ${CYAN}auth_success${RESET} - Authentication success"
10181052
echo " ${CYAN}elicitation_dialog${RESET} - MCP tool input needed"
1053+
echo ""
1054+
echo "Claude agent/team hook events:"
1055+
echo " ${CYAN}SubagentStart${RESET} - A Claude subagent started"
1056+
echo " ${CYAN}SubagentStop${RESET} - A Claude subagent completed"
1057+
echo " ${CYAN}TeammateIdle${RESET} - A Claude teammate is idle"
1058+
echo " ${CYAN}TaskCreated${RESET} - An agent-team task was created"
1059+
echo " ${CYAN}TaskCompleted${RESET} - An agent-team task completed"
1060+
echo ""
1061+
echo "Aliases like ${CYAN}subagent_stop${RESET}, ${CYAN}teammate-idle${RESET}, and ${CYAN}task_completed${RESET} are accepted."
10191062
}
10201063

10211064
# Add an alert type
10221065
add_alert_type() {
1023-
local type="$1"
1066+
local type
1067+
type="$(normalize_alert_type "$1" 2>/dev/null || true)"
10241068

1025-
# Validate type
1026-
case "$type" in
1027-
"idle_prompt"|"permission_prompt"|"auth_success"|"elicitation_dialog")
1028-
;;
1029-
*)
1030-
error "Unknown notification type: $type"
1031-
echo ""
1032-
show_available_alert_types
1033-
return 1
1034-
;;
1035-
esac
1069+
if [[ -z "$type" ]]; then
1070+
error "Unknown notification type: $1"
1071+
echo ""
1072+
show_available_alert_types
1073+
return 1
1074+
fi
10361075

10371076
if is_notify_type_enabled "$type"; then
10381077
warning "$type is already enabled"
@@ -1047,7 +1086,15 @@ add_alert_type() {
10471086

10481087
# Remove an alert type
10491088
remove_alert_type() {
1050-
local type="$1"
1089+
local type
1090+
type="$(normalize_alert_type "$1" 2>/dev/null || true)"
1091+
1092+
if [[ -z "$type" ]]; then
1093+
error "Unknown notification type: $1"
1094+
echo ""
1095+
show_available_alert_types
1096+
return 1
1097+
fi
10511098

10521099
if ! is_notify_type_enabled "$type"; then
10531100
warning "$type is not currently enabled"
@@ -1084,6 +1131,7 @@ show_alerts_help() {
10841131
echo "Examples:"
10851132
echo " cn alerts # Show current config"
10861133
echo " cn alerts add permission_prompt # Also notify on permission requests"
1134+
echo " cn alerts add SubagentStop # Also notify when Claude subagents finish"
10871135
echo " cn alerts remove permission_prompt"
10881136
echo " cn alerts reset # Back to idle_prompt only"
10891137
}

0 commit comments

Comments
 (0)