# 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 <command> [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
