telegram-claude-mcp 1.6.1 ā 2.0.1
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/ARCHITECTURE.md +234 -0
- package/README.md +122 -0
- package/bin/daemon-ctl.js +207 -0
- package/bin/daemon.js +20 -0
- package/bin/proxy.js +22 -0
- package/hooks-v2/notify-hook.sh +32 -0
- package/hooks-v2/permission-hook.sh +43 -0
- package/hooks-v2/stop-hook.sh +45 -0
- package/package.json +16 -5
- package/src/daemon/index.ts +415 -0
- package/src/daemon/session-manager.ts +173 -0
- package/src/daemon/telegram-multi.ts +611 -0
- package/src/proxy/index.ts +429 -0
- package/src/shared/protocol.ts +146 -0
- package/src/telegram.ts +66 -69
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
|
-
//
|
|
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
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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
|
-
|
|
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,47 @@ export class TelegramManager {
|
|
|
375
382
|
messageIds: [...this.getSessionState().messageIds, sent.message_id],
|
|
376
383
|
});
|
|
377
384
|
|
|
378
|
-
//
|
|
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
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
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
|
-
|
|
412
|
-
|
|
413
|
-
|
|
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
|
|
424
420
|
return {
|
|
425
421
|
decision: 'block',
|
|
426
422
|
reason: response,
|
|
427
423
|
};
|
|
428
424
|
} catch (err) {
|
|
425
|
+
clearInterval(reminderInterval);
|
|
429
426
|
// Truly timed out - notify and allow stop
|
|
430
427
|
await this.bot.sendMessage(
|
|
431
428
|
this.config.chatId,
|