tg-claude 0.1.0

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.
Files changed (111) hide show
  1. package/README.md +175 -0
  2. package/bin/cli.js +2 -0
  3. package/dist/claude/ClaudeProcess.d.ts +77 -0
  4. package/dist/claude/ClaudeProcess.d.ts.map +1 -0
  5. package/dist/claude/ClaudeProcess.js +270 -0
  6. package/dist/claude/ClaudeProcess.js.map +1 -0
  7. package/dist/claude/EventAdapter.d.ts +44 -0
  8. package/dist/claude/EventAdapter.d.ts.map +1 -0
  9. package/dist/claude/EventAdapter.js +129 -0
  10. package/dist/claude/EventAdapter.js.map +1 -0
  11. package/dist/claude/index.d.ts +10 -0
  12. package/dist/claude/index.d.ts.map +1 -0
  13. package/dist/claude/index.js +9 -0
  14. package/dist/claude/index.js.map +1 -0
  15. package/dist/claude/types.d.ts +244 -0
  16. package/dist/claude/types.d.ts.map +1 -0
  17. package/dist/claude/types.js +8 -0
  18. package/dist/claude/types.js.map +1 -0
  19. package/dist/env.d.ts +21 -0
  20. package/dist/env.d.ts.map +1 -0
  21. package/dist/env.js +49 -0
  22. package/dist/env.js.map +1 -0
  23. package/dist/index.d.ts +2 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +360 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/parser/AnsiStripper.d.ts +54 -0
  28. package/dist/parser/AnsiStripper.d.ts.map +1 -0
  29. package/dist/parser/AnsiStripper.js +115 -0
  30. package/dist/parser/AnsiStripper.js.map +1 -0
  31. package/dist/parser/OptionExtractor.d.ts +31 -0
  32. package/dist/parser/OptionExtractor.d.ts.map +1 -0
  33. package/dist/parser/OptionExtractor.js +91 -0
  34. package/dist/parser/OptionExtractor.js.map +1 -0
  35. package/dist/parser/OutputParser.d.ts +121 -0
  36. package/dist/parser/OutputParser.d.ts.map +1 -0
  37. package/dist/parser/OutputParser.js +306 -0
  38. package/dist/parser/OutputParser.js.map +1 -0
  39. package/dist/parser/PromptDetector.d.ts +20 -0
  40. package/dist/parser/PromptDetector.d.ts.map +1 -0
  41. package/dist/parser/PromptDetector.js +68 -0
  42. package/dist/parser/PromptDetector.js.map +1 -0
  43. package/dist/parser/index.d.ts +7 -0
  44. package/dist/parser/index.d.ts.map +1 -0
  45. package/dist/parser/index.js +5 -0
  46. package/dist/parser/index.js.map +1 -0
  47. package/dist/parser/types.d.ts +73 -0
  48. package/dist/parser/types.d.ts.map +1 -0
  49. package/dist/parser/types.js +2 -0
  50. package/dist/parser/types.js.map +1 -0
  51. package/dist/pty/OutputBuffer.d.ts +39 -0
  52. package/dist/pty/OutputBuffer.d.ts.map +1 -0
  53. package/dist/pty/OutputBuffer.js +55 -0
  54. package/dist/pty/OutputBuffer.js.map +1 -0
  55. package/dist/pty/PtyProcess.d.ts +47 -0
  56. package/dist/pty/PtyProcess.d.ts.map +1 -0
  57. package/dist/pty/PtyProcess.js +94 -0
  58. package/dist/pty/PtyProcess.js.map +1 -0
  59. package/dist/pty/PtyService.d.ts +55 -0
  60. package/dist/pty/PtyService.d.ts.map +1 -0
  61. package/dist/pty/PtyService.js +115 -0
  62. package/dist/pty/PtyService.js.map +1 -0
  63. package/dist/pty/index.d.ts +5 -0
  64. package/dist/pty/index.d.ts.map +1 -0
  65. package/dist/pty/index.js +4 -0
  66. package/dist/pty/index.js.map +1 -0
  67. package/dist/pty/types.d.ts +36 -0
  68. package/dist/pty/types.d.ts.map +1 -0
  69. package/dist/pty/types.js +2 -0
  70. package/dist/pty/types.js.map +1 -0
  71. package/dist/router/BoundedQueue.d.ts +57 -0
  72. package/dist/router/BoundedQueue.d.ts.map +1 -0
  73. package/dist/router/BoundedQueue.js +86 -0
  74. package/dist/router/BoundedQueue.js.map +1 -0
  75. package/dist/router/EventRouter.d.ts +103 -0
  76. package/dist/router/EventRouter.d.ts.map +1 -0
  77. package/dist/router/EventRouter.js +169 -0
  78. package/dist/router/EventRouter.js.map +1 -0
  79. package/dist/router/index.d.ts +13 -0
  80. package/dist/router/index.d.ts.map +1 -0
  81. package/dist/router/index.js +12 -0
  82. package/dist/router/index.js.map +1 -0
  83. package/dist/router/types.d.ts +104 -0
  84. package/dist/router/types.d.ts.map +1 -0
  85. package/dist/router/types.js +6 -0
  86. package/dist/router/types.js.map +1 -0
  87. package/dist/telegram/TelegramBot.d.ts +151 -0
  88. package/dist/telegram/TelegramBot.d.ts.map +1 -0
  89. package/dist/telegram/TelegramBot.js +514 -0
  90. package/dist/telegram/TelegramBot.js.map +1 -0
  91. package/dist/telegram/index.d.ts +7 -0
  92. package/dist/telegram/index.d.ts.map +1 -0
  93. package/dist/telegram/index.js +6 -0
  94. package/dist/telegram/index.js.map +1 -0
  95. package/dist/telegram/types.d.ts +30 -0
  96. package/dist/telegram/types.d.ts.map +1 -0
  97. package/dist/telegram/types.js +5 -0
  98. package/dist/telegram/types.js.map +1 -0
  99. package/dist/terminal/TerminalInterface.d.ts +61 -0
  100. package/dist/terminal/TerminalInterface.d.ts.map +1 -0
  101. package/dist/terminal/TerminalInterface.js +218 -0
  102. package/dist/terminal/TerminalInterface.js.map +1 -0
  103. package/dist/terminal/index.d.ts +3 -0
  104. package/dist/terminal/index.d.ts.map +1 -0
  105. package/dist/terminal/index.js +2 -0
  106. package/dist/terminal/index.js.map +1 -0
  107. package/dist/terminal/types.d.ts +17 -0
  108. package/dist/terminal/types.d.ts.map +1 -0
  109. package/dist/terminal/types.js +2 -0
  110. package/dist/terminal/types.js.map +1 -0
  111. package/package.json +43 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TelegramBot.d.ts","sourceRoot":"","sources":["../../src/telegram/TelegramBot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AASjD;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;AAE/E;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAE3E;;;GAGG;AACH,MAAM,WAAW,kBAAmB,SAAQ,cAAc;CAEzD;AAYD;;;;;;;;;;;;GAYG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAC1B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,OAAO,CAAS;IAIxB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6B;IAG5D,UAAU,EAAE,eAAe,GAAG,IAAI,CAAQ;IAC1C,aAAa,EAAE,kBAAkB,GAAG,IAAI,CAAQ;IAGhD,OAAO,CAAC,eAAe,CAAuB;IAG9C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAuC;gBAE5D,OAAO,EAAE,kBAAkB;IAOvC;;OAEG;IACH,OAAO,CAAC,eAAe;IAyDvB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAezB;;OAEG;YAEW,kBAAkB;IAiChC;;OAEG;YAEW,YAAY;IA2C1B;;OAEG;YAEW,YAAY;IAgD1B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAuBhC;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB5B;;;OAGG;IACH,IAAI,IAAI,IAAI;IAOZ;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;;OAGG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;;OAGG;IACH,IAAI,GAAG,kDAEN;IAED;;;OAGG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKxC;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAK1C;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAItC;;;;OAIG;IACG,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IA8EjF;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAS1B;;OAEG;IACH,OAAO,CAAC,UAAU;IAOlB;;;;;OAKG;IACG,0BAA0B,CAAC,OAAO,EAAE;QACxC,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAkE/B;;OAEG;IACH,OAAO,CAAC,YAAY;IA0BpB;;;OAGG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKzC;;;OAGG;IACH,kBAAkB,IAAI,IAAI;CAM3B"}
@@ -0,0 +1,514 @@
1
+ /**
2
+ * TelegramBot class wrapping grammY Bot with composition pattern.
3
+ * Implements AUTH-01 whitelist authentication for single-user access.
4
+ */
5
+ import { Bot, InlineKeyboard, GrammyError, HttpError } from 'grammy';
6
+ import { AnsiStripper } from '../parser/AnsiStripper.js';
7
+ // Log to stderr to avoid polluting Claude's TUI on stdout
8
+ const log = (msg) => process.stderr.write(`${msg}\n`);
9
+ const logWarn = (msg) => process.stderr.write(`${msg}\n`);
10
+ const logError = (msg) => process.stderr.write(`${msg}\n`);
11
+ /**
12
+ * TelegramBot wraps grammY Bot with composition pattern.
13
+ * Provides single-user authentication and graceful lifecycle management.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const bot = new TelegramBot({
18
+ * token: process.env.TELEGRAM_BOT_TOKEN,
19
+ * allowedUserId: Number(process.env.TELEGRAM_USER_ID),
20
+ * });
21
+ * await bot.start();
22
+ * ```
23
+ */
24
+ export class TelegramBot {
25
+ bot;
26
+ allowedUserId;
27
+ started = false;
28
+ // Session-to-chat mapping (SESS-01)
29
+ // For single-user bot, all sessions route to allowedUserId
30
+ sessionChatMap = new Map();
31
+ // External handlers for response routing (RESP-01, RESP-02)
32
+ onCallback = null;
33
+ onTextMessage = null;
34
+ // Track which session is awaiting input (single-user simplification)
35
+ awaitingSession = null;
36
+ // Multi-select state keyed by message ID
37
+ multiSelectState = new Map();
38
+ constructor(options) {
39
+ this.bot = new Bot(options.token);
40
+ this.allowedUserId = options.allowedUserId;
41
+ this.setupMiddleware();
42
+ this.setupErrorHandler();
43
+ }
44
+ /**
45
+ * Set up bot middleware and command handlers.
46
+ */
47
+ setupMiddleware() {
48
+ // Auth middleware - first in chain (AUTH-01)
49
+ this.bot.use(async (ctx, next) => {
50
+ const userId = ctx.from?.id;
51
+ if (userId !== this.allowedUserId) {
52
+ logWarn(`[TELEGRAM] Unauthorized access attempt from user ${userId}`);
53
+ return; // Silently ignore unauthorized users
54
+ }
55
+ await next();
56
+ });
57
+ // /start command handler
58
+ this.bot.command('start', (ctx) => {
59
+ ctx.reply('Claude Telegram Bridge is running. You will receive notifications when Claude sessions need input.');
60
+ });
61
+ // Callback query handler for inline button clicks (RESP-01)
62
+ this.bot.on('callback_query:data', async (ctx) => {
63
+ const data = ctx.callbackQuery.data;
64
+ // Detect callback type by format
65
+ if (data.includes(':t:')) {
66
+ // Multi-select toggle: sessionId:t:optionIndex
67
+ await this.handleToggle(ctx, data);
68
+ }
69
+ else if (data.endsWith(':s')) {
70
+ // Multi-select submit: sessionId:s
71
+ await this.handleSubmit(ctx, data);
72
+ }
73
+ else {
74
+ // Single-select: sessionId:optionIndex (existing behavior)
75
+ await this.handleSingleSelect(ctx, data);
76
+ }
77
+ });
78
+ // Text message handler for freeform responses (RESP-02)
79
+ this.bot.on('message:text', async (ctx) => {
80
+ const text = ctx.message.text;
81
+ // Ignore commands (already handled by command handlers)
82
+ if (text.startsWith('/'))
83
+ return;
84
+ // Check for active awaiting session
85
+ if (!this.awaitingSession) {
86
+ await ctx.reply('No active Claude session awaiting input.');
87
+ return;
88
+ }
89
+ log(`[TELEGRAM] Text message for session ${this.awaitingSession}: "${text.slice(0, 50)}..."`);
90
+ this.onTextMessage?.(this.awaitingSession, text);
91
+ // Send confirmation reply
92
+ await ctx.reply('<i>Sent to Claude</i>', { parse_mode: 'HTML' });
93
+ // Clear awaiting state after response sent
94
+ this.awaitingSession = null;
95
+ });
96
+ }
97
+ /**
98
+ * Set up error handler for Telegram API and network errors.
99
+ */
100
+ setupErrorHandler() {
101
+ this.bot.catch((err) => {
102
+ const ctx = err.ctx;
103
+ logError(`[TELEGRAM] Error handling update ${ctx.update.update_id}:`);
104
+ const e = err.error;
105
+ if (e instanceof GrammyError) {
106
+ logError(`[TELEGRAM] Telegram API error: ${e.description}`);
107
+ }
108
+ else if (e instanceof HttpError) {
109
+ logError(`[TELEGRAM] Network error: ${e}`);
110
+ }
111
+ else {
112
+ logError(`[TELEGRAM] Unknown error: ${e}`);
113
+ }
114
+ });
115
+ }
116
+ /**
117
+ * Handle single-select button click (existing behavior, refactored)
118
+ */
119
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
120
+ async handleSingleSelect(ctx, data) {
121
+ await ctx.answerCallbackQuery({ text: 'Sending to Claude...' });
122
+ const colonIdx = data.lastIndexOf(':');
123
+ if (colonIdx === -1) {
124
+ logWarn(`[TELEGRAM] Malformed callback data: ${data}`);
125
+ return;
126
+ }
127
+ const sessionId = data.slice(0, colonIdx);
128
+ const optionIndex = parseInt(data.slice(colonIdx + 1), 10);
129
+ if (isNaN(optionIndex)) {
130
+ logWarn(`[TELEGRAM] Invalid option index: ${data}`);
131
+ return;
132
+ }
133
+ log(`[TELEGRAM] Button clicked: session=${sessionId}, option=${optionIndex}`);
134
+ // Edit message to remove buttons and show confirmation
135
+ const originalText = ctx.callbackQuery.message?.text || '';
136
+ try {
137
+ await ctx.editMessageText(`${originalText}\n\n<i>Selected: Option ${optionIndex}</i>`, { parse_mode: 'HTML' });
138
+ }
139
+ catch (err) {
140
+ log(`[TELEGRAM] Could not edit message: ${err}`);
141
+ }
142
+ this.onCallback?.(sessionId, optionIndex);
143
+ }
144
+ /**
145
+ * Handle multi-select toggle button click
146
+ */
147
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
148
+ async handleToggle(ctx, data) {
149
+ const messageId = ctx.callbackQuery.message?.message_id;
150
+ if (!messageId) {
151
+ await ctx.answerCallbackQuery({ text: 'Error: no message' });
152
+ return;
153
+ }
154
+ const state = this.multiSelectState.get(messageId);
155
+ if (!state) {
156
+ await ctx.answerCallbackQuery({ text: 'Selection expired' });
157
+ return;
158
+ }
159
+ // Parse: sessionId:t:optionIndex
160
+ const parts = data.split(':t:');
161
+ const optionIndex = parseInt(parts[1], 10) - 1; // Convert to 0-based
162
+ // Toggle selection
163
+ if (state.selectedIndices.has(optionIndex)) {
164
+ state.selectedIndices.delete(optionIndex);
165
+ await ctx.answerCallbackQuery({ text: 'Deselected' });
166
+ }
167
+ else {
168
+ state.selectedIndices.add(optionIndex);
169
+ await ctx.answerCallbackQuery({ text: 'Selected' });
170
+ }
171
+ // Rebuild keyboard with updated checkmarks
172
+ const keyboard = this.buildMultiSelectKeyboard(state.sessionId, state.options, state.selectedIndices);
173
+ try {
174
+ await ctx.editMessageReplyMarkup({ reply_markup: keyboard });
175
+ }
176
+ catch (err) {
177
+ // "message is not modified" is OK if selection visually unchanged
178
+ if (!String(err).includes('not modified')) {
179
+ log(`[TELEGRAM] Could not update keyboard: ${err}`);
180
+ }
181
+ }
182
+ }
183
+ /**
184
+ * Handle multi-select submit button click
185
+ */
186
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
187
+ async handleSubmit(ctx, data) {
188
+ const messageId = ctx.callbackQuery.message?.message_id;
189
+ if (!messageId) {
190
+ await ctx.answerCallbackQuery({ text: 'Error: no message' });
191
+ return;
192
+ }
193
+ const state = this.multiSelectState.get(messageId);
194
+ if (!state) {
195
+ await ctx.answerCallbackQuery({ text: 'Selection expired' });
196
+ return;
197
+ }
198
+ await ctx.answerCallbackQuery({ text: 'Sending to Claude...' });
199
+ // Build comma-separated labels from selected indices
200
+ const selectedLabels = Array.from(state.selectedIndices)
201
+ .sort((a, b) => a - b)
202
+ .map(idx => {
203
+ const opt = state.options[idx];
204
+ // Extract just the label (before " - description")
205
+ const labelPart = opt.text.split(' - ')[0];
206
+ return labelPart;
207
+ })
208
+ .join(', ');
209
+ const displayText = selectedLabels || 'None selected';
210
+ log(`[TELEGRAM] Multi-select submit: session=${state.sessionId}, selected="${displayText}"`);
211
+ // Edit message to show final selection
212
+ const originalText = ctx.callbackQuery.message?.text || '';
213
+ try {
214
+ await ctx.editMessageText(`${originalText}\n\n<i>Selected: ${this.escapeHtml(displayText)}</i>`, { parse_mode: 'HTML' });
215
+ }
216
+ catch (err) {
217
+ log(`[TELEGRAM] Could not edit message: ${err}`);
218
+ }
219
+ // Clean up state
220
+ this.multiSelectState.delete(messageId);
221
+ // Send response to Claude using the text handler (labels as comma-separated string)
222
+ this.onTextMessage?.(state.sessionId, selectedLabels || 'None');
223
+ }
224
+ /**
225
+ * Build multi-select keyboard with checkmarks for selected options
226
+ */
227
+ buildMultiSelectKeyboard(sessionId, options, selectedIndices) {
228
+ const keyboard = new InlineKeyboard();
229
+ for (const opt of options) {
230
+ const idx = opt.index - 1; // Convert to 0-based for Set lookup
231
+ const isSelected = selectedIndices.has(idx);
232
+ const prefix = isSelected ? '\u2713 ' : ''; // Checkmark U+2713
233
+ const buttonLabel = this.truncateButtonText(opt.text);
234
+ const label = `${prefix}${opt.index}. ${buttonLabel}`;
235
+ const callbackData = `${sessionId.slice(0, 48)}:t:${opt.index}`;
236
+ keyboard.text(label, callbackData).row();
237
+ }
238
+ // Add Submit button
239
+ keyboard.text('Submit', `${sessionId.slice(0, 50)}:s`);
240
+ return keyboard;
241
+ }
242
+ /**
243
+ * Start the bot with long polling.
244
+ * Safe to call multiple times (idempotent).
245
+ */
246
+ async start() {
247
+ if (this.started)
248
+ return;
249
+ this.started = true;
250
+ // Graceful shutdown handlers
251
+ process.once('SIGINT', () => this.stop());
252
+ process.once('SIGTERM', () => this.stop());
253
+ log('[TELEGRAM] Starting bot with long polling...');
254
+ await this.bot.start({
255
+ onStart: (botInfo) => {
256
+ log(`[TELEGRAM] Bot @${botInfo.username} started`);
257
+ },
258
+ });
259
+ }
260
+ /**
261
+ * Stop the bot gracefully.
262
+ * Safe to call multiple times (idempotent).
263
+ */
264
+ stop() {
265
+ if (!this.started)
266
+ return;
267
+ log('[TELEGRAM] Stopping bot...');
268
+ this.bot.stop();
269
+ this.started = false;
270
+ }
271
+ /**
272
+ * Check if the bot is currently running.
273
+ */
274
+ get isStarted() {
275
+ return this.started;
276
+ }
277
+ /**
278
+ * Get the chat ID for the single whitelisted user.
279
+ * For private chats, chat_id equals user_id.
280
+ */
281
+ get chatId() {
282
+ return this.allowedUserId;
283
+ }
284
+ /**
285
+ * Expose bot.api for proactive messaging.
286
+ * Used by higher layers to send notifications.
287
+ */
288
+ get api() {
289
+ return this.bot.api;
290
+ }
291
+ /**
292
+ * Register a session for notifications.
293
+ * Maps session to the whitelisted user's chat.
294
+ */
295
+ registerSession(sessionId) {
296
+ this.sessionChatMap.set(sessionId, this.allowedUserId);
297
+ log(`[TELEGRAM] Session ${sessionId} registered for notifications`);
298
+ }
299
+ /**
300
+ * Unregister a session.
301
+ */
302
+ unregisterSession(sessionId) {
303
+ this.sessionChatMap.delete(sessionId);
304
+ log(`[TELEGRAM] Session ${sessionId} unregistered`);
305
+ }
306
+ /**
307
+ * Check if a session is registered.
308
+ */
309
+ hasSession(sessionId) {
310
+ return this.sessionChatMap.has(sessionId);
311
+ }
312
+ /**
313
+ * Send a prompt notification to Telegram with inline keyboard.
314
+ * @param payload - The notification payload with question and options
315
+ * @returns Message ID if sent, undefined if session not registered
316
+ */
317
+ async sendNotification(payload) {
318
+ const chatId = this.sessionChatMap.get(payload.sessionId);
319
+ if (!chatId) {
320
+ logWarn(`[TELEGRAM] No chat mapped for session ${payload.sessionId}`);
321
+ return undefined;
322
+ }
323
+ // Build message text
324
+ const escapedQuestion = this.escapeHtml(payload.question);
325
+ let messageText = `<b>Claude needs input</b>\n\n${escapedQuestion}`;
326
+ // Add full options list with descriptions in message body
327
+ if (payload.options.length > 0) {
328
+ messageText += '\n';
329
+ for (const opt of payload.options) {
330
+ messageText += `\n<b>${opt.index}.</b> ${this.escapeHtml(opt.text)}`;
331
+ }
332
+ }
333
+ // Add context if provided (strip ANSI codes, then truncate)
334
+ if (payload.rawContext) {
335
+ const strippedContext = AnsiStripper.stripComplete(payload.rawContext);
336
+ const truncatedContext = strippedContext.length > 500
337
+ ? '...' + strippedContext.slice(-500)
338
+ : strippedContext;
339
+ messageText += `\n\n<pre>${this.escapeHtml(truncatedContext)}</pre>`;
340
+ }
341
+ // Build inline keyboard from options
342
+ let replyMarkup = undefined;
343
+ if (payload.options.length > 0) {
344
+ const keyboard = new InlineKeyboard();
345
+ if (payload.multiSelect) {
346
+ // Multi-select: toggle buttons with Submit
347
+ for (const opt of payload.options) {
348
+ // Callback data: "sessionId:t:optionIndex" for toggle
349
+ const callbackData = `${payload.sessionId.slice(0, 48)}:t:${opt.index}`;
350
+ const buttonLabel = this.truncateButtonText(opt.text);
351
+ keyboard.text(`${opt.index}. ${buttonLabel}`, callbackData).row();
352
+ }
353
+ // Add Submit button
354
+ keyboard.text('Submit', `${payload.sessionId.slice(0, 50)}:s`);
355
+ }
356
+ else {
357
+ // Single-select: immediate send (existing behavior)
358
+ for (const opt of payload.options) {
359
+ const callbackData = `${payload.sessionId.slice(0, 50)}:${opt.index}`;
360
+ const buttonLabel = this.truncateButtonText(opt.text);
361
+ keyboard.text(`${opt.index}. ${buttonLabel}`, callbackData).row();
362
+ }
363
+ }
364
+ replyMarkup = keyboard;
365
+ }
366
+ try {
367
+ const result = await this.bot.api.sendMessage(chatId, messageText, {
368
+ parse_mode: 'HTML',
369
+ reply_markup: replyMarkup,
370
+ });
371
+ log(`[TELEGRAM] Notification sent for session ${payload.sessionId}, message_id=${result.message_id}`);
372
+ // Store multi-select state for this message
373
+ if (payload.multiSelect && result) {
374
+ this.multiSelectState.set(result.message_id, {
375
+ sessionId: payload.sessionId,
376
+ question: payload.question,
377
+ options: payload.options,
378
+ selectedIndices: new Set(),
379
+ });
380
+ }
381
+ return result.message_id;
382
+ }
383
+ catch (error) {
384
+ logError(`[TELEGRAM] Failed to send notification: ${error}`);
385
+ return undefined;
386
+ }
387
+ }
388
+ /**
389
+ * Truncate button text for Telegram inline keyboards.
390
+ * Extracts label (before " - ") and truncates to max length.
391
+ * Telegram buttons have ~40-50 char visible width.
392
+ */
393
+ truncateButtonText(text, maxLength = 35) {
394
+ // Extract label only (before " - description")
395
+ const label = text.split(' - ')[0];
396
+ if (label.length <= maxLength) {
397
+ return label;
398
+ }
399
+ return label.slice(0, maxLength - 1) + '…';
400
+ }
401
+ /**
402
+ * Escape HTML special characters for Telegram HTML parse mode.
403
+ */
404
+ escapeHtml(text) {
405
+ return text
406
+ .replace(/&/g, '&amp;')
407
+ .replace(/</g, '&lt;')
408
+ .replace(/>/g, '&gt;');
409
+ }
410
+ /**
411
+ * Send a completion notification to Telegram.
412
+ * Handles long messages by splitting into multiple messages.
413
+ * @param payload - The completion payload with summary
414
+ * @returns Message ID of last message if sent, undefined if session not registered
415
+ */
416
+ async sendCompletionNotification(payload) {
417
+ const chatId = this.sessionChatMap.get(payload.sessionId);
418
+ if (!chatId) {
419
+ logWarn(`[TELEGRAM] No chat mapped for session ${payload.sessionId}`);
420
+ return undefined;
421
+ }
422
+ // Format duration if provided
423
+ const durationText = payload.duration
424
+ ? ` <i>(${Math.round(payload.duration / 1000)}s)</i>`
425
+ : '';
426
+ // Strip ANSI from summary
427
+ const cleanSummary = AnsiStripper.stripComplete(payload.summary);
428
+ const escapedSummary = this.escapeHtml(cleanSummary);
429
+ // Telegram max message length is 4096 chars
430
+ // Header takes ~50 chars, leave room for formatting
431
+ const MAX_CONTENT_LENGTH = 3900;
432
+ const header = `<b>Claude finished</b>${durationText}\n\n`;
433
+ try {
434
+ let lastMessageId;
435
+ if (escapedSummary.length <= MAX_CONTENT_LENGTH) {
436
+ // Single message
437
+ const messageText = `${header}<pre>${escapedSummary}</pre>`;
438
+ const result = await this.bot.api.sendMessage(chatId, messageText, {
439
+ parse_mode: 'HTML',
440
+ });
441
+ lastMessageId = result.message_id;
442
+ }
443
+ else {
444
+ // Split into multiple messages
445
+ const chunks = this.splitMessage(escapedSummary, MAX_CONTENT_LENGTH);
446
+ for (let i = 0; i < chunks.length; i++) {
447
+ const isFirst = i === 0;
448
+ const isLast = i === chunks.length - 1;
449
+ const partIndicator = chunks.length > 1 ? ` (${i + 1}/${chunks.length})` : '';
450
+ const messageText = isFirst
451
+ ? `${header}<pre>${chunks[i]}</pre>${partIndicator}`
452
+ : `<pre>${chunks[i]}</pre>${partIndicator}`;
453
+ const result = await this.bot.api.sendMessage(chatId, messageText, {
454
+ parse_mode: 'HTML',
455
+ });
456
+ if (isLast) {
457
+ lastMessageId = result.message_id;
458
+ }
459
+ }
460
+ }
461
+ log(`[TELEGRAM] Completion sent for session ${payload.sessionId}, message_id=${lastMessageId}`);
462
+ // Clear awaiting state since task completed
463
+ this.awaitingSession = null;
464
+ return lastMessageId;
465
+ }
466
+ catch (error) {
467
+ logError(`[TELEGRAM] Failed to send completion: ${error}`);
468
+ return undefined;
469
+ }
470
+ }
471
+ /**
472
+ * Split a long message into chunks at natural break points.
473
+ */
474
+ splitMessage(text, maxLength) {
475
+ const chunks = [];
476
+ let remaining = text;
477
+ while (remaining.length > 0) {
478
+ if (remaining.length <= maxLength) {
479
+ chunks.push(remaining);
480
+ break;
481
+ }
482
+ // Find a good break point (newline, space, or just cut)
483
+ let breakPoint = remaining.lastIndexOf('\n', maxLength);
484
+ if (breakPoint < maxLength * 0.5) {
485
+ breakPoint = remaining.lastIndexOf(' ', maxLength);
486
+ }
487
+ if (breakPoint < maxLength * 0.5) {
488
+ breakPoint = maxLength;
489
+ }
490
+ chunks.push(remaining.slice(0, breakPoint));
491
+ remaining = remaining.slice(breakPoint).trimStart();
492
+ }
493
+ return chunks;
494
+ }
495
+ /**
496
+ * Mark a session as awaiting user input.
497
+ * Called when a prompt notification is sent.
498
+ */
499
+ setAwaitingInput(sessionId) {
500
+ this.awaitingSession = sessionId;
501
+ log(`[TELEGRAM] Session ${sessionId} awaiting input`);
502
+ }
503
+ /**
504
+ * Clear the awaiting input state.
505
+ * Called when response is received or session ends.
506
+ */
507
+ clearAwaitingInput() {
508
+ if (this.awaitingSession) {
509
+ log(`[TELEGRAM] Cleared awaiting state for ${this.awaitingSession}`);
510
+ }
511
+ this.awaitingSession = null;
512
+ }
513
+ }
514
+ //# sourceMappingURL=TelegramBot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TelegramBot.js","sourceRoot":"","sources":["../../src/telegram/TelegramBot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Telegram module exports.
3
+ */
4
+ export type { TelegramConfig, NotificationPayload } from './types.js';
5
+ export { TelegramBot } from './TelegramBot.js';
6
+ export type { TelegramBotOptions } from './TelegramBot.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/telegram/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGtE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Telegram module exports.
3
+ */
4
+ // Classes
5
+ export { TelegramBot } from './TelegramBot.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/telegram/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,UAAU;AACV,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Telegram bot configuration and payload types.
3
+ */
4
+ import type { PromptOption } from '../parser/types.js';
5
+ /**
6
+ * Configuration for TelegramBot initialization.
7
+ */
8
+ export interface TelegramConfig {
9
+ /** Telegram Bot API token from BotFather */
10
+ token: string;
11
+ /** Telegram user ID for whitelist authentication (AUTH-01) */
12
+ allowedUserId: number;
13
+ }
14
+ /**
15
+ * Payload for sending notification messages to Telegram.
16
+ * Represents a blocking prompt from Claude that needs user input.
17
+ */
18
+ export interface NotificationPayload {
19
+ /** Session ID for routing the response back */
20
+ sessionId: string;
21
+ /** The question or prompt text */
22
+ question: string;
23
+ /** Available options for the user to select */
24
+ options: PromptOption[];
25
+ /** Optional raw context for debugging */
26
+ rawContext?: string;
27
+ /** Whether multiple options can be selected (enables toggle buttons) */
28
+ multiSelect?: boolean;
29
+ }
30
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/telegram/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Telegram bot configuration and payload types.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/telegram/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}