opencode-telegram-bot 1.1.0 → 1.1.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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/index.js +109 -18
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -280,7 +280,7 @@ You: [tap "Auth refactoring"]
280
280
  Bot: Switched to session: Auth refactoring
281
281
  ```
282
282
 
283
- The `/sessions` list only shows sessions created by the Telegram bot, not sessions from other OpenCode clients (like the TUI). You cannot delete the currently active session -- use `/new` first.
283
+ The `/sessions` list shows sessions created by the Telegram bot. At the bottom of the list, a **"Show all sessions"** button lets you discover sessions created by other OpenCode clients (like the TUI via `opencode attach`). Tapping an external session adopts it and switches to it. You cannot delete the currently active session -- use `/new` first.
284
284
 
285
285
  ## Session Persistence
286
286
 
package/dist/index.js CHANGED
@@ -20923,7 +20923,13 @@ async function startTelegram(options) {
20923
20923
  try {
20924
20924
  const sessions = await getKnownSessions();
20925
20925
  if (sessions.length === 0) {
20926
- await ctx.reply("No sessions found.");
20926
+ await ctx.reply("No sessions found.\n\nYou can discover sessions created outside this bot:", {
20927
+ reply_markup: {
20928
+ inline_keyboard: [
20929
+ [{ text: "Show all sessions", callback_data: "sessions:all" }],
20930
+ ],
20931
+ },
20932
+ });
20927
20933
  return;
20928
20934
  }
20929
20935
  const activeSession = sessions.find((session) => session.id === activeSessionId);
@@ -20932,25 +20938,33 @@ async function startTelegram(options) {
20932
20938
  msgLines.push(`Current session: ${activeSession.title}`);
20933
20939
  }
20934
20940
  const otherSessions = sessions.filter((session) => session.id !== activeSessionId);
20935
- if (otherSessions.length === 0) {
20941
+ const keyboard = [];
20942
+ if (otherSessions.length > 0) {
20943
+ msgLines.push("Tap a session to switch or delete.");
20944
+ otherSessions.forEach((session) => {
20945
+ keyboard.push([
20946
+ {
20947
+ text: session.title,
20948
+ callback_data: `switch:${session.id}`,
20949
+ },
20950
+ {
20951
+ text: "Delete",
20952
+ callback_data: `delete:${session.id}`,
20953
+ },
20954
+ ]);
20955
+ });
20956
+ }
20957
+ else {
20936
20958
  msgLines.push("This is your only session.");
20937
- await ctx.reply(msgLines.join("\n"));
20938
- return;
20939
20959
  }
20940
- msgLines.push("Tap a session to switch or delete.");
20941
- const keyboard = [];
20942
- otherSessions.forEach((session) => {
20943
- keyboard.push([
20944
- {
20945
- text: session.title,
20946
- callback_data: `switch:${session.id}`,
20947
- },
20948
- {
20949
- text: "Delete",
20950
- callback_data: `delete:${session.id}`,
20951
- },
20952
- ]);
20953
- });
20960
+ // Always show "Show all sessions" button to discover sessions
20961
+ // created outside the Telegram bot (e.g. via opencode TUI)
20962
+ keyboard.push([
20963
+ {
20964
+ text: "Show all sessions",
20965
+ callback_data: "sessions:all",
20966
+ },
20967
+ ]);
20954
20968
  await ctx.reply(msgLines.join("\n"), {
20955
20969
  reply_markup: {
20956
20970
  inline_keyboard: keyboard,
@@ -21110,6 +21124,83 @@ async function startTelegram(options) {
21110
21124
  await answerAndEdit(ctx, "Failed to delete session.");
21111
21125
  }
21112
21126
  });
21127
+ // Handle "Show all sessions" button - list sessions not tracked by the bot
21128
+ bot.action("sessions:all", async (ctx) => {
21129
+ const chatId = getChatIdFromContext(ctx);
21130
+ if (!chatId)
21131
+ return;
21132
+ try {
21133
+ // Delete the button message
21134
+ try {
21135
+ await ctx.deleteMessage();
21136
+ }
21137
+ catch {
21138
+ // Ignore if already deleted
21139
+ }
21140
+ await ctx.answerCbQuery();
21141
+ const list = await client.session.list({});
21142
+ const allSessions = (list.data || [])
21143
+ .filter((s) => !knownSessionIds.has(s.id) && !s.parentID)
21144
+ .sort((a, b) => b.time.updated - a.time.updated);
21145
+ if (allSessions.length === 0) {
21146
+ await ctx.reply("No other sessions found.");
21147
+ return;
21148
+ }
21149
+ const keyboard = [];
21150
+ allSessions.forEach((session) => {
21151
+ keyboard.push([
21152
+ {
21153
+ text: session.title,
21154
+ callback_data: `adopt:${session.id}`,
21155
+ },
21156
+ ]);
21157
+ });
21158
+ await ctx.reply("Sessions created outside this bot.\nTap to adopt and switch:", {
21159
+ reply_markup: {
21160
+ inline_keyboard: keyboard,
21161
+ },
21162
+ });
21163
+ }
21164
+ catch (err) {
21165
+ console.error("[Telegram] Error listing all sessions:", err);
21166
+ await ctx.reply("Failed to list sessions.");
21167
+ }
21168
+ });
21169
+ // Handle adopt button - adopt an external session and switch to it
21170
+ bot.action(/^adopt:(.+)$/, async (ctx) => {
21171
+ const chatId = getChatIdFromContext(ctx);
21172
+ const sessionId = ctx.match?.[1];
21173
+ if (!chatId || !sessionId)
21174
+ return;
21175
+ try {
21176
+ // Verify the session still exists on the server
21177
+ const list = await client.session.list({});
21178
+ const allSessions = (list.data || []);
21179
+ const match = allSessions.find((s) => s.id === sessionId);
21180
+ if (!match) {
21181
+ await answerAndEdit(ctx, "Session not found. It may have been deleted.");
21182
+ return;
21183
+ }
21184
+ // Delete the button message
21185
+ try {
21186
+ await ctx.deleteMessage();
21187
+ }
21188
+ catch {
21189
+ // Ignore if already deleted
21190
+ }
21191
+ await ctx.answerCbQuery();
21192
+ // Adopt: add to known sessions and switch to it
21193
+ knownSessionIds.add(match.id);
21194
+ chatSessions.set(chatId, match.id);
21195
+ saveSessions();
21196
+ console.log(`[Telegram] Adopted and switched chat ${chatId} to session ${match.id}`);
21197
+ await ctx.reply(`Adopted and switched to session: ${match.title}`);
21198
+ }
21199
+ catch (err) {
21200
+ console.error("[Telegram] Error adopting session:", err);
21201
+ await answerAndEdit(ctx, "Failed to adopt session.");
21202
+ }
21203
+ });
21113
21204
  // Handle /verbose command - toggle verbose mode for this chat
21114
21205
  // Usage: /verbose, /verbose on, /verbose off
21115
21206
  bot.command("verbose", (ctx) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-telegram-bot",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "type": "module",
5
5
  "description": "Telegram bot that forwards messages to an OpenCode agent",
6
6
  "main": "./dist/index.js",