Files
agentik/agentik-tui
subochev 5bdc517988 Добавляет Cursor/OffsetSequencer в :outbox-api и интегрирует PersistentOffsetSequencer через :outbox-ksqlite.
Введение монотонного offset'а как персистентного состояния агента:
offset'ы переживают рестарт standalone-агента, клиент продолжает
синхронизацию инкрементально, без полной re-sync с нуля.

outbox-api:
  - Cursor (offset: Long) — курсор в журнале событий агента.
  - OffsetSequencer — интерфейс резервирования уникального offset.
  - CursorStore — персистентное хранилище текущего offset'а.
  - PersistentOffsetSequencer — декоратор над любым OutboxStore,
    обновляет CursorStore на каждом append (atomic transaction).
  - OutboxGapException — клиент запросил after < earliestCursor() →
    сервер не может удовлетворить, клиент обязан делать full resync.
  - DurableEvent переименован из Event.kt → DurableEvent.kt (Event.kt
    был общим sealed-типом, теперь это термин из спеки).
  - MutableOutboxStore и OutboxStore теперь читают offset через
    CursorStore вместо in-memory counter'а.

outbox-inmemory:
  - InMemoryOffsetSequencer — для тестов и dev-режима.
  - InMemoryOutboxStore теперь принимает OffsetSequencer в конструкторе.

outbox-ksqlite (новый модуль):
  - KsqliteCursorStore — таблица outbox_cursor (agent_id TEXT PK,
    offset INTEGER NOT NULL DEFAULT 0, updated_at INTEGER NOT NULL).
  - KsqliteCursorStoreTest — 4 теста (set/get, monotonic, concurrent).

proto + server:
  - Snapshot.proto — server-state snapshot endpoint для клиентов,
    которым нужна полная материализация (использование TBD).
  - Routes.kt + SnapshotRouteTest — endpoint /agentik/snapshot (GET).

journal-ksqlite:
  - KsqliteJournalStore.listFlow/append — без изменений по API,
    нотации минимальные (codecs).

standalone:
  - DurableLog (бывший ChatAgent-orchestration) — атомарный commit
    события в OutboxStore + PersistentOffsetSequencer + materialization
    (через Reducer) одной транзакцией.
  - SqliteStores — добавляет KsqliteCursorStore в bundle, единая
    shared-connection для всех ksqlite-сторов standalone-агента.
  - ChatAgent / ConversationLoop / ConversationEvents / ReflectionScheduler /
    ToolDispatcher — переход на новые абстракции.
  - standalone/build.gradle.kts — implementation(project(':outbox-ksqlite'))
    включено (раньше было закомментировано — модуль только создавался).

client:
  - AgentikAgent / AgentClient / HttpEventStore / HttpJournalStore /
    ReconnectingOutbox — используют Cursor через transport API.
  - client/README.md — синхронизирован с новым поведением (468 строк
    diff — это в основном оформление и примеры).

kotlinx-io: 0.8.0 → 0.9.1 в libs.versions.toml (см. sync-core tests).

SYNC-SYSTEM.md (в корне) — спецификация, на которую ссылается и
:sync-core (эта сессия), и эта Cursor-абстракция в outbox-api.

Тесты: standalone 132, journal-ksqlite 25, outbox-inmemory 20,
outbox-ksqlite 4, client 10, sync-core 74 — все зелёные на jvm;
sync-core linuxX64 74 тоже зелёный.

sync2/ (заброшенный stub с одним build.gradle.kts) удалён.
2026-10-02 01:16:15 +03:00
..

:agentik-tui — Compose-for-Mosaic TUI-клиент к /agentik

Что это

Compose-style TUI-клиент в терминале на базе 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

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)

./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. 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()).