shadok-ai 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 (66) hide show
  1. package/README.md +196 -0
  2. package/dist/args.d.ts +8 -0
  3. package/dist/args.js +17 -0
  4. package/dist/args.js.map +1 -0
  5. package/dist/channels.d.ts +61 -0
  6. package/dist/channels.js +169 -0
  7. package/dist/channels.js.map +1 -0
  8. package/dist/cli.d.ts +2 -0
  9. package/dist/cli.js +100 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/config.d.ts +31 -0
  12. package/dist/config.js +59 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/detect.d.ts +17 -0
  15. package/dist/detect.js +41 -0
  16. package/dist/detect.js.map +1 -0
  17. package/dist/extract.d.ts +55 -0
  18. package/dist/extract.js +269 -0
  19. package/dist/extract.js.map +1 -0
  20. package/dist/main.d.ts +2 -0
  21. package/dist/main.js +90 -0
  22. package/dist/main.js.map +1 -0
  23. package/dist/pace.d.ts +33 -0
  24. package/dist/pace.js +53 -0
  25. package/dist/pace.js.map +1 -0
  26. package/dist/retry.d.ts +15 -0
  27. package/dist/retry.js +40 -0
  28. package/dist/retry.js.map +1 -0
  29. package/dist/secrets.d.ts +21 -0
  30. package/dist/secrets.js +71 -0
  31. package/dist/secrets.js.map +1 -0
  32. package/dist/server.d.ts +1 -0
  33. package/dist/server.js +854 -0
  34. package/dist/server.js.map +1 -0
  35. package/dist/session.d.ts +74 -0
  36. package/dist/session.js +244 -0
  37. package/dist/session.js.map +1 -0
  38. package/dist/setup-prompt.d.ts +6 -0
  39. package/dist/setup-prompt.js +25 -0
  40. package/dist/setup-prompt.js.map +1 -0
  41. package/dist/supervisor.d.ts +55 -0
  42. package/dist/supervisor.js +61 -0
  43. package/dist/supervisor.js.map +1 -0
  44. package/dist/tail.d.ts +66 -0
  45. package/dist/tail.js +244 -0
  46. package/dist/tail.js.map +1 -0
  47. package/dist/telegram.d.ts +48 -0
  48. package/dist/telegram.js +565 -0
  49. package/dist/telegram.js.map +1 -0
  50. package/dist/tmux.d.ts +69 -0
  51. package/dist/tmux.js +267 -0
  52. package/dist/tmux.js.map +1 -0
  53. package/dist/update-flag.d.ts +13 -0
  54. package/dist/update-flag.js +36 -0
  55. package/dist/update-flag.js.map +1 -0
  56. package/dist/updater.d.ts +18 -0
  57. package/dist/updater.js +45 -0
  58. package/dist/updater.js.map +1 -0
  59. package/dist/usage.d.ts +23 -0
  60. package/dist/usage.js +125 -0
  61. package/dist/usage.js.map +1 -0
  62. package/dist/worktree.d.ts +63 -0
  63. package/dist/worktree.js +153 -0
  64. package/dist/worktree.js.map +1 -0
  65. package/package.json +44 -0
  66. package/public/index.html +2583 -0
@@ -0,0 +1,565 @@
1
+ import WebSocket from "ws";
2
+ import { loadChannels, upsertChannel, removeChannel, channelForTelegram, loadTgGroup, saveTgGroup, } from "./channels.js";
3
+ import { resolveRepo, secretKeys, setSecret, deleteSecret } from "./secrets.js";
4
+ import { readAndClearUpdateResult } from "./update-flag.js";
5
+ import { UPDATE_EXIT_CODE } from "./supervisor.js";
6
+ /**
7
+ * Telegram control bridge. Runs inside the server process (only when
8
+ * TELEGRAM_BOT_TOKEN is set) and connects to the server's own /ws as a plain
9
+ * client — so a Telegram-driven session is the same Live session the web UI
10
+ * sees. See docs/superpowers/specs/2026-07-23-telegram-design.md.
11
+ *
12
+ * Increment 1: DMs (1 chat = 1 session), text prompt → streamed reply,
13
+ * /new /end /list, binding persistence. Topics + dialogs come next.
14
+ */
15
+ const MSG_LIMIT = 4000; // Telegram hard limit is 4096; leave headroom.
16
+ // ── Pure helpers (unit-tested) ───────────────────────────────────────────
17
+ /** The binding key for a chat + optional forum topic thread. */
18
+ export function bindKey(chat, threadId) {
19
+ if (chat.type === "private")
20
+ return `private:${chat.id}`;
21
+ return threadId ? `topic:${chat.id}:${threadId}` : `group:${chat.id}`;
22
+ }
23
+ /** Split text into Telegram-sized chunks, preferring line boundaries. */
24
+ export function chunk(text, max = MSG_LIMIT) {
25
+ const out = [];
26
+ let rest = text;
27
+ while (rest.length > max) {
28
+ let cut = rest.lastIndexOf("\n", max);
29
+ if (cut < max * 0.5)
30
+ cut = max; // no nearby newline: hard cut
31
+ out.push(rest.slice(0, cut));
32
+ rest = rest.slice(cut).replace(/^\n/, "");
33
+ }
34
+ if (rest)
35
+ out.push(rest);
36
+ return out;
37
+ }
38
+ /** Parse a leading bot command: "/spawn foo" → {cmd:"spawn", arg:"foo"}. */
39
+ export function parseCommand(text) {
40
+ const m = text.match(/^\/([a-z]+)(?:@\w+)?\s*(.*)$/is);
41
+ return m ? { cmd: m[1].toLowerCase(), arg: m[2].trim() } : null;
42
+ }
43
+ /** Telegram's "typing…" indicator lives ~5 s per sendChatAction and dies on
44
+ * every sendMessage — a single beat can't cover a turn that runs for minutes.
45
+ * This keeps it alive: an immediate beat, then one every `intervalMs` until
46
+ * stop(). start() while beating is a no-op; stop() is idempotent. */
47
+ export function makeTyping(beat, intervalMs = 4000) {
48
+ let timer = null;
49
+ return {
50
+ start() {
51
+ if (timer)
52
+ return;
53
+ beat();
54
+ timer = setInterval(beat, intervalMs);
55
+ timer.unref?.(); // never keep the process alive for an indicator
56
+ },
57
+ stop() {
58
+ if (timer)
59
+ clearInterval(timer);
60
+ timer = null;
61
+ },
62
+ };
63
+ }
64
+ /** Inline keyboard for a TUI dialog. Single-select → one button per option
65
+ * (choose); multi-select → toggle buttons (with ☑/☐) + a Submit row. */
66
+ export function dialogKeyboard(d) {
67
+ const rows = d.options.map((o) => [
68
+ {
69
+ text: (d.multi ? (o.checked ? "☑ " : "☐ ") : "") + `${o.n}. ${o.label}`.slice(0, 60),
70
+ callback_data: (d.multi ? "t:" : "d:") + o.n,
71
+ },
72
+ ]);
73
+ if (d.multi)
74
+ rows.push([{ text: "✅ Submit", callback_data: "s" }]);
75
+ return { inline_keyboard: rows };
76
+ }
77
+ /** Parse a dialog callback_data → an action for the WS. */
78
+ export function parseCallback(data) {
79
+ if (data === "s")
80
+ return { kind: "confirm" };
81
+ const m = data.match(/^([dt]):(\d+)$/);
82
+ if (!m)
83
+ return null;
84
+ return { kind: m[1] === "d" ? "choose" : "toggle", n: Number(m[2]) };
85
+ }
86
+ /**
87
+ * Rename a Telegram forum topic to match a channel renamed elsewhere (the web
88
+ * UI). Wired up by startTelegram; a no-op when Telegram is off. Lets the server
89
+ * push a web-side rename to Telegram without importing its token/closure.
90
+ */
91
+ let renameTopicImpl = null;
92
+ export function renameTelegramTopic(chatId, threadId, name) {
93
+ renameTopicImpl?.(chatId, threadId, name);
94
+ }
95
+ /** Close (archive) a Telegram forum topic when its session ends elsewhere. */
96
+ let closeTopicImpl = null;
97
+ export function closeTelegramTopic(chatId, threadId) {
98
+ closeTopicImpl?.(chatId, threadId);
99
+ }
100
+ export function startTelegram(port) {
101
+ const token = process.env.TELEGRAM_BOT_TOKEN;
102
+ if (!token)
103
+ return;
104
+ const api = `https://api.telegram.org/bot${token}`;
105
+ const allowed = (process.env.TELEGRAM_ALLOWED_CHATS ?? "")
106
+ .split(",")
107
+ .map((s) => s.trim())
108
+ .filter(Boolean);
109
+ const bridges = new Map();
110
+ // Names of topics we've seen created/renamed (chatId:threadId → name), so a
111
+ // manually-created topic keeps its name instead of the GUI defaulting it.
112
+ const topicNames = new Map();
113
+ const tg = async (method, params) => {
114
+ try {
115
+ const r = await fetch(`${api}/${method}`, {
116
+ method: "POST",
117
+ headers: { "content-type": "application/json" },
118
+ body: JSON.stringify(params),
119
+ });
120
+ return await r.json();
121
+ }
122
+ catch {
123
+ return null;
124
+ }
125
+ };
126
+ // Web-side rename → rename the matching Telegram topic (best effort).
127
+ renameTopicImpl = (chatId, threadId, name) => {
128
+ tg("editForumTopic", { chat_id: chatId, message_thread_id: threadId, name: name.slice(0, 128) });
129
+ };
130
+ // Session ended elsewhere → delete its topic so it disappears from the group
131
+ // (the bot created it, so it can). Irreversible; ignore errors.
132
+ closeTopicImpl = (chatId, threadId) => {
133
+ tg("deleteForumTopic", { chat_id: chatId, message_thread_id: threadId });
134
+ };
135
+ const send = async (b, text) => {
136
+ for (const part of chunk(text)) {
137
+ await tg("sendMessage", {
138
+ chat_id: b.chatId,
139
+ ...(b.threadId ? { message_thread_id: b.threadId } : {}),
140
+ text: part,
141
+ disable_web_page_preview: true,
142
+ });
143
+ }
144
+ };
145
+ // Fold each bridge into the ONE registry: its session becomes a channel
146
+ // carrying the Telegram binding, so it shows up (and is pilotable) in the web
147
+ // UI too. The server fills cwd/branch on ready; here we own the binding.
148
+ const persist = () => {
149
+ for (const b of bridges.values()) {
150
+ if (!b.sessionId)
151
+ continue;
152
+ const existing = channelForTelegram(b.chatId, b.threadId);
153
+ upsertChannel({
154
+ sessionId: b.sessionId,
155
+ // Seed the name from the topic once; never override a later rename.
156
+ ...(b.name && !existing?.name ? { name: b.name } : {}),
157
+ telegram: { chatId: b.chatId, ...(b.threadId ? { threadId: b.threadId } : {}) },
158
+ });
159
+ }
160
+ };
161
+ /** Open (or resume) a session for a chat/topic and wire its events to Telegram. */
162
+ const openBridge = (key, chatId, threadId, opts = {}) => {
163
+ const ws = new WebSocket(`ws://127.0.0.1:${port}/ws`);
164
+ const b = {
165
+ key,
166
+ chatId,
167
+ threadId,
168
+ ws,
169
+ sessionId: opts.resumeId ?? null,
170
+ ready: false,
171
+ pending: [],
172
+ pendingActions: [],
173
+ worktree: opts.worktree,
174
+ name: opts.name,
175
+ typing: makeTyping(() => tg("sendChatAction", {
176
+ chat_id: chatId,
177
+ ...(threadId ? { message_thread_id: threadId } : {}),
178
+ action: "typing",
179
+ })),
180
+ };
181
+ bridges.set(key, b);
182
+ ws.on("open", () => {
183
+ ws.send(JSON.stringify(opts.resumeId
184
+ ? { type: "start", resume: opts.resumeId, cwd: process.cwd() }
185
+ : { type: "start", cwd: process.cwd(), worktree: !!opts.worktree }));
186
+ });
187
+ ws.on("message", (raw) => {
188
+ let m;
189
+ try {
190
+ m = JSON.parse(String(raw));
191
+ }
192
+ catch {
193
+ return;
194
+ }
195
+ switch (m.type) {
196
+ case "ready":
197
+ b.sessionId = m.sessionId;
198
+ b.ready = true;
199
+ persist();
200
+ for (const p of b.pending.splice(0))
201
+ ws.send(JSON.stringify({ type: "prompt", text: p }));
202
+ for (const a of b.pendingActions.splice(0))
203
+ ws.send(JSON.stringify(a));
204
+ break;
205
+ case "working":
206
+ // Heartbeat, not a one-shot: Telegram's indicator dies after ~5 s
207
+ // (and on every message we send) while a turn runs for minutes.
208
+ b.typing.start();
209
+ break;
210
+ case "stream-text":
211
+ if (m.text?.trim())
212
+ send(b, m.text);
213
+ break;
214
+ case "stream-tool":
215
+ send(b, "→ " + m.name + (m.summary ? " " + m.summary : ""));
216
+ break;
217
+ case "dialog":
218
+ // The turn is suspended on a question — Claude isn't "typing",
219
+ // it's waiting for the user. Stop the heartbeat.
220
+ b.typing.stop();
221
+ // A TUI question → inline keyboard. On multi-select toggles the
222
+ // server re-sends the dialog; edit the existing keyboard in place.
223
+ if (b.dialogMsgId) {
224
+ tg("editMessageReplyMarkup", {
225
+ chat_id: b.chatId,
226
+ message_id: b.dialogMsgId,
227
+ reply_markup: dialogKeyboard(m),
228
+ });
229
+ }
230
+ else {
231
+ tg("sendMessage", {
232
+ chat_id: b.chatId,
233
+ ...(b.threadId ? { message_thread_id: b.threadId } : {}),
234
+ text: m.question || "Choisis :",
235
+ reply_markup: dialogKeyboard(m),
236
+ }).then((r) => {
237
+ if (r?.ok)
238
+ b.dialogMsgId = r.result.message_id;
239
+ });
240
+ }
241
+ break;
242
+ case "turn-done":
243
+ b.typing.stop();
244
+ b.dialogMsgId = undefined; // any dialog is resolved once the turn ends
245
+ break;
246
+ case "pace-blocked":
247
+ // The prompt was refused by the pace guard (there is no "force"
248
+ // button here) — say so instead of staying silent, and drop the
249
+ // optimistic typing started at message receipt.
250
+ b.typing.stop();
251
+ send(b, "⏸️ pace guard: " + (m.reason ?? "over the ideal pace") + "\nYour message was not sent — retry later.");
252
+ break;
253
+ case "error":
254
+ // No typing.stop() here: fail() errors ("a response is already in
255
+ // progress") don't end the running turn — turn-done/exited will.
256
+ send(b, "⚠️ " + m.message);
257
+ break;
258
+ case "exited":
259
+ b.typing.stop();
260
+ send(b, "— session ended —");
261
+ break;
262
+ }
263
+ });
264
+ ws.on("close", () => {
265
+ b.typing.stop();
266
+ if (bridges.get(key) === b)
267
+ bridges.delete(key);
268
+ });
269
+ ws.on("error", () => { });
270
+ return b;
271
+ };
272
+ const bridgeFor = (key, chatId, threadId, name) => {
273
+ const existing = bridges.get(key);
274
+ if (existing && existing.ws.readyState <= WebSocket.OPEN)
275
+ return existing;
276
+ const saved = channelForTelegram(chatId, threadId);
277
+ return openBridge(key, chatId, threadId, { resumeId: saved?.sessionId, name });
278
+ };
279
+ const promptTo = (b, text) => {
280
+ if (b.ready && b.ws.readyState === WebSocket.OPEN)
281
+ b.ws.send(JSON.stringify({ type: "prompt", text }));
282
+ else
283
+ b.pending.push(text);
284
+ };
285
+ const reply = (chatId, threadId, text, extra = {}) => tg("sendMessage", {
286
+ chat_id: chatId,
287
+ ...(threadId ? { message_thread_id: threadId } : {}),
288
+ text,
289
+ disable_web_page_preview: true,
290
+ ...extra,
291
+ });
292
+ const endBinding = (key, chatId, threadId) => {
293
+ const b = bridges.get(key);
294
+ if (b) {
295
+ b.ws.send(JSON.stringify({ type: "stop" }));
296
+ b.ws.close();
297
+ bridges.delete(key);
298
+ }
299
+ // The session is stopped → drop it from the one registry (removes it from
300
+ // the web UI too).
301
+ const ch = channelForTelegram(chatId, threadId);
302
+ if (ch)
303
+ removeChannel(ch.sessionId);
304
+ };
305
+ const handleMessage = async (msg) => {
306
+ if (typeof msg.text !== "string")
307
+ return;
308
+ const chat = msg.chat;
309
+ if (allowed.length && !allowed.includes(String(chat.id))) {
310
+ await reply(chat.id, msg.message_thread_id, "⛔ this bot is restricted.");
311
+ return;
312
+ }
313
+ const threadId = msg.message_thread_id;
314
+ const isGroup = chat.type === "group" || chat.type === "supergroup";
315
+ const cmd = parseCommand(msg.text);
316
+ // One board per instance: a group must be the bound group.
317
+ if (isGroup) {
318
+ const bound = loadTgGroup();
319
+ if (bound === null) {
320
+ if (cmd?.cmd === "setup") {
321
+ saveTgGroup(chat.id);
322
+ await reply(chat.id, threadId, "✅ This group is now shadok-ai's board. Use /spawn <name> to create an agent (a forum topic). Enable Topics + make me admin if /spawn fails.");
323
+ }
324
+ else {
325
+ await reply(chat.id, threadId, "Run /setup here to bind this group as shadok-ai's board (one group per instance).");
326
+ }
327
+ return;
328
+ }
329
+ if (bound !== chat.id) {
330
+ await reply(chat.id, threadId, "⛔ This shadok-ai instance is bound to another group.");
331
+ return;
332
+ }
333
+ }
334
+ const key = bindKey(chat, threadId);
335
+ if (cmd) {
336
+ switch (cmd.cmd) {
337
+ case "start":
338
+ case "help":
339
+ await reply(chat.id, threadId, "shadok-ai — talk to your agent by sending a message.\n/spawn <name> — new agent in a topic (groups)\n/new — reset · /end — stop · /list — bindings\n/secrets — list · /secret KEY value — set · /unsecret KEY");
340
+ return;
341
+ case "setup":
342
+ if (isGroup)
343
+ await reply(chat.id, threadId, "✅ already this instance's board.");
344
+ return;
345
+ case "spawn": {
346
+ if (!isGroup) {
347
+ await reply(chat.id, threadId, "/spawn works in the board group. In a DM just send a message.");
348
+ return;
349
+ }
350
+ const name = cmd.arg || "agent";
351
+ const t = await tg("createForumTopic", { chat_id: chat.id, name: name.slice(0, 128) });
352
+ if (!t?.ok) {
353
+ const why = t?.description ? ` (Telegram: ${t.description})` : "";
354
+ console.log(`telegram: createForumTopic failed for ${chat.id}:`, t?.description ?? t);
355
+ await reply(chat.id, threadId, `⚠️ Couldn't create a topic${why}.\nMake sure this is a supergroup with Topics enabled, and that I'm an admin with 'Manage topics'.`);
356
+ return;
357
+ }
358
+ const newThread = t.result.message_thread_id;
359
+ // A group agent is isolated in its own worktree (a board of agents).
360
+ openBridge(bindKey(chat, newThread), chat.id, newThread, { worktree: true, name });
361
+ await reply(chat.id, newThread, `🤖 Agent « ${name} » ready (isolated worktree). Send it a task.`);
362
+ return;
363
+ }
364
+ case "new":
365
+ case "end":
366
+ endBinding(key, chat.id, threadId);
367
+ await reply(chat.id, threadId, cmd.cmd === "new" ? "🔄 fresh session — send a message." : "🛑 session ended.");
368
+ return;
369
+ case "list": {
370
+ const lines = loadChannels()
371
+ .filter((c) => c.telegram)
372
+ .map((c) => {
373
+ const where = c.telegram.threadId ? `topic ${c.telegram.threadId}` : "here";
374
+ return `• ${c.name ?? c.sessionId.slice(0, 8)} (${where})`;
375
+ });
376
+ await reply(chat.id, threadId, lines.length ? lines.join("\n") : "no sessions bound yet.");
377
+ return;
378
+ }
379
+ case "update": {
380
+ // Powerful (npm install + respawn): board group only. The allowlist,
381
+ // if set, was already enforced at the top of handleMessage.
382
+ if (!isGroup) {
383
+ await reply(chat.id, threadId, "/update runs in the board group.");
384
+ return;
385
+ }
386
+ await reply(chat.id, threadId, "🔄 updating… I'll be back in a moment.");
387
+ // Ask the supervisor to fetch @latest and respawn us.
388
+ process.exit(UPDATE_EXIT_CODE);
389
+ }
390
+ case "secrets": {
391
+ const repo = resolveRepo(channelForTelegram(chat.id, threadId)?.cwd || process.cwd());
392
+ const keys = secretKeys(repo);
393
+ await reply(chat.id, threadId, `🔐 secrets for ${repo}:\n${keys.length ? keys.map((k) => "• " + k).join("\n") : "(none)"}\n\nSet: /secret KEY value · remove: /unsecret KEY`);
394
+ return;
395
+ }
396
+ case "secret": {
397
+ // /secret KEY value — store then DELETE the message so the value
398
+ // doesn't linger in the chat history.
399
+ const sp = cmd.arg.indexOf(" ");
400
+ const skey = sp === -1 ? cmd.arg : cmd.arg.slice(0, sp);
401
+ const sval = sp === -1 ? "" : cmd.arg.slice(sp + 1);
402
+ if (!skey || !sval) {
403
+ await reply(chat.id, threadId, "Usage: /secret KEY value");
404
+ return;
405
+ }
406
+ const repo = resolveRepo(channelForTelegram(chat.id, threadId)?.cwd || process.cwd());
407
+ setSecret(repo, skey.trim(), sval);
408
+ const del = await tg("deleteMessage", { chat_id: chat.id, message_id: msg.message_id });
409
+ await reply(chat.id, threadId, `🔐 ${skey.trim()} saved for ${repo}.${del?.ok ? " (your message was deleted)" : "\n⚠️ I couldn't delete your message — remove it manually; the value is exposed in history."} Applies to newly spawned/restarted agents.`);
410
+ return;
411
+ }
412
+ case "unsecret": {
413
+ const skey = cmd.arg.trim();
414
+ if (!skey) {
415
+ await reply(chat.id, threadId, "Usage: /unsecret KEY");
416
+ return;
417
+ }
418
+ const repo = resolveRepo(channelForTelegram(chat.id, threadId)?.cwd || process.cwd());
419
+ deleteSecret(repo, skey);
420
+ await reply(chat.id, threadId, `🔐 ${skey} removed for ${repo}.`);
421
+ return;
422
+ }
423
+ case "restart": {
424
+ // Re-spawn this topic's agent so it picks up freshly-added secrets.
425
+ const rb = bridgeFor(key, chat.id, threadId);
426
+ const rmsg = { type: "restart" };
427
+ if (rb.ready && rb.ws.readyState === WebSocket.OPEN)
428
+ rb.ws.send(JSON.stringify(rmsg));
429
+ else
430
+ rb.pendingActions.push(rmsg);
431
+ await reply(chat.id, threadId, "♻️ restarting the agent to apply secrets…");
432
+ return;
433
+ }
434
+ }
435
+ }
436
+ // A manually-created topic keeps its own name: take it from the cache
437
+ // (forum_topic_created) or the topic's root message, so the channel isn't
438
+ // named after the cwd. Only used to seed a nameless channel (see persist).
439
+ const topicName = threadId != null
440
+ ? topicNames.get(key) ?? msg.reply_to_message?.forum_topic_created?.name
441
+ : undefined;
442
+ // Optimistic typing: start the heartbeat now, before the server confirms
443
+ // anything — spawning/resuming a session can take tens of seconds and the
444
+ // first "working" only arrives after it. Every terminal outcome stops it
445
+ // (turn-done, dialog, pace-blocked, exited, ws close).
446
+ const b = bridgeFor(key, chat.id, threadId, topicName);
447
+ b.typing.start();
448
+ promptTo(b, msg.text);
449
+ };
450
+ const handleCallback = async (cq) => {
451
+ const action = parseCallback(cq.data ?? "");
452
+ const msg = cq.message;
453
+ if (!action || !msg)
454
+ return;
455
+ await tg("answerCallbackQuery", { callback_query_id: cq.id }); // stop the client spinner
456
+ const wsMsg = action.kind === "confirm" ? { type: "confirm" } : { type: action.kind, n: action.n };
457
+ // Resume the bridge if the server was restarted since the dialog was shown
458
+ // (otherwise a click on an orphaned keyboard would silently do nothing).
459
+ const b = bridgeFor(bindKey(msg.chat, msg.message_thread_id), msg.chat.id, msg.message_thread_id);
460
+ if (b.ready && b.ws.readyState === WebSocket.OPEN)
461
+ b.ws.send(JSON.stringify(wsMsg));
462
+ else
463
+ b.pendingActions.push(wsMsg);
464
+ };
465
+ // A topic created in Telegram → spawn its agent right away, so the channel
466
+ // shows up in the GUI before anyone writes. Creating a topic = creating an
467
+ // agent (the board model). Skips topics already bound (e.g. the bot's own
468
+ // /spawn, which opened the bridge before this event arrived).
469
+ const handleTopicCreated = (msg) => {
470
+ const name = msg.forum_topic_created?.name;
471
+ const threadId = msg.message_thread_id;
472
+ const key = bindKey(msg.chat, threadId);
473
+ if (typeof name === "string" && name)
474
+ topicNames.set(key, name);
475
+ if (msg.chat.id !== loadTgGroup())
476
+ return; // only the bound board group
477
+ const ch = channelForTelegram(msg.chat.id, threadId);
478
+ if (bridges.has(key) || ch) {
479
+ if (ch && !ch.name && name)
480
+ upsertChannel({ sessionId: ch.sessionId, name });
481
+ return;
482
+ }
483
+ openBridge(key, msg.chat.id, threadId, { worktree: true, name });
484
+ reply(msg.chat.id, threadId, `🤖 Agent « ${name ?? "agent"} » ready (isolated worktree). Send it a task.`);
485
+ };
486
+ // A topic renamed in Telegram → update the one registry so the web tab follows.
487
+ const handleTopicEdited = (msg) => {
488
+ const name = msg.forum_topic_edited?.name;
489
+ if (typeof name !== "string" || !name)
490
+ return;
491
+ topicNames.set(bindKey(msg.chat, msg.message_thread_id), name);
492
+ const ch = channelForTelegram(msg.chat.id, msg.message_thread_id);
493
+ if (ch)
494
+ upsertChannel({ sessionId: ch.sessionId, name });
495
+ };
496
+ // A topic closed/deleted in Telegram → end its session everywhere. Sending
497
+ // `stop` lets the server tear down + drop it from the registry (which removes
498
+ // the web tab via the sync poll). No bridge → just unbind.
499
+ const handleTopicClosed = (msg) => {
500
+ const ch = channelForTelegram(msg.chat.id, msg.message_thread_id);
501
+ if (!ch)
502
+ return;
503
+ const key = bindKey(msg.chat, msg.message_thread_id);
504
+ const b = bridges.get(key);
505
+ if (b?.ws.readyState === WebSocket.OPEN)
506
+ b.ws.send(JSON.stringify({ type: "stop" }));
507
+ else
508
+ removeChannel(ch.sessionId);
509
+ bridges.delete(key);
510
+ };
511
+ const handleUpdate = async (u) => {
512
+ if (u.callback_query)
513
+ return handleCallback(u.callback_query);
514
+ if (u.message?.forum_topic_created)
515
+ return handleTopicCreated(u.message);
516
+ if (u.message?.forum_topic_edited)
517
+ return handleTopicEdited(u.message);
518
+ if (u.message?.forum_topic_closed || u.message?.forum_topic_deleted)
519
+ return handleTopicClosed(u.message);
520
+ if (u.message)
521
+ return handleMessage(u.message);
522
+ };
523
+ // Long-poll loop — no webhook / public URL needed.
524
+ let offset = 0;
525
+ const poll = async () => {
526
+ const res = await tg("getUpdates", { offset, timeout: 30, allowed_updates: ["message", "callback_query"] });
527
+ if (res?.ok && Array.isArray(res.result)) {
528
+ for (const u of res.result) {
529
+ offset = u.update_id + 1;
530
+ handleUpdate(u).catch(() => { });
531
+ }
532
+ }
533
+ setTimeout(poll, res ? 0 : 3000); // back off on network error
534
+ };
535
+ // Connect, retrying transient failures with backoff. A single network hiccup
536
+ // on getMe used to leave Telegram dead for the whole run; only a real 401
537
+ // (bad token) stops us now.
538
+ const connect = async (attempt = 0) => {
539
+ const me = await tg("getMe", {});
540
+ if (me?.ok) {
541
+ console.log(`telegram: bot @${me.result.username} connected (long-polling)`);
542
+ poll();
543
+ announceUpdateResult();
544
+ return;
545
+ }
546
+ if (me && me.error_code === 401) {
547
+ console.log("telegram: unauthorized — check TELEGRAM_BOT_TOKEN");
548
+ return;
549
+ }
550
+ const delay = Math.min(30_000, 2_000 * 2 ** attempt);
551
+ console.log(`telegram: getMe failed (transient), retrying in ${delay / 1000}s`);
552
+ setTimeout(() => connect(attempt + 1), delay);
553
+ };
554
+ connect();
555
+ /** After a supervisor-driven /update, tell the board group how it went. */
556
+ function announceUpdateResult() {
557
+ const r = readAndClearUpdateResult();
558
+ const group = loadTgGroup();
559
+ if (!r || group === null)
560
+ return;
561
+ const text = r.ok ? `✅ updated to v${r.version}` : `⚠️ update failed: ${r.error}`;
562
+ tg("sendMessage", { chat_id: group, text });
563
+ }
564
+ }
565
+ //# sourceMappingURL=telegram.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram.js","sourceRoot":"","sources":["../src/telegram.ts"],"names":[],"mappings":"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"}