claude-notification-plugin 1.1.97 โ†’ 1.1.98

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.1.97",
3
+ "version": "1.1.98",
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/README.md CHANGED
@@ -251,6 +251,7 @@ Projects are referenced with the `&` prefix (e.g. `&api`, `&api/branch`).
251
251
  | `/cancel &project[/branch]` | Cancel the active task |
252
252
  | `/drop &project N` | Remove task N from queue |
253
253
  | `/clear &project[/branch]` | Clear queue + reset session |
254
+ | `/clearchat` | Delete the bot's messages in this chat (private chats: bot's own; groups: all if admin) |
254
255
  | `/newsession [&project[/branch]]` | Reset session only (keep queue) |
255
256
  | `/projects` | List projects and paths |
256
257
  | `/addproject <alias> <path>` | Register a project alias |
package/commit-sha CHANGED
@@ -1 +1 @@
1
- a8a48c155fceb62317866537f758bed0f6a7213b
1
+ d616d4330e2f4b80ffc5c66df77e2dc6ab72f6bc
@@ -608,7 +608,7 @@ function formatDuration (ms) {
608
608
  // COMMAND HANDLERS
609
609
  // ----------------------
610
610
 
611
- async function handleCommand (cmd, args) {
611
+ async function handleCommand (cmd, args, messageId) {
612
612
  switch (cmd) {
613
613
  case '/status':
614
614
  return handleStatus(args);
@@ -620,6 +620,8 @@ async function handleCommand (cmd, args) {
620
620
  return handleDrop(args);
621
621
  case '/clear':
622
622
  return handleClear(args);
623
+ case '/clearchat':
624
+ return handleClearChat(messageId);
623
625
  case '/newsession':
624
626
  return handleNewSession(args);
625
627
  case '/projects':
@@ -842,6 +844,43 @@ function handleClear (args) {
842
844
  return `๐Ÿงน [${escapeHtml(label)}] Queue cleared (${count} tasks), session reset`;
843
845
  }
844
846
 
847
+ // Sweep deletes the bot's outgoing messages in the private chat. We can't
848
+ // know the bot's message-id range, so we walk backwards from the user's
849
+ // /clearchat command id and ask Telegram to delete each id. The bot has no
850
+ // permission to delete the user's own messages in private chats โ€” those
851
+ // requests fail silently and don't count. We stop early when an entire
852
+ // parallel batch comes back as failures (we've passed the bot's recent
853
+ // outputs into a stretch of user-only messages, or hit the 48h delete window).
854
+ async function handleClearChat (messageId) {
855
+ if (!messageId || messageId < 2) {
856
+ return 'โŒ /clearchat needs a message context';
857
+ }
858
+ const BATCH = 25; // โ‰ค Telegram's 30 req/sec ceiling for a single chat
859
+ const MAX_LOOKBACK = 5000;
860
+
861
+ let deleted = 0;
862
+ let attempted = 0;
863
+ let cursor = messageId - 1;
864
+ while (cursor > 0 && attempted < MAX_LOOKBACK) {
865
+ const ids = [];
866
+ for (let i = 0; i < BATCH && cursor - i > 0; i++) {
867
+ ids.push(cursor - i);
868
+ }
869
+ const results = await Promise.all(ids.map((id) => poller.deleteMessage(id)));
870
+ attempted += results.length;
871
+ const ok = results.filter(Boolean).length;
872
+ deleted += ok;
873
+ cursor -= BATCH;
874
+ if (ok === 0) {
875
+ break;
876
+ }
877
+ }
878
+ // Also drop the user's /clearchat command itself โ€” works only if Telegram
879
+ // accepts it (e.g. bot is admin in a group); silently skipped in private chats.
880
+ await poller.deleteMessage(messageId);
881
+ return `๐Ÿงน Deleted ${deleted} of ${attempted} bot messages.`;
882
+ }
883
+
845
884
  function handleNewSession (args) {
846
885
  const target = parseTarget(args);
847
886
  const projectAlias = target?.project || getDefaultProject(listenerConfig.projects);
@@ -1444,6 +1483,7 @@ function handleHelp () {
1444
1483
  /cancel [&project[/branch]] โ€” cancel task
1445
1484
  /drop &project N โ€” remove task from queue
1446
1485
  /clear &project[/branch] โ€” clear queue + reset session
1486
+ /clearchat โ€” delete the bot's messages in this chat (private chats: bot's own; groups: all if admin)
1447
1487
  /newsession [&project[/branch]] โ€” reset session (keep queue)
1448
1488
  /projects โ€” list projects
1449
1489
  /addproject &lt;alias&gt; &lt;path-or-/basename&gt; โ€” register a project
@@ -1583,7 +1623,7 @@ async function mainLoop () {
1583
1623
 
1584
1624
  if (parsed.type === 'command') {
1585
1625
  logger.info(`Command: ${parsed.cmd} ${parsed.args}`);
1586
- const response = await handleCommand(parsed.cmd, parsed.args);
1626
+ const response = await handleCommand(parsed.cmd, parsed.args, msg.messageId);
1587
1627
  if (response) {
1588
1628
  if (typeof response === 'object' && response.text) {
1589
1629
  await poller.sendMessage(response.text, msg.callbackQueryId ? null : msg.messageId, response.replyMarkup);
@@ -1616,6 +1656,7 @@ async function mainLoop () {
1616
1656
  { command: 'history', description: 'Recent task history' },
1617
1657
  { command: 'pty', description: 'PTY session diagnostics' },
1618
1658
  { command: 'sessions', description: 'List recent CC sessions' },
1659
+ { command: 'clearchat', description: 'Delete the bot\'s messages in this chat' },
1619
1660
  { command: 'help', description: 'Show all commands' },
1620
1661
  { command: 'stop', description: 'Stop listener' },
1621
1662
  ]);
@@ -453,10 +453,12 @@ export class PtyRunner extends EventEmitter {
453
453
  this.logger.info(`Creating PTY session in ${workDir} with args: ${JSON.stringify(args)}`);
454
454
 
455
455
  const shell = process.platform === 'win32' ? 'cmd.exe' : '/bin/bash';
456
- // Switch CMD to UTF-8 codepage (65001) so non-ASCII prompts piped via
457
- // pty.write() reach claude as valid UTF-8. Without this, cmd.exe applies
458
- // the system OEM codepage to the input stream and Cyrillic/CJK bytes
459
- // arrive at claude mangled (`๏ฟฝ`), so the prompt is never submitted.
456
+ // Switch CMD to UTF-8 codepage (65001 = UTF-8, covers all Unicode:
457
+ // Cyrillic, CJK, Arabic, Hebrew, accented Latin, emoji, etc.) so non-ASCII
458
+ // prompts piped via pty.write() reach claude as valid UTF-8. Without this,
459
+ // cmd.exe applies the system OEM codepage to the input stream and any
460
+ // multi-byte UTF-8 sequence arrives at claude mangled (`๏ฟฝ`), so the
461
+ // prompt is never submitted.
460
462
  // `chcp` and `&` MUST be separate argv tokens โ€” bundling them into one
461
463
  // string ("chcp 65001 & claude") trips cmd.exe's argument parser.
462
464
  const shellArgs = process.platform === 'win32'
@@ -194,10 +194,10 @@ export class TelegramPoller {
194
194
 
195
195
  async deleteMessage (messageId) {
196
196
  if (!messageId) {
197
- return;
197
+ return false;
198
198
  }
199
199
  try {
200
- await fetch(`${this.baseUrl}/deleteMessage`, {
200
+ const res = await fetch(`${this.baseUrl}/deleteMessage`, {
201
201
  method: 'POST',
202
202
  headers: { 'Content-Type': 'application/json' },
203
203
  body: JSON.stringify({
@@ -205,8 +205,11 @@ export class TelegramPoller {
205
205
  message_id: messageId,
206
206
  }),
207
207
  });
208
+ const data = await res.json();
209
+ return !!data.ok;
208
210
  } catch (err) {
209
211
  this.logger.error(`deleteMessage error: ${err.message}`);
212
+ return false;
210
213
  }
211
214
  }
212
215
 
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.1.97",
4
+ "version": "1.1.98",
5
5
  "description": "Claude Code task-completion notifications: Telegram, desktop notifications (Windows/macOS/Linux), sound, and voice",
6
6
  "type": "module",
7
7
  "engines": {