# План: Navi Code TUI (OpenCode-style)

Цель: превратить `navi-code` из простого click-CLI в полноэкранный терминальный UI, вдохновлённый OpenCode, сохранив click-CLI как `navi-code --raw`.

---

## Принципы

- **Микро-архитектура**: каждый компонент отвечает за одну задачу, общаётся через события/шину.
- **Расширяемость**: новые slash-команды, виджеты, renderers, themes добавляются без переделки ядра.
- **Совместимость**: TUI и click-CLI используют общий `ws_client.py`, `api.py`, `config.py`, `state.py`.
- **Постепенность**: каждая фаза — отдельный коммит, после которого продукт работает.

---

## Общая архитектура

```
┌─────────────────────────────────────────────────────────────┐
│                      NaviCodeApp (Textual)                   │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────┐   │
│  │ ChatPanel    │  │ StatusPanel  │  │ SessionsPanel   │   │
│  │ (messages)   │  │ (profile,    │  │ (optional/right)│   │
│  │              │  │ model,       │  │                 │   │
│  │              │  │ connection)  │  │                 │   │
│  └──────────────┘  └──────────────┘  └──────────────────┘   │
│  ┌────────────────────────────────────────────────────────┐ │
│  │ InputBox (prompt frame, slash commands, @/! parsing)   │ │
│  └────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│  EventBus / Dispatcher                                       │
│  - WebSocket events → ChatPanel/StatusPanel                 │
│  - User input → CommandParser → execute command/send message │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│  Shared services                                             │
│  - NaviWebSocketClient                                       │
│  - api (REST wrappers)                                       │
│  - StateManager (~/.navi_code/state.json)                    │
│  - Settings                                                  │
└─────────────────────────────────────────────────────────────┘
```

---

## Фазы

### Phase 3 — TUI skeleton

- Добавить `textual>=0.70` в `pyproject.toml`.
- Создать `clients/terminal/tui_app.py` с базовым `App`:
  - `ChatPanel` — `ScrollableContainer` + RichLog для сообщений.
  - `StatusPanel` — Static/Label с профилем, сессией, моделью, статусом.
  - `InputBox` — кастомный виджет ввода с рамкой в стиле OpenCode.
- `navi-code` по умолчанию запускает TUI; `navi-code --raw` — старый click-CLI.
- Интегрировать `NaviWebSocketClient` с Textual event loop через `asyncio.create_task` + `call_from_thread`/`post_message`.
- Базовый рендеринг событий: `stream_delta`, `thinking_delta`/`thinking_end`, `tool_started`/`tool_call`, `error`, `stream_end`.
- Добавить `TuiRenderer`, который превращает WebSocket-события в Rich renderables.
- Обновить тесты: хотя бы один smoke-test, что TUI App монтируется и запускается без ошибок.

### Phase 4 — OpenCode UX

- **Slash commands**: `/help`, `/new`, `/sessions`, `/switch`, `/profile`, `/thinking`, `/compact`, `/quit`, `/models`.
- **Command palette**: `Ctrl+P`, поиск по командам и настройкам.
- **`@` file references**: fuzzy autocomplete файлов в CWD при вводе `@`.
- **`!` shell pre-command**: если сообщение начинается с `!`, выполнить shell и подставить вывод.
- **Permission prompt**: inline prompt для destructive tool calls (`rm`, overwrite, format), кнопки Allow once / Allow always / Reject.
- **Markdown/code highlighting**: `rich.markdown` + `rich.syntax` в ChatPanel.
- **Diff/artifact renderers**: расширяемый `ContentRenderer` registry — code, diff, plain, image mention.

### Phase 5 — Polish & config

- **Mouse support** включить в Textual.
- **Themes**: `/themes` + `~/.navi_code/tui.json` с `theme`, `keybinds`, `diff_style`, `mouse`, `scroll_speed`.
- **SessionsPanel**: боковая панель со списком сессий, переключение по клику/стрелкам.
- **Export**: `/export` сохраняет текущий чат в markdown и открывает `$EDITOR`.
- **Advanced status panel**: tokens used, remaining iterations, backend, connection health.
- **Undo/Redo**: если получится интегрировать с git — отдельно.
- **Тесты**: unit + TUI integration tests через Textual Pilot.

---

## Расширяемые точки

1. **Command registry** (`clients/terminal/commands/registry.py`)
   - Каждая slash-команда = класс с `name`, `aliases`, `description`, `keybind`, `async execute(ctx)`.
   - Регистрация через декоратор `@register_command`.

2. **Content renderers** (`clients/terminal/renderers/`)
   - `BaseRenderer` → `CodeRenderer`, `DiffRenderer`, `MarkdownRenderer`, `ToolCallRenderer`, `ErrorRenderer`.
   - `RendererRegistry` выбирает по `type`/`mime`.

3. **Themes** (`clients/terminal/themes/`)
   - `Theme` dataclass: цвета рамок, фона, акцента, статуса, ошибок, thinking.
   - `ThemeRegistry` с built-in темами и загрузкой из `tui.json`.

4. **Event bus** (`clients/terminal/events.py`)
   - Textual-native `post_message`, но с типизированными событиями `WsEvent`, `CommandEvent`, `PermissionEvent`.

5. **Permission engine** (`clients/terminal/permissions.py`)
   - Правила по имени инструмента + action/pattern.
   - `PermissionStore` хранит `allow_always` в `~/.navi_code/permissions.json`.

---

## Интеграция с существующим CLI

- `cli.py` остаётся, получает флаг `--raw`.
- `tui_app.py` импортирует `Settings`, `StateManager`, `api`, `NaviWebSocketClient`.
- `render.py` остаётся для `--raw`; TUI использует новые renderers поверх Rich.

---

## Тестирование

- `tests/clients/test_tui_app.py` — монтирование App, проверка layout.
- `tests/clients/test_tui_commands.py` — unit tests командного парсера и registry.
- `tests/clients/test_tui_renderers.py` — рендеринг разных типов контента.
- `tests/clients/test_tui_permissions.py` — permission prompt и `allow_always`.
- Smoke test: `navi-code --help` и `navi-code --version` работают в обоих режимах.

---

## Критерий завершения

- `navi-code` запускается в полноэкранном TUI.
- Click-CLI доступен через `navi-code --raw`.
- Все новые файлы покрыты тестами, ruff чистый, pytest зелёный.
- Документация `docs/navi_code_cli.md` обновлена с TUI-режимом.
