# CLI / TUI Client Plan ## Overview Single executable with two interfaces, distributed via bbin/babashka: - **CLI mode**: one-off commands via args (send message, read history, check notifications) - **TUI mode**: full interactive terminal app (clojure-tui) Shared codebase — CLI and TUI use the same API client, auth, and config. ## Stack - Babashka for fast startup + distribution via bbin - clojure-tui (~/repos/clojure-tui) for TUI rendering - Shared API client library (HTTP) - Connects to TUI session manager via SSE for real-time updates - HTTP POSTs to TUI SM for client→server signals (typing indicators) ## Modes ### CLI Mode (`ajet-chat [args]`) Stateless, one-shot commands. Fast startup via Babashka. ``` ajet-chat send #general "hey everyone" ajet-chat read #general # last N messages ajet-chat read #general --since 1h # messages from last hour ajet-chat dm @alice "hey" # send a DM ajet-chat dm @alice # read DM history with alice ajet-chat dms # list DM conversations ajet-chat notifications # unread notifications ajet-chat channels # list channels ajet-chat status # connection/auth status ``` ### TUI Mode (`ajet-chat` or `ajet-chat tui`) Full interactive app. Launches when invoked with no command (or explicit `tui`). - Channel sidebar, message list, input - Real-time updates via TUI session manager (SSE) - Keyboard navigation, scrollback, search - Presence indicators, typing notifications - Inline image rendering (see below) ## Shared Components - **API client**: HTTP client for REST calls to API (via auth gateway) - **Auth/config**: token storage, server URL, credentials (~/.config/ajet-chat/) - **Message formatting**: rendering messages to terminal (shared between CLI output and TUI views) - **Notification model**: unread tracking, mention detection ## Image Rendering Inline image display in the terminal via [timg](https://github.com/hzeller/timg) (optional dependency). - If `timg` is on PATH, shell out to render images inline in both CLI and TUI modes - timg handles terminal protocol detection automatically (kitty, iTerm2, sixel, unicode block fallback) - Works over SSH - If `timg` is not available, fall back to: 1. Native kitty/sixel escape sequences for compatible terminals 2. No inline images (show a placeholder with filename/URL) - In TUI mode: coordinate timg output with clojure-tui's terminal state (suspend raw mode, render, resume) ## Distribution - Packaged as a bbin-installable babashka script/jar - `bbin install io.github.ajet/ajet-chat-cli` (or similar) - Single `ajet-chat` binary on PATH ## TODO - [ ] Set up babashka-compatible project structure - [ ] CLI arg parsing (babashka.cli or tools.cli) - [x] API client module (shared between CLI and TUI) — `ajet.chat.shared.api-client` in shared/ - [ ] Auth flow: login, token storage, refresh - [ ] CLI commands: send, read, notifications, channels, status - [ ] TUI layout (channels sidebar, messages, input) - [ ] TUI real-time subscription via session manager - [ ] TUI keyboard navigation and commands - [ ] bbin packaging and install