@landienzla/claude-code-notify 1.0.5 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,17 +1,23 @@
1
1
  # claude-code-notify
2
2
 
3
+ [![CI](https://github.com/Landienzla/claude-code-notify/actions/workflows/ci.yml/badge.svg)](https://github.com/Landienzla/claude-code-notify/actions/workflows/ci.yml)
4
+ [![npm](https://img.shields.io/npm/v/@landienzla/claude-code-notify)](https://www.npmjs.com/package/@landienzla/claude-code-notify)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
3
7
  Cross-platform desktop notifications for [Claude Code](https://docs.anthropic.com/en/docs/claude-code). Get notified when Claude Code needs your attention — permission approval, task completion, idle prompts, and more.
4
8
 
5
9
  Works as a **Claude Code plugin** (zero config) or as a **CLI setup tool**.
6
10
 
7
11
  ## Platforms
8
12
 
9
- | Platform | Method | Sound |
10
- |----------|--------|-------|
11
- | Windows | Toast notification (slides in from right) | Silent |
12
- | macOS | Native notification center | Default |
13
- | Linux | `notify-send` (libnotify) | Default |
14
- | WSL | Windows toast via PowerShell | Silent |
13
+ | Platform | Method |
14
+ |----------|--------|
15
+ | Windows | Toast notification (slides in from right) |
16
+ | macOS | Native notification center |
17
+ | Linux | `notify-send` (libnotify) |
18
+ | WSL | Windows toast via PowerShell |
19
+
20
+ Notifications are **silent by default**. Use `--sound` to enable sound. Use `--name` to give your Claude a name.
15
21
 
16
22
  ## Quick Start
17
23
 
@@ -53,12 +59,16 @@ Plugin mode requires no changes to your `settings.json` — the hook is loaded a
53
59
 
54
60
  | Command | Description |
55
61
  |---------|-------------|
56
- | `claude-code-notify setup` | Install notification hook into `~/.claude/` |
62
+ | `claude-code-notify setup` | Install notification hook (silent) |
63
+ | `claude-code-notify setup --sound` | Install with sound enabled |
64
+ | `claude-code-notify setup --name "Jarvis"` | Install with a custom name |
57
65
  | `claude-code-notify dry-run` | Preview what setup will change (no writes) |
58
66
  | `claude-code-notify test` | Send a test notification |
59
67
  | `claude-code-notify uninstall` | Remove notification hook and script |
60
68
  | `claude-code-notify help` | Show usage info |
61
69
 
70
+ Options can be combined: `claude-code-notify setup --sound --name "Jarvis"`
71
+
62
72
  Run `dry-run` first to see exactly what files will be created/modified before committing.
63
73
 
64
74
  ## How It Works
package/bin/cli.js CHANGED
@@ -13,20 +13,30 @@ const NOTIFY_DEST = path.join(SCRIPTS_DIR, 'notify.sh');
13
13
  const PACKAGE_ROOT = path.resolve(__dirname, '..');
14
14
  const NOTIFY_SRC = path.join(PACKAGE_ROOT, 'hooks', 'scripts', 'notify.sh');
15
15
 
16
- const HOOK_CONFIG = {
17
- Notification: [
18
- {
19
- matcher: '',
20
- hooks: [
21
- {
22
- type: 'command',
23
- command: `bash "${NOTIFY_DEST.replace(/\\/g, '/')}"`,
24
- timeout: 10
25
- }
26
- ]
27
- }
28
- ]
29
- };
16
+ // Parse flags
17
+ const args = process.argv.slice(3);
18
+ const sound = args.includes('--sound');
19
+ const nameIdx = args.indexOf('--name');
20
+ const name = nameIdx !== -1 && args[nameIdx + 1] ? args[nameIdx + 1] : null;
21
+ const soundFlag = sound ? ' --sound' : '';
22
+ const nameFlag = name ? ` --name "${name}"` : '';
23
+
24
+ function hookConfig() {
25
+ return {
26
+ Notification: [
27
+ {
28
+ matcher: '',
29
+ hooks: [
30
+ {
31
+ type: 'command',
32
+ command: `bash "${NOTIFY_DEST.replace(/\\/g, '/')}"${soundFlag}${nameFlag}`,
33
+ timeout: 10
34
+ }
35
+ ]
36
+ }
37
+ ]
38
+ };
39
+ }
30
40
 
31
41
  function dryRun() {
32
42
  console.log('Dry run — no changes will be made.\n');
@@ -36,7 +46,7 @@ function dryRun() {
36
46
  console.log(` 2. Add Notification hook to:`);
37
47
  console.log(` ${SETTINGS_PATH}\n`);
38
48
  console.log(' Hook config:');
39
- console.log(JSON.stringify(HOOK_CONFIG, null, 2).split('\n').map(l => ' ' + l).join('\n'));
49
+ console.log(JSON.stringify(hookConfig(), null, 2).split('\n').map(l => ' ' + l).join('\n'));
40
50
 
41
51
  if (fs.existsSync(SETTINGS_PATH)) {
42
52
  try {
@@ -82,11 +92,12 @@ function setup() {
82
92
  }
83
93
 
84
94
  if (!settings.hooks) settings.hooks = {};
85
- settings.hooks.Notification = HOOK_CONFIG.Notification;
95
+ settings.hooks.Notification = hookConfig().Notification;
86
96
 
87
97
  fs.writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2) + '\n');
88
98
  console.log(` Updated ${SETTINGS_PATH}`);
89
99
 
100
+ if (name) console.log(` Notifications will appear as "${name}".`);
90
101
  console.log('\nDone! Restart Claude Code for notifications to take effect.');
91
102
  }
92
103
 
@@ -119,7 +130,10 @@ function test() {
119
130
  const input = JSON.stringify({ notification_message: 'Test notification from claude-code-notify' });
120
131
  try {
121
132
  const { spawnSync } = require('child_process');
122
- const result = spawnSync('bash', [NOTIFY_SRC], {
133
+ const scriptArgs = [NOTIFY_SRC];
134
+ if (sound) scriptArgs.push('--sound');
135
+ if (name) scriptArgs.push('--name', name);
136
+ const result = spawnSync('bash', scriptArgs, {
123
137
  input,
124
138
  stdio: ['pipe', 'inherit', 'inherit'],
125
139
  timeout: 15000
@@ -137,11 +151,15 @@ function help() {
137
151
  claude-code-notify - Desktop notifications for Claude Code
138
152
 
139
153
  Usage:
140
- claude-code-notify setup Install notification hook into ~/.claude/
141
- claude-code-notify dry-run Preview what setup will change (no writes)
142
- claude-code-notify uninstall Remove notification hook from ~/.claude/
143
- claude-code-notify test Send a test notification
144
- claude-code-notify help Show this help
154
+ claude-code-notify setup [options] Install notification hook into ~/.claude/
155
+ claude-code-notify dry-run [options] Preview what setup will change (no writes)
156
+ claude-code-notify uninstall Remove notification hook from ~/.claude/
157
+ claude-code-notify test [options] Send a test notification
158
+ claude-code-notify help Show this help
159
+
160
+ Options:
161
+ --sound Enable notification sound (default: silent)
162
+ --name <name> Give your Claude a name (e.g. --name "Jarvis")
145
163
 
146
164
  Plugin mode (no setup needed):
147
165
  claude --plugin-dir /path/to/node_modules/claude-code-notify
@@ -2,6 +2,18 @@
2
2
  # Cross-platform desktop notification for Claude Code
3
3
  # Reads hook JSON from stdin, extracts notification message, sends native OS notification
4
4
 
5
+ # Parse flags
6
+ SILENT=true
7
+ NAME="Claude Code"
8
+ while [ $# -gt 0 ]; do
9
+ case "$1" in
10
+ --sound) SILENT=false ;;
11
+ --silent) SILENT=true ;;
12
+ --name) shift; NAME="$1" ;;
13
+ esac
14
+ shift
15
+ done
16
+
5
17
  INPUT=$(cat)
6
18
 
7
19
  # Parse JSON and sanitize for safe shell usage
@@ -17,9 +29,14 @@ let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{
17
29
  });
18
30
  " 2>/dev/null)
19
31
 
20
- # Fallback if python3 parsing fails
21
32
  MESSAGE="${MESSAGE:-Needs your attention}"
22
33
 
34
+ # Build audio XML for Windows toast
35
+ AUDIO_XML=""
36
+ if [ "$SILENT" = true ]; then
37
+ AUDIO_XML='<audio silent="true"/>'
38
+ fi
39
+
23
40
  # Detect OS and send notification
24
41
  case "$(uname -s)" in
25
42
  Linux*)
@@ -29,18 +46,26 @@ case "$(uname -s)" in
29
46
  [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > \$null
30
47
  [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] > \$null
31
48
  \$xml = New-Object Windows.Data.Xml.Dom.XmlDocument
32
- \$xml.LoadXml('<toast><visual><binding template=\"ToastText01\"><text id=\"1\">$MESSAGE</text></binding></visual><audio silent=\"true\"/></toast>')
49
+ \$xml.LoadXml('<toast><visual><binding template=\"ToastText01\"><text id=\"1\">$MESSAGE</text></binding></visual>$AUDIO_XML</toast>')
33
50
  \$toast = New-Object Windows.UI.Notifications.ToastNotification \$xml
34
- [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier('Claude Code').Show(\$toast)
51
+ [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier('$NAME').Show(\$toast)
35
52
  " 2>/dev/null
36
53
  else
37
54
  # Native Linux
38
- notify-send "Claude Code" "$MESSAGE" --app-name="Claude Code" 2>/dev/null || true
55
+ if [ "$SILENT" = true ]; then
56
+ notify-send "$NAME" "$MESSAGE" --app-name="$NAME" -h string:suppress-sound:true 2>/dev/null || true
57
+ else
58
+ notify-send "$NAME" "$MESSAGE" --app-name="$NAME" 2>/dev/null || true
59
+ fi
39
60
  fi
40
61
  ;;
41
62
  Darwin*)
42
63
  # macOS
43
- osascript -e "display notification \"$MESSAGE\" with title \"Claude Code\"" 2>/dev/null || true
64
+ if [ "$SILENT" = true ]; then
65
+ osascript -e "display notification \"$MESSAGE\" with title \"$NAME\"" 2>/dev/null || true
66
+ else
67
+ osascript -e "display notification \"$MESSAGE\" with title \"$NAME\" sound name \"default\"" 2>/dev/null || true
68
+ fi
44
69
  ;;
45
70
  CYGWIN*|MINGW*|MSYS*)
46
71
  # Native Windows (Git Bash / MSYS2)
@@ -48,9 +73,9 @@ case "$(uname -s)" in
48
73
  [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > \$null
49
74
  [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] > \$null
50
75
  \$xml = New-Object Windows.Data.Xml.Dom.XmlDocument
51
- \$xml.LoadXml('<toast><visual><binding template=\"ToastText01\"><text id=\"1\">$MESSAGE</text></binding></visual><audio silent=\"true\"/></toast>')
76
+ \$xml.LoadXml('<toast><visual><binding template=\"ToastText01\"><text id=\"1\">$MESSAGE</text></binding></visual>$AUDIO_XML</toast>')
52
77
  \$toast = New-Object Windows.UI.Notifications.ToastNotification \$xml
53
- [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier('Claude Code').Show(\$toast)
78
+ [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier('$NAME').Show(\$toast)
54
79
  " 2>/dev/null
55
80
  ;;
56
81
  esac
package/package.json CHANGED
@@ -1,8 +1,14 @@
1
1
  {
2
2
  "name": "@landienzla/claude-code-notify",
3
- "version": "1.0.5",
3
+ "version": "1.1.2",
4
4
  "description": "Cross-platform desktop notifications for Claude Code — plugin and CLI setup tool",
5
5
  "author": "Talha <landienzla@gmail.com>",
6
+ "scripts": {
7
+ "test": "node --test test/cli.test.js test/notify.test.js"
8
+ },
9
+ "engines": {
10
+ "node": ">=18"
11
+ },
6
12
  "license": "MIT",
7
13
  "repository": {
8
14
  "type": "git",