claude-notification-plugin 1.0.99 → 1.0.101

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-notification-plugin",
3
- "version": "1.0.99",
3
+ "version": "1.0.101",
4
4
  "description": "Claude Code task-completion notifications: Telegram, desktop notifications (Windows/macOS/Linux), sound, and voice",
5
5
  "author": {
6
6
  "name": "Viacheslav Makarov",
package/bin/uninstall.js CHANGED
@@ -9,26 +9,48 @@ const home = os.homedir();
9
9
  const claudeDir = path.join(home, '.claude');
10
10
  const configPath = path.join(claudeDir, 'notifier.config.json');
11
11
  const settingsPath = path.join(claudeDir, 'settings.json');
12
- const statePath = path.join(claudeDir, '.notifier_state.json');
13
-
14
- const HOOK_COMMAND = 'claude-notify';
15
- const PLUGIN_KEY = 'claude-notification-plugin@bazilio-plugins';
16
- const MARKETPLACE_KEY = 'bazilio-plugins';
12
+ const statePath = path.join(claudeDir, '.notifier_state.json');
13
+
14
+ const HOOK_COMMAND = 'claude-notify';
15
+ const PLUGIN_KEY = 'claude-notification-plugin@bazilio-plugins';
16
+ const MARKETPLACE_KEY = 'bazilio-plugins';
17
+
18
+ function isPluginHookCommand (command) {
19
+ if (typeof command !== 'string') {
20
+ return false;
21
+ }
22
+
23
+ const normalized = command.trim().toLowerCase();
24
+ if (!normalized) {
25
+ return false;
26
+ }
27
+
28
+ return normalized === HOOK_COMMAND || normalized.startsWith(`${HOOK_COMMAND} `);
29
+ }
17
30
 
18
31
  // Remove hooks from settings.json
19
- if (fs.existsSync(settingsPath)) {
20
- try {
21
- const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
22
-
23
- if (settings.hooks) {
24
- for (const event of Object.keys(settings.hooks)) {
25
- settings.hooks[event] = settings.hooks[event].filter((matcher) =>
26
- !matcher.hooks?.some((h) => h.command?.includes(HOOK_COMMAND)),
27
- );
28
-
29
- if (settings.hooks[event].length === 0) {
30
- delete settings.hooks[event];
31
- }
32
+ let hooksRemoved = false;
33
+ let hooksRemoveError = '';
34
+ if (fs.existsSync(settingsPath)) {
35
+ try {
36
+ const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
37
+ let hadPluginHooks = false;
38
+
39
+ if (settings.hooks) {
40
+ for (const event of Object.keys(settings.hooks)) {
41
+ const eventHooks = Array.isArray(settings.hooks[event]) ? settings.hooks[event] : [];
42
+ const hadInEvent = eventHooks.some((matcher) =>
43
+ matcher.hooks?.some((h) => isPluginHookCommand(h.command)),
44
+ );
45
+ hadPluginHooks = hadPluginHooks || hadInEvent;
46
+
47
+ settings.hooks[event] = settings.hooks[event].filter((matcher) =>
48
+ !matcher.hooks?.some((h) => isPluginHookCommand(h.command)),
49
+ );
50
+
51
+ if (settings.hooks[event].length === 0) {
52
+ delete settings.hooks[event];
53
+ }
32
54
  }
33
55
 
34
56
  if (Object.keys(settings.hooks).length === 0) {
@@ -53,9 +75,22 @@ if (fs.existsSync(settingsPath)) {
53
75
  }
54
76
 
55
77
  fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
56
- } catch {
57
- // ignore
58
- }
78
+
79
+ // Verify hooks were actually removed
80
+ const verify = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
81
+ const remainingPluginHooks = verify.hooks
82
+ ? Object.values(verify.hooks).some((matchers) =>
83
+ Array.isArray(matchers) &&
84
+ matchers.some((m) => m.hooks?.some((h) => isPluginHookCommand(h.command))),
85
+ )
86
+ : false;
87
+ hooksRemoved = hadPluginHooks && !remainingPluginHooks;
88
+ if (hadPluginHooks && remainingPluginHooks) {
89
+ hooksRemoveError = 'Hooks still present in settings.json after removal attempt';
90
+ }
91
+ } catch (err) {
92
+ hooksRemoveError = `Failed to update settings.json: ${err.message}`;
93
+ }
59
94
  }
60
95
 
61
96
  // Remove config, state, and resolver files
@@ -66,9 +101,8 @@ for (const file of [configPath, statePath, resolverPath]) {
66
101
  }
67
102
  }
68
103
 
69
- // Remove CLI wrapper scripts
70
- // Current name + legacy names from previous versions
71
- const WRAPPER_NAMES = ['claude-notify', 'claude-notify-listener', 'claude-notify-install', 'claude-notify-uninstall'];
104
+ // Remove CLI wrapper script
105
+ const WRAPPER_NAMES = ['claude-notify'];
72
106
  let cliBinsRemoved = false;
73
107
  const ext = process.platform === 'win32' ? '.cmd' : '';
74
108
 
@@ -121,6 +155,12 @@ if (fs.existsSync(pluginCacheDir)) {
121
155
  cacheRemoved = !fs.existsSync(pluginCacheDir);
122
156
  }
123
157
 
158
+ const hooksStatus = hooksRemoved
159
+ ? 'Hooks removed from settings.json'
160
+ : hooksRemoveError
161
+ ? `Warning: ${hooksRemoveError}`
162
+ : 'No hooks found in settings.json';
163
+
124
164
  const extras = [
125
165
  pluginEntryRemoved || cacheRemoved ? 'Plugin registration cleaned.' : '',
126
166
  cliBinsRemoved ? 'CLI wrapper scripts removed.' : '',
@@ -132,13 +172,13 @@ if (cacheStillExists) {
132
172
  Warning: Could not fully remove plugin cache directory:
133
173
  ${pluginCacheDir}
134
174
  Please remove it manually.
135
- Hooks removed from settings.json
175
+ ${hooksStatus}
136
176
  Config files deleted.${extras ? `\n${extras}` : ''}
137
177
  `);
138
178
  } else {
139
179
  console.log(`
140
180
  Claude Notification Plugin uninstalled.
141
- Hooks removed from settings.json
181
+ ${hooksStatus}
142
182
  Config files deleted.${extras ? `\n${extras}` : ''}
143
183
  `);
144
184
  }
package/commit-sha CHANGED
@@ -1 +1 @@
1
- cea9eaeeae4658684c2f1977bdc09fa20916bf7c
1
+ e766d03df0c9561a16f5f2e1dff3dc896c1ee862
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "claude-notification-plugin",
3
3
  "productName": "claude-notification-plugin",
4
- "version": "1.0.99",
4
+ "version": "1.0.101",
5
5
  "description": "Claude Code task-completion notifications: Telegram, desktop notifications (Windows/macOS/Linux), sound, and voice",
6
6
  "type": "module",
7
7
  "engines": {