zot/internal/tui
patriceckhart 098a79743d feat(tui): /telegram connect | disconnect | status
The Telegram bridge can now mirror into the running TUI session.
Runs inside the zot process (no daemon needed); DMs from the
paired user become prompts in the current agent, and the
assistant's final text is sent back to Telegram. You see the full
conversation in the TUI in real time and on your phone.

UI:
  - /telegram or /tg with no arg opens a picker (connect /
    disconnect / status) that reflects current state.
  - /telegram connect  starts the bridge. Refuses if bot.json
    has no token (tells you to run `zot telegram-bot setup`) or
    if the background daemon is already polling.
  - /telegram disconnect  stops the bridge cleanly.
  - /telegram status  one-liner: "connected as @botname, paired
    with user X" / "background daemon running (pid N)" /
    "not configured" / "disconnected".
  - Status bar gets a "· tg · ~/cwd" tag while the bridge is
    active, next to the "· jailed ·" tag if that's also on.

How it's wired:

  internal/agent/modes/telegram/bridge.go (new)
    A slim Bridge type that owns the long-poll loop + typing
    indicator + reply sender but delegates the agent side to a
    Host interface. Not an agent itself - just a courier that
    pushes inbound DMs at a host and relays outbound text.

  internal/agent/modes/telegram_dialog.go (new)
    Picker with connect / disconnect / status rows. Shape
    mirrors the logout dialog: arrow keys, enter, esc.

  internal/agent/modes/interactive.go
    - New SubmitOrQueue(text, images) that runs if idle or
      queues if busy. Telegram Host calls this so DMs use the
      same queuing semantics as the user's editor submit.
    - New CancelTurn() for when Telegram sends /stop.
    - telegramHost adapter wires the Interactive to the
      bridge without a cyclic import (bridge lives in
      modes/telegram, interactive in modes; the adapter is
      in modes so it's fine).
    - EvAssistantMessage handler now also forwards the final
      visible text to the bridge when active (goroutine, so
      the network call doesn't hold the event-loop lock).
    - Bridge is stopped on zot exit via a defer in Run().

  internal/tui/view.go
    StatusBarParams gains Telegram bool; the cwd line builds a
    composite "· jailed · tg · ~/cwd" when both tags apply.

  internal/agent/modes/slash_suggest.go
    /telegram added to the slash catalog.

Collision safety:
  /telegram connect refuses when the background daemon
  (telegram.IsRunning via bot.pid) is alive. Two concurrent
  long-poll consumers of the same bot always race and one
  drops half the updates; refusing up-front beats half-working
  silently. Message tells the user exactly what to do.

Attachments:
  Image attachments arriving in Telegram are downloaded and
  queued as user-prompt images (same code path as drag-drop).
  Non-image attachments are ignored for now.

Pairing:
  First Telegram user to DM /start claims the bridge; the id
  is persisted to bot.json so subsequent connects are already
  paired. Anyone else DMing the bot gets "this bot is paired
  with a different user."

README: /telegram row added to the slash-commands table.
2026-04-20 09:18:04 +02:00
..
editor.go fix(tui): three cursor/alignment fixes in the editor and /help 2026-04-19 20:25:34 +02:00
highlight.go chore: scrub stray "pi" references from source comments 2026-04-19 17:06:45 +02:00
image.go fix ci: portable syscall.Select via x/sys/unix; gofmt pass 2026-04-18 10:55:42 +02:00
input.go add collapsible code blocks 2026-04-18 10:30:29 +02:00
markdown.go fix code highlighting 2026-04-18 10:16:06 +02:00
partialjson.go feat(tui): live-stream file body during write/edit tool calls 2026-04-20 08:37:14 +02:00
partialjson_test.go feat(tui): live-stream file body during write/edit tool calls 2026-04-20 08:37:14 +02:00
quote_paste_test.go tui: quote drag-dropped file paths in the input editor 2026-04-19 13:01:37 +02:00
render.go tui: quote drag-dropped file paths in the input editor 2026-04-19 13:01:37 +02:00
resize_unix.go fix ci: portable syscall.Select via x/sys/unix; gofmt pass 2026-04-18 10:55:42 +02:00
resize_windows.go initial commit 2026-04-17 20:36:38 +02:00
statusbar_test.go feat(ext): phase 4 - full-event interception, arg rewrites, /reload-ext 2026-04-19 17:02:04 +02:00
terminal.go initial commit 2026-04-17 20:36:38 +02:00
theme.go fix ci: portable syscall.Select via x/sys/unix; gofmt pass 2026-04-18 10:55:42 +02:00
view.go feat(tui): /telegram connect | disconnect | status 2026-04-20 09:18:04 +02:00
wrap_test.go fix(tui): three cursor/alignment fixes in the editor and /help 2026-04-19 20:25:34 +02:00