From e1ecfb9c4866c301eb2f8d601ecb3465e3928d6c Mon Sep 17 00:00:00 2001 From: "exe.dev user" Date: Tue, 5 May 2026 09:29:23 +0000 Subject: [PATCH] =?UTF-8?q?setup:=20add=20=E2=86=90=20Back=20option=20to?= =?UTF-8?q?=20Telegram=20channel=20flow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stacked on the back-nav scaffolding from the Discord/WhatsApp/iMessage PR — depends on setup/lib/back-nav.ts and the auto.ts loop. Telegram's "no existing token" path adds one extra prompt — a brightSelect "Ready to paste your bot token?" between the BotFather instructions and the token paste. Clack's p.password prompt doesn't support menu options so we can't fold Back into the paste itself; the cleanest fix is a separate gate immediately before. The "existing token" path doesn't add noise — the Yes/No confirm becomes Yes/No/Back. Co-Authored-By: Claude Opus 4.7 (1M context) --- setup/auto.ts | 2 +- setup/channels/telegram.ts | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/setup/auto.ts b/setup/auto.ts index 4b7ca46..bf3ce92 100644 --- a/setup/auto.ts +++ b/setup/auto.ts @@ -454,7 +454,7 @@ async function main(): Promise { } let result: void | typeof BACK_TO_CHANNEL_SELECTION; if (channelChoice === 'telegram') { - await runTelegramChannel(displayName!); + result = await runTelegramChannel(displayName!); } else if (channelChoice === 'discord') { result = await runDiscordChannel(displayName!); } else if (channelChoice === 'whatsapp') { diff --git a/setup/channels/telegram.ts b/setup/channels/telegram.ts index bf474f2..01a6675 100644 --- a/setup/channels/telegram.ts +++ b/setup/channels/telegram.ts @@ -21,7 +21,9 @@ import * as p from '@clack/prompts'; import k from 'kleur'; import * as setupLog from '../logs.js'; +import { BACK_TO_CHANNEL_SELECTION, type ChannelFlowResult } from '../lib/back-nav.js'; import { confirmThenOpen, formatNoteLink } from '../lib/browser.js'; +import { brightSelect } from '../lib/bright-select.js'; import { askOperatorRole } from '../lib/role-prompt.js'; import { type Block, @@ -38,8 +40,10 @@ import { accentGreen, brandBold, fitToWidth, fmtDuration, note } from '../lib/th const DEFAULT_AGENT_NAME = 'Nano'; -export async function runTelegramChannel(displayName: string): Promise { - const token = await collectTelegramToken(); +export async function runTelegramChannel(displayName: string): Promise { + const tokenOrBack = await collectTelegramToken(); + if (tokenOrBack === 'back') return BACK_TO_CHANNEL_SELECTION; + const token = tokenOrBack; const botUsername = await validateTelegramToken(token); // Deep-link the user into the bot's chat so they're on the right screen @@ -131,17 +135,24 @@ export async function runTelegramChannel(displayName: string): Promise { } } -async function collectTelegramToken(): Promise { +async function collectTelegramToken(): Promise { const existing = readEnvKey('TELEGRAM_BOT_TOKEN'); if (existing && /^[0-9]+:[A-Za-z0-9_-]{35,}$/.test(existing)) { - const reuse = ensureAnswer(await p.confirm({ + const choice = ensureAnswer(await brightSelect<'yes' | 'no' | 'back'>({ message: `Found an existing Telegram bot token (${existing.slice(0, 8)}…). Use it?`, - initialValue: true, + options: [ + { value: 'yes', label: 'Yes, use the existing token' }, + { value: 'no', label: 'No, paste a new one' }, + { value: 'back', label: '← Back to channel selection' }, + ], + initialValue: 'yes', })); - if (reuse) { + if (choice === 'back') return 'back'; + if (choice === 'yes') { setupLog.userInput('telegram_token', 'reused-existing'); return existing; } + // 'no' falls through to the paste flow below } note( @@ -159,6 +170,19 @@ async function collectTelegramToken(): Promise { 'Set up your Telegram bot', ); + // Back-aware gate before the password prompt — `p.password` doesn't + // accept extra options, so we offer Back as a separate brightSelect + // immediately after the BotFather instructions and before the paste. + const proceed = ensureAnswer(await brightSelect<'continue' | 'back'>({ + message: 'Ready to paste your bot token?', + options: [ + { value: 'continue', label: 'Yes, paste it on the next prompt' }, + { value: 'back', label: '← Back to channel selection' }, + ], + initialValue: 'continue', + })); + if (proceed === 'back') return 'back'; + const answer = ensureAnswer( await p.password({ message: 'Paste your bot token',