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.
- package/README.md +175 -0
- package/bin/cli.js +2 -0
- package/dist/claude/ClaudeProcess.d.ts +77 -0
- package/dist/claude/ClaudeProcess.d.ts.map +1 -0
- package/dist/claude/ClaudeProcess.js +270 -0
- package/dist/claude/ClaudeProcess.js.map +1 -0
- package/dist/claude/EventAdapter.d.ts +44 -0
- package/dist/claude/EventAdapter.d.ts.map +1 -0
- package/dist/claude/EventAdapter.js +129 -0
- package/dist/claude/EventAdapter.js.map +1 -0
- package/dist/claude/index.d.ts +10 -0
- package/dist/claude/index.d.ts.map +1 -0
- package/dist/claude/index.js +9 -0
- package/dist/claude/index.js.map +1 -0
- package/dist/claude/types.d.ts +244 -0
- package/dist/claude/types.d.ts.map +1 -0
- package/dist/claude/types.js +8 -0
- package/dist/claude/types.js.map +1 -0
- package/dist/env.d.ts +21 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +49 -0
- package/dist/env.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +360 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/AnsiStripper.d.ts +54 -0
- package/dist/parser/AnsiStripper.d.ts.map +1 -0
- package/dist/parser/AnsiStripper.js +115 -0
- package/dist/parser/AnsiStripper.js.map +1 -0
- package/dist/parser/OptionExtractor.d.ts +31 -0
- package/dist/parser/OptionExtractor.d.ts.map +1 -0
- package/dist/parser/OptionExtractor.js +91 -0
- package/dist/parser/OptionExtractor.js.map +1 -0
- package/dist/parser/OutputParser.d.ts +121 -0
- package/dist/parser/OutputParser.d.ts.map +1 -0
- package/dist/parser/OutputParser.js +306 -0
- package/dist/parser/OutputParser.js.map +1 -0
- package/dist/parser/PromptDetector.d.ts +20 -0
- package/dist/parser/PromptDetector.d.ts.map +1 -0
- package/dist/parser/PromptDetector.js +68 -0
- package/dist/parser/PromptDetector.js.map +1 -0
- package/dist/parser/index.d.ts +7 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +5 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/types.d.ts +73 -0
- package/dist/parser/types.d.ts.map +1 -0
- package/dist/parser/types.js +2 -0
- package/dist/parser/types.js.map +1 -0
- package/dist/pty/OutputBuffer.d.ts +39 -0
- package/dist/pty/OutputBuffer.d.ts.map +1 -0
- package/dist/pty/OutputBuffer.js +55 -0
- package/dist/pty/OutputBuffer.js.map +1 -0
- package/dist/pty/PtyProcess.d.ts +47 -0
- package/dist/pty/PtyProcess.d.ts.map +1 -0
- package/dist/pty/PtyProcess.js +94 -0
- package/dist/pty/PtyProcess.js.map +1 -0
- package/dist/pty/PtyService.d.ts +55 -0
- package/dist/pty/PtyService.d.ts.map +1 -0
- package/dist/pty/PtyService.js +115 -0
- package/dist/pty/PtyService.js.map +1 -0
- package/dist/pty/index.d.ts +5 -0
- package/dist/pty/index.d.ts.map +1 -0
- package/dist/pty/index.js +4 -0
- package/dist/pty/index.js.map +1 -0
- package/dist/pty/types.d.ts +36 -0
- package/dist/pty/types.d.ts.map +1 -0
- package/dist/pty/types.js +2 -0
- package/dist/pty/types.js.map +1 -0
- package/dist/router/BoundedQueue.d.ts +57 -0
- package/dist/router/BoundedQueue.d.ts.map +1 -0
- package/dist/router/BoundedQueue.js +86 -0
- package/dist/router/BoundedQueue.js.map +1 -0
- package/dist/router/EventRouter.d.ts +103 -0
- package/dist/router/EventRouter.d.ts.map +1 -0
- package/dist/router/EventRouter.js +169 -0
- package/dist/router/EventRouter.js.map +1 -0
- package/dist/router/index.d.ts +13 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/index.js +12 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router/types.d.ts +104 -0
- package/dist/router/types.d.ts.map +1 -0
- package/dist/router/types.js +6 -0
- package/dist/router/types.js.map +1 -0
- package/dist/telegram/TelegramBot.d.ts +151 -0
- package/dist/telegram/TelegramBot.d.ts.map +1 -0
- package/dist/telegram/TelegramBot.js +514 -0
- package/dist/telegram/TelegramBot.js.map +1 -0
- package/dist/telegram/index.d.ts +7 -0
- package/dist/telegram/index.d.ts.map +1 -0
- package/dist/telegram/index.js +6 -0
- package/dist/telegram/index.js.map +1 -0
- package/dist/telegram/types.d.ts +30 -0
- package/dist/telegram/types.d.ts.map +1 -0
- package/dist/telegram/types.js +5 -0
- package/dist/telegram/types.js.map +1 -0
- package/dist/terminal/TerminalInterface.d.ts +61 -0
- package/dist/terminal/TerminalInterface.d.ts.map +1 -0
- package/dist/terminal/TerminalInterface.js +218 -0
- package/dist/terminal/TerminalInterface.js.map +1 -0
- package/dist/terminal/index.d.ts +3 -0
- package/dist/terminal/index.d.ts.map +1 -0
- package/dist/terminal/index.js +2 -0
- package/dist/terminal/index.js.map +1 -0
- package/dist/terminal/types.d.ts +17 -0
- package/dist/terminal/types.d.ts.map +1 -0
- package/dist/terminal/types.js +2 -0
- package/dist/terminal/types.js.map +1 -0
- 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, '&')
|
|
407
|
+
.replace(/</g, '<')
|
|
408
|
+
.replace(/>/g, '>');
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/telegram/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|