# `:agentik-tui` — Compose-for-Mosaic TUI-клиент к `/agentik` ## Что это Compose-style TUI-клиент в терминале на базе [Mosaic](https://github.com/JakeWharton/mosaic) (Jetpack Compose runtime, рендерится в ANSI-коды). Без `:`-команд (без vim-style prompt): клавиатурная навигация Tab/Enter/Esc/Ctrl-D/F1/стрелки + жирный focus indicator. - **Layout**: header (id/conv/focus) + history + input + footer. - **Focus**: Tab/Shift-Tab цикл по фокусам (input → history → sidebar). - **Input**: стандартное текстовое поле с курсором `|` посередине. - **Stream**: подписка на SSE в фон-корутинах, `StateFlow` + `collectAsState()` для UI-реактивности (см. Snake sample). Решает: полноценный TUI-клиент для тех, кто предпочитает мышкой кликать в терминале больше, чем печатать. В отличие от `:agentik-cli`, показывает историю диалога и текущий стрим в одном окне. ## Как запустить ### Требования - JVM 21+. - Запущенный `:standalone` (по умолчанию `http://localhost:8080/agentik`). - Реальный TTY (через `ssh -tt`, `tmux`, либо нативный terminal). ### Запуск из готового fatjar ```bash java --enable-native-access=ALL-UNNAMED \ -jar agentik-tui-0.1.0-all.jar \ --server http://192.168.76.166:8080/agentik ``` `--enable-native-access=ALL-UNNAMED` обязателен — Mosaic использует native syscalls для терминала. ### Запуск через Gradle (dev) ```bash ./gradlew :agentik-tui:run --args="--server http://localhost:8080/agentik" ``` ## Параметры CLI | Флаг | ENV | Что делает | |---|---|---| | `--server URL` | `AGENTIK_SERVER` | URL `/agentik` (default `http://localhost:8080/agentik`) | | `--id ID` | `USER`/`USERNAME` | Имя агента (default — текущий пользователь) | | `--no-history` | — | Не восстанавливать последнюю диалог после запуска | | `--help` | — | Показывает help и выходит | ## Keybindings | Клавиша | Когда | Что делает | |---|---|---| | `Tab` / `Shift-Tab` | глобально | Цикл фокусов: input → history → sidebar → ... | | `F1` | глобально | Toggle help overlay | | `Esc` | в input | Очистить input | | `Enter` | в input | Submit message | | `Backspace` / `Del` | в input | Удалить символ | | `←` `→` `Home` `End` | в input | Курсор | | `↑` `↓` | в history | Scrollback | | `Ctrl-D` / `Ctrl-C` | — | Exit (TODO — пока работает только вне стрима) | ## Переменные среды (сервера) См. [`../standalone/README.md`](../standalone/README.md). TUI получает URL сервера через `--server`, остальное настройка агента, а не клиента. ## Известное ограничение 1. **SSE в не-TTY ssh закрывается на default Ktor timeout** — то же, что для `:agentik-cli`. 2. **Mouse events не подключены** в v2 (Mosaic 0.18 не имеет built-in mouse-runtime). Планируется в v3 через termios SGR-mouse. 3. **Нативные target'ы (macOS / Linux x64+ARM64 / Windows x64)** собраны, но без `:client` (он JVM-only). Для нативной работы нужен альтернативный HTTP-клиент. ## Тесты ``` ./gradlew :agentik-tui:jvmTest ``` Тесты composable'ов и event-рендеринга. Включает smoke-test для key-event → AppState mutation → ре-рендер. ## Версии `gradle/libs.versions.toml` → `[versions] agentik-agentik-tui`. ## Архитектурная заметка UI-стейт держится в `StateFlow`, а **не** в Compose `mutableStateOf`. Причина: Mosaic 0.18 не триггерит recomposition от `mutableStateOf` -writes внутри `onPreviewKeyEvent`-handler'ов (см. Snake sample в репо Mosaic — они тоже используют `StateFlow` + `collectAsState()`).