Skip to content

Commit 6338493

Browse files
garyshengclaude
andcommitted
feat: independent desktop notification toggle (closes #47)
Add desktop_notifications config option and --notifications-on/--notifications-off CLI flags so users can control popups independently from sounds. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c5d589c commit 6338493

7 files changed

Lines changed: 103 additions & 17 deletions

File tree

README.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,14 @@ Need to mute sounds and notifications during a meeting or pairing session? Two o
4949
Other CLI commands:
5050

5151
```bash
52-
peon --pause # Mute sounds
53-
peon --resume # Unmute sounds
54-
peon --status # Check if paused or active
55-
peon --packs # List available sound packs
56-
peon --pack <name> # Switch to a specific pack
57-
peon --pack # Cycle to the next pack
52+
peon --pause # Mute sounds
53+
peon --resume # Unmute sounds
54+
peon --status # Check if paused or active
55+
peon --packs # List available sound packs
56+
peon --pack <name> # Switch to a specific pack
57+
peon --pack # Cycle to the next pack
58+
peon --notifications-on # Enable desktop notifications
59+
peon --notifications-off # Disable desktop notifications
5860
```
5961

6062
Tab completion is supported — type `peon --pack <TAB>` to see available pack names.
@@ -82,6 +84,7 @@ The config lives at `$CLAUDE_CONFIG_DIR/hooks/peon-ping/config.json` (default: `
8284
```
8385

8486
- **volume**: 0.0–1.0 (quiet enough for the office)
87+
- **desktop_notifications**: `true`/`false` — toggle desktop notification popups independently from sounds (default: `true`)
8588
- **categories**: Toggle individual sound types on/off
8689
- **annoyed_threshold / annoyed_window_seconds**: How many prompts in N seconds triggers the easter egg
8790
- **pack_rotation**: Array of pack names (e.g. `["peon", "sc_kerrigan", "peasant"]`). Each Claude Code session randomly gets one pack from the list and keeps it for the whole session. Leave empty `[]` to use `active_pack` instead.

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.5.13
1+
1.5.14

completions.bash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ _peon_completions() {
88
prev="${COMP_WORDS[COMP_CWORD-1]}"
99

1010
# Top-level options
11-
opts="--pause --resume --toggle --status --packs --pack --help"
11+
opts="--pause --resume --toggle --status --packs --pack --notifications-on --notifications-off --help"
1212

1313
if [ "$prev" = "--pack" ]; then
1414
# Complete pack names by scanning manifest files

completions.fish

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,6 @@ complete -c peon -l pack -d "Switch active sound pack" -r -a "(
1515
end
1616
end
1717
)"
18+
complete -c peon -l notifications-on -d "Enable desktop notifications"
19+
complete -c peon -l notifications-off -d "Disable desktop notifications"
1820
complete -c peon -l help -d "Show help message"

config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"active_pack": "peon",
33
"volume": 0.5,
44
"enabled": true,
5+
"desktop_notifications": true,
56
"categories": {
67
"greeting": true,
78
"acknowledge": true,

peon.sh

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,41 @@ case "${1:-}" in
282282
exit 0 ;;
283283
--status)
284284
[ -f "$PAUSED_FILE" ] && echo "peon-ping: paused" || echo "peon-ping: active"
285+
python3 -c "
286+
import json
287+
try:
288+
c = json.load(open('$CONFIG'))
289+
dn = c.get('desktop_notifications', True)
290+
print('peon-ping: desktop notifications ' + ('on' if dn else 'off'))
291+
except:
292+
print('peon-ping: desktop notifications on')
293+
"
294+
exit 0 ;;
295+
--notifications-on)
296+
python3 -c "
297+
import json
298+
config_path = '$CONFIG'
299+
try:
300+
cfg = json.load(open(config_path))
301+
except:
302+
cfg = {}
303+
cfg['desktop_notifications'] = True
304+
json.dump(cfg, open(config_path, 'w'), indent=2)
305+
print('peon-ping: desktop notifications on')
306+
"
307+
exit 0 ;;
308+
--notifications-off)
309+
python3 -c "
310+
import json
311+
config_path = '$CONFIG'
312+
try:
313+
cfg = json.load(open(config_path))
314+
except:
315+
cfg = {}
316+
cfg['desktop_notifications'] = False
317+
json.dump(cfg, open(config_path, 'w'), indent=2)
318+
print('peon-ping: desktop notifications off')
319+
"
285320
exit 0 ;;
286321
--packs)
287322
python3 -c "
@@ -364,14 +399,16 @@ print(f'peon-ping: switched to {pack_arg} ({display})')
364399
Usage: peon <command>
365400
366401
Commands:
367-
--pause Mute sounds
368-
--resume Unmute sounds
369-
--toggle Toggle mute on/off
370-
--status Check if paused or active
371-
--packs List available sound packs
372-
--pack <name> Switch to a specific pack
373-
--pack Cycle to the next pack
374-
--help Show this help
402+
--pause Mute sounds
403+
--resume Unmute sounds
404+
--toggle Toggle mute on/off
405+
--status Check if paused or active
406+
--packs List available sound packs
407+
--pack <name> Switch to a specific pack
408+
--pack Cycle to the next pack
409+
--notifications-on Enable desktop notifications
410+
--notifications-off Disable desktop notifications
411+
--help Show this help
375412
HELPEOF
376413
exit 0 ;;
377414
--*)
@@ -412,6 +449,7 @@ if str(cfg.get('enabled', True)).lower() == 'false':
412449
sys.exit(0)
413450
414451
volume = cfg.get('volume', 0.5)
452+
desktop_notif = cfg.get('desktop_notifications', True)
415453
active_pack = cfg.get('active_pack', 'peon')
416454
pack_rotation = cfg.get('pack_rotation', [])
417455
annoyed_threshold = int(cfg.get('annoyed_threshold', 3))
@@ -581,6 +619,7 @@ print('MARKER=' + q(marker))
581619
print('NOTIFY=' + q(notify))
582620
print('NOTIFY_COLOR=' + q(notify_color))
583621
print('MSG=' + q(msg))
622+
print('DESKTOP_NOTIF=' + ('true' if desktop_notif else 'false'))
584623
print('SOUND_FILE=' + q(sound_file))
585624
" <<< "$INPUT" 2>/dev/null)"
586625

@@ -641,7 +680,7 @@ if [ -n "$SOUND_FILE" ] && [ -f "$SOUND_FILE" ]; then
641680
fi
642681

643682
# --- Smart notification: only when terminal is NOT frontmost ---
644-
if [ -n "$NOTIFY" ] && [ "$PAUSED" != "true" ]; then
683+
if [ -n "$NOTIFY" ] && [ "$PAUSED" != "true" ] && [ "${DESKTOP_NOTIF:-true}" = "true" ]; then
645684
if ! terminal_is_focused; then
646685
send_notification "$MSG" "$TITLE" "${NOTIFY_COLOR:-red}"
647686
fi

tests/peon.bats

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,47 @@ JSON
360360
! afplay_was_called
361361
}
362362

363+
# ============================================================
364+
# desktop_notifications config
365+
# ============================================================
366+
367+
@test "desktop_notifications false suppresses notification but plays sound" {
368+
# Set desktop_notifications to false
369+
/usr/bin/python3 -c "
370+
import json
371+
c = json.load(open('$TEST_DIR/config.json'))
372+
c['desktop_notifications'] = False
373+
json.dump(c, open('$TEST_DIR/config.json', 'w'), indent=2)
374+
"
375+
run_peon '{"hook_event_name":"Stop","cwd":"/tmp/myproject","session_id":"s1","permission_mode":"default"}'
376+
[ "$PEON_EXIT" -eq 0 ]
377+
# Sound should still play even with notifications disabled
378+
afplay_was_called
379+
# Verify config still has desktop_notifications=false (wasn't reset)
380+
val=$(/usr/bin/python3 -c "import json; print(json.load(open('$TEST_DIR/config.json')).get('desktop_notifications', True))")
381+
[ "$val" = "False" ]
382+
}
383+
384+
@test "--notifications-off updates config" {
385+
run bash "$PEON_SH" --notifications-off
386+
[ "$status" -eq 0 ]
387+
[[ "$output" == *"desktop notifications off"* ]]
388+
# Verify config was updated
389+
val=$(/usr/bin/python3 -c "import json; print(json.load(open('$TEST_DIR/config.json')).get('desktop_notifications', True))")
390+
[ "$val" = "False" ]
391+
}
392+
393+
@test "--notifications-on updates config" {
394+
# First turn off
395+
bash "$PEON_SH" --notifications-off
396+
# Then turn on
397+
run bash "$PEON_SH" --notifications-on
398+
[ "$status" -eq 0 ]
399+
[[ "$output" == *"desktop notifications on"* ]]
400+
val=$(/usr/bin/python3 -c "import json; print(json.load(open('$TEST_DIR/config.json')).get('desktop_notifications', True))")
401+
[ "$val" = "True" ]
402+
}
403+
363404
# ============================================================
364405
# --packs (list packs)
365406
# ============================================================

0 commit comments

Comments
 (0)