@landienzla/claude-code-notify 1.0.2 → 1.0.4

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
@@ -54,10 +54,13 @@ Plugin mode requires no changes to your `settings.json` — the hook is loaded a
54
54
  | Command | Description |
55
55
  |---------|-------------|
56
56
  | `claude-code-notify setup` | Install notification hook into `~/.claude/` |
57
+ | `claude-code-notify dry-run` | Preview what setup will change (no writes) |
57
58
  | `claude-code-notify test` | Send a test notification |
58
59
  | `claude-code-notify uninstall` | Remove notification hook and script |
59
60
  | `claude-code-notify help` | Show usage info |
60
61
 
62
+ Run `dry-run` first to see exactly what files will be created/modified before committing.
63
+
61
64
  ## How It Works
62
65
 
63
66
  Claude Code fires a [`Notification`](https://docs.anthropic.com/en/docs/claude-code/hooks) hook whenever it needs your attention. This package provides a handler that:
package/bin/cli.js CHANGED
@@ -28,12 +28,55 @@ const HOOK_CONFIG = {
28
28
  ]
29
29
  };
30
30
 
31
+ function dryRun() {
32
+ console.log('Dry run — no changes will be made.\n');
33
+ console.log('The following changes would be applied:\n');
34
+ console.log(` 1. Copy notification script to:`);
35
+ console.log(` ${NOTIFY_DEST}\n`);
36
+ console.log(` 2. Add Notification hook to:`);
37
+ console.log(` ${SETTINGS_PATH}\n`);
38
+ console.log(' Hook config:');
39
+ console.log(JSON.stringify(HOOK_CONFIG, null, 2).split('\n').map(l => ' ' + l).join('\n'));
40
+
41
+ if (fs.existsSync(SETTINGS_PATH)) {
42
+ try {
43
+ const settings = JSON.parse(fs.readFileSync(SETTINGS_PATH, 'utf8'));
44
+ if (settings.hooks && settings.hooks.Notification) {
45
+ console.log('\n Warning: Existing Notification hook will be replaced.');
46
+ }
47
+ } catch (e) {
48
+ console.log(`\n Warning: ${SETTINGS_PATH} is invalid JSON and will be backed up.`);
49
+ }
50
+ }
51
+
52
+ // Check python3
53
+ const { spawnSync } = require('child_process');
54
+ const py = spawnSync('python3', ['--version'], { stdio: 'pipe' });
55
+ if (py.status !== 0) {
56
+ console.log('\n Warning: Python 3 not found. Notifications will work but show');
57
+ console.log(' generic messages instead of contextual ones.');
58
+ } else {
59
+ console.log(`\n Python 3: ${py.stdout.toString().trim()}`);
60
+ }
61
+
62
+ console.log('\nRun "claude-code-notify setup" to apply these changes.');
63
+ }
64
+
31
65
  function setup() {
32
66
  if (!fs.existsSync(CLAUDE_DIR)) {
33
67
  console.error(`Error: ${CLAUDE_DIR} does not exist. Is Claude Code installed?`);
34
68
  process.exit(1);
35
69
  }
36
70
 
71
+ // Check python3 availability
72
+ const { spawnSync } = require('child_process');
73
+ const py = spawnSync('python3', ['--version'], { stdio: 'pipe' });
74
+ if (py.status !== 0) {
75
+ console.log(' Warning: Python 3 not found. Notifications will work but show');
76
+ console.log(' generic messages instead of contextual ones.');
77
+ console.log(' Install Python 3 for full functionality.\n');
78
+ }
79
+
37
80
  // Copy notify.sh
38
81
  fs.mkdirSync(SCRIPTS_DIR, { recursive: true });
39
82
  fs.copyFileSync(NOTIFY_SRC, NOTIFY_DEST);
@@ -53,6 +96,10 @@ function setup() {
53
96
  }
54
97
  }
55
98
 
99
+ if (settings.hooks && settings.hooks.Notification) {
100
+ console.log(' Replacing existing Notification hook.');
101
+ }
102
+
56
103
  if (!settings.hooks) settings.hooks = {};
57
104
  settings.hooks.Notification = HOOK_CONFIG.Notification;
58
105
 
@@ -90,7 +137,13 @@ function uninstall() {
90
137
  function test() {
91
138
  const input = JSON.stringify({ notification_message: 'Test notification from claude-code-notify' });
92
139
  try {
93
- execSync(`echo '${input}' | bash "${NOTIFY_SRC}"`, { stdio: 'inherit', timeout: 15000 });
140
+ const { spawnSync } = require('child_process');
141
+ const result = spawnSync('bash', [NOTIFY_SRC], {
142
+ input,
143
+ stdio: ['pipe', 'inherit', 'inherit'],
144
+ timeout: 15000
145
+ });
146
+ if (result.status !== 0) throw new Error(`exit code ${result.status}`);
94
147
  console.log('Test notification sent!');
95
148
  } catch (e) {
96
149
  console.error('Test failed:', e.message);
@@ -104,6 +157,7 @@ claude-code-notify - Desktop notifications for Claude Code
104
157
 
105
158
  Usage:
106
159
  claude-code-notify setup Install notification hook into ~/.claude/
160
+ claude-code-notify dry-run Preview what setup will change (no writes)
107
161
  claude-code-notify uninstall Remove notification hook from ~/.claude/
108
162
  claude-code-notify test Send a test notification
109
163
  claude-code-notify help Show this help
@@ -117,6 +171,7 @@ const command = process.argv[2];
117
171
 
118
172
  switch (command) {
119
173
  case 'setup': setup(); break;
174
+ case 'dry-run': dryRun(); break;
120
175
  case 'uninstall': uninstall(); break;
121
176
  case 'test': test(); break;
122
177
  case 'help': case '--help': case '-h': case undefined: help(); break;
@@ -7,7 +7,7 @@ INPUT=$(cat)
7
7
  # Parse JSON and sanitize for safe shell usage
8
8
  # - Strip characters that could break shell/PowerShell/XML/AppleScript interpolation
9
9
  # - Truncate to 200 chars (OS notification display limit)
10
- MESSAGE=$(echo "$INPUT" | python3 -c "
10
+ MESSAGE=$(printf '%s' "$INPUT" | python3 -c "
11
11
  import sys, json, re
12
12
  data = json.load(sys.stdin)
13
13
  message = data.get('notification_message', data.get('message', 'Needs your attention'))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@landienzla/claude-code-notify",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Cross-platform desktop notifications for Claude Code — plugin and CLI setup tool",
5
5
  "author": "Talha <landienzla@gmail.com>",
6
6
  "license": "MIT",