Skip to content

fix(telegram): slash menu + repo navigator + inline approvals#189

Merged
finedesignz merged 1 commit into
mainfrom
fix/telegram-bridge-ux
May 30, 2026
Merged

fix(telegram): slash menu + repo navigator + inline approvals#189
finedesignz merged 1 commit into
mainfrom
fix/telegram-bridge-ux

Conversation

@finedesignz
Copy link
Copy Markdown
Owner

@-

Fix A — slash menu: register the bot's command list with Telegram via
setMyCommands at bridge startup so typing `/` shows the command popup.
BOT_COMMANDS in commands.ts is the single source of truth for the menu +
/help (list/session/status/doctor/help — only the real handled commands).
Idempotent, fire-and-forget, gated on botToken.

Fix B — repo navigator: the callback_query session-picker path was
structurally intact at #188 (proven by new integration tests) — its real-
world "broken" symptom was the missing slash menu (Fix A) making /list
undiscoverable. Hardened: webhook picker re-render now uses PAGE_SIZE
instead of a hardcoded 20, and set_session/paginate/unknown callbacks are
now covered by integration tests that lock the contract.

Fix C — inline approval prompts: when a Telegram-driven session hits a
tool permission prompt it no longer blocks silently. ws/agent.ts emits a
permission_request:pending event (new isolated bus, mirrors assistant-
events); the bridge surfaces it inline with Approve/Deny buttons to users
whose default session matches. Taps route through the existing callback_query
path → handlePermissionCallback forwards a permission_response frame on the
agent socket (same frame the web client sends). Pending prompts are tracked
in an in-memory registry keyed by request_id (callback_data is too small for
session+request UUIDs) which also enforces per-user authorization. No new
dispatch path — this is a control-frame reply to a runner-initiated prompt,
so the cost-cap pipeline is untouched.

Tests: telegram-approvals (registry + codec), telegram-bridge (slash menu +
permission surfacing), telegram-webhook (callback set_session/paginate +
approve/deny/stale/foreign/offline). check-baseline GREEN (947 pass, 0 fail).
docs/telegram-bridge.md updated in lockstep.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@finedesignz finedesignz merged commit 0050cf4 into main May 30, 2026
3 checks passed
finedesignz added a commit that referenced this pull request May 30, 2026
#191)

Three deliverables for the hub Telegram bridge (one cohesive feature):

1. MarkdownV2 formatting. All user-facing bridge messages now send with
   parse_mode MarkdownV2. New sendMessageMd / editMessageTextMd wrap the send
   with a 400->plain-text single retry so an unbalanced reserved char never
   silently drops a session reply. Reuses the existing escapeMarkdownV2 (full
   reserved set). Inline approve/deny prompt is MarkdownV2 with the same fallback;
   keyboard unaffected.

2. Summarized streaming. New session-activity event bus (tool_use one-liners)
   emitted from ws/agent.ts. The bridge maintains one editable "Working..."
   message per (chat, session): each tool_use appends a collapsed one-liner
   (throttled edit), a typing chat-action refreshes ~every 4s, and
   assistant_message:final edits the same message to the full answer. Gated on
   config.telegram.summarizedStreaming (TELEGRAM_SUMMARIZED_STREAMING=false
   reverts to a single final-blob send). No parallel dispatch path; cost-cap gate
   untouched.

3. MED fast-follow (#189 review). approvals.ts pending-prompt registry was keyed
   by requestId alone -> a shared default session clobbered the first binding and
   locked out a valid approver. Re-keyed by (sessionId, requestId) holding a set
   of authorized userIds; takePendingPrompt(requestId, userId) folds in the
   authorization check and resolves exactly once for whichever authorized user
   taps first.

Tests: escaper (every reserved char, existing) + 400->plaintext fallback (new
file, cache-busted import to dodge cross-file Bun mock pollution) + approval
re-keying incl. two-users-same-default-session. check-baseline GREEN
(956 pass / 0 fail). docs/telegram-bridge.md updated.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant