telegram-claude-mcp 1.6.1 → 2.0.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/src/telegram.ts CHANGED
@@ -209,48 +209,55 @@ export class TelegramManager {
209
209
  { chat_id: this.config.chatId, message_id: sent.message_id }
210
210
  );
211
211
 
212
- // Try with reminders
212
+ // Use a single long-lived pending permission with periodic reminders
213
+ const totalTimeoutMs = this.config.permissionTimeoutMs! + (120000 * 5); // Base timeout + 5 reminder intervals
213
214
  const reminderIntervalMs = 120000; // 2 minutes between reminders
214
- const maxReminders = 4; // Up to 4 reminders (total ~10 min with initial wait)
215
215
 
216
- for (let attempt = 0; attempt <= maxReminders; attempt++) {
217
- try {
218
- const decision = await this.waitForPermissionWithTimeout(sent.message_id, toolName, reminderIntervalMs);
219
- return decision;
220
- } catch (err) {
221
- if (attempt < maxReminders) {
222
- // Send reminder
223
- await this.bot.sendMessage(
224
- this.config.chatId,
225
- `ā° [${this.config.sessionName}] Reminder: Still waiting for permission\n\nTool: ${toolName}\n\nšŸ‘† Please respond to the message above`,
226
- { reply_to_message_id: sent.message_id }
227
- );
216
+ // Start reminder loop in background
217
+ let reminderCount = 0;
218
+ const maxReminders = 5;
219
+ const reminderInterval = setInterval(async () => {
220
+ reminderCount++;
221
+ if (reminderCount <= maxReminders) {
222
+ try {
223
+ const isLastChance = reminderCount === maxReminders;
224
+ if (isLastChance) {
225
+ // Send final reminder with new buttons
226
+ const retryMsg = await this.bot.sendMessage(
227
+ this.config.chatId,
228
+ `āš ļø [${this.config.sessionName}] Last chance! Permission will be denied soon.\n\nTool: ${toolName}\n\nClick below to respond now:`,
229
+ );
230
+ await this.bot.editMessageReplyMarkup(
231
+ {
232
+ inline_keyboard: [
233
+ [
234
+ { text: 'āœ… Allow Now', callback_data: `allow:${sent.message_id}` },
235
+ { text: 'āŒ Deny', callback_data: `deny:${sent.message_id}` },
236
+ ],
237
+ ],
238
+ },
239
+ { chat_id: this.config.chatId, message_id: retryMsg.message_id }
240
+ );
241
+ } else {
242
+ await this.bot.sendMessage(
243
+ this.config.chatId,
244
+ `ā° [${this.config.sessionName}] Reminder ${reminderCount}/${maxReminders}: Permission needed\n\nTool: ${toolName}\n\nšŸ‘† Please respond to the message above`,
245
+ { reply_to_message_id: sent.message_id }
246
+ );
247
+ }
248
+ } catch (e) {
249
+ console.error('[Telegram] Error sending reminder:', e);
228
250
  }
229
251
  }
230
- }
231
-
232
- // Final attempt: ask if they want to retry
233
- const retryMsg = await this.bot.sendMessage(
234
- this.config.chatId,
235
- `āš ļø [${this.config.sessionName}] Permission request timed out\n\nTool: ${toolName}\n\nClick below to respond now:`,
236
- );
237
-
238
- await this.bot.editMessageReplyMarkup(
239
- {
240
- inline_keyboard: [
241
- [
242
- { text: 'āœ… Allow Now', callback_data: `allow:${sent.message_id}` },
243
- { text: 'āŒ Deny', callback_data: `deny:${sent.message_id}` },
244
- ],
245
- ],
246
- },
247
- { chat_id: this.config.chatId, message_id: retryMsg.message_id }
248
- );
252
+ }, reminderIntervalMs);
249
253
 
250
- // One more wait with the original timeout
251
254
  try {
252
- return await this.waitForPermissionWithTimeout(sent.message_id, toolName, this.config.permissionTimeoutMs!);
255
+ // Wait for permission with full timeout
256
+ const decision = await this.waitForPermissionWithTimeout(sent.message_id, toolName, totalTimeoutMs);
257
+ clearInterval(reminderInterval);
258
+ return decision;
253
259
  } catch {
260
+ clearInterval(reminderInterval);
254
261
  // Truly timed out
255
262
  return { behavior: 'deny', message: 'Permission request timed out after multiple reminders' };
256
263
  }
@@ -375,57 +382,50 @@ export class TelegramManager {
375
382
  messageIds: [...this.getSessionState().messageIds, sent.message_id],
376
383
  });
377
384
 
378
- // Try with reminders
385
+ // Use a single long-lived pending response with periodic reminders
386
+ const totalTimeoutMs = this.config.responseTimeoutMs! + (120000 * 5); // Base timeout + 5 reminder intervals
379
387
  const reminderIntervalMs = 120000; // 2 minutes between reminders
380
- const maxReminders = 4; // Up to 4 reminders
381
388
 
382
- for (let attempt = 0; attempt <= maxReminders; attempt++) {
383
- try {
384
- const response = await this.waitForResponseWithTimeout(sent.message_id, reminderIntervalMs);
385
-
386
- // Check if user wants to stop
387
- const lowerResponse = response.toLowerCase().trim();
388
- if (lowerResponse === 'done' || lowerResponse === 'stop' || lowerResponse === 'finish' || lowerResponse === 'ok') {
389
- return {};
390
- }
391
-
392
- // User provided instructions - continue
393
- return {
394
- decision: 'block',
395
- reason: response,
396
- };
397
- } catch (err) {
398
- if (attempt < maxReminders) {
399
- // Send reminder
400
- await this.bot.sendMessage(
401
- this.config.chatId,
402
- `ā° [${this.config.sessionName}] Reminder: Claude is waiting for your response\n\nšŸ’¬ Reply with instructions to continue, or "done" to let Claude stop`,
403
- { reply_to_message_id: sent.message_id }
404
- );
389
+ // Start reminder loop in background
390
+ let reminderCount = 0;
391
+ const maxReminders = 5;
392
+ const reminderInterval = setInterval(async () => {
393
+ reminderCount++;
394
+ if (reminderCount <= maxReminders) {
395
+ try {
396
+ const isLastChance = reminderCount === maxReminders;
397
+ const message = isLastChance
398
+ ? `āš ļø [${this.config.sessionName}] Last chance! Claude will stop soon if no response.\n\nšŸ’¬ Reply now to continue working.`
399
+ : `ā° [${this.config.sessionName}] Reminder ${reminderCount}/${maxReminders}: Claude is waiting\n\nšŸ’¬ Reply with instructions to continue, or "done" to stop`;
400
+
401
+ await this.bot.sendMessage(this.config.chatId, message, { reply_to_message_id: sent.message_id });
402
+ } catch (e) {
403
+ console.error('[Telegram] Error sending reminder:', e);
405
404
  }
406
405
  }
407
- }
406
+ }, reminderIntervalMs);
408
407
 
409
- // Final attempt with longer timeout
410
408
  try {
411
- await this.bot.sendMessage(
412
- this.config.chatId,
413
- `āš ļø [${this.config.sessionName}] Last chance! Claude will stop in ${Math.round(this.config.responseTimeoutMs! / 60000)} minutes if no response.\n\nšŸ’¬ Reply now to continue working.`,
414
- { reply_to_message_id: sent.message_id }
415
- );
416
-
417
- const response = await this.waitForResponseWithTimeout(sent.message_id, this.config.responseTimeoutMs!);
409
+ // Wait for response with full timeout
410
+ const response = await this.waitForResponseWithTimeout(sent.message_id, totalTimeoutMs);
411
+ clearInterval(reminderInterval);
418
412
 
413
+ // Check if user wants to stop
419
414
  const lowerResponse = response.toLowerCase().trim();
420
415
  if (lowerResponse === 'done' || lowerResponse === 'stop' || lowerResponse === 'finish' || lowerResponse === 'ok') {
421
416
  return {};
422
417
  }
423
418
 
419
+ // User provided instructions - continue
420
+ // Include multiple fields for compatibility with different Claude Code versions
424
421
  return {
425
422
  decision: 'block',
426
423
  reason: response,
424
+ continue: true,
425
+ stopReason: response,
427
426
  };
428
427
  } catch (err) {
428
+ clearInterval(reminderInterval);
429
429
  // Truly timed out - notify and allow stop
430
430
  await this.bot.sendMessage(
431
431
  this.config.chatId,