# Navi Code CLI

Терминальный клиент для общения с Navi через WebSocket.

## Установка

CLI устанавливается вместе с пакетом `navi`:

```bash
pip install -e .
```

После установки доступна команда `navi-code`. Внутри репозитория можно запускать без установки:

```bash
python -m clients.terminal
```

## Использование

### Интерактивный режим

```bash
navi-code
```

Клиент подключается к `http://localhost:8000`, создаёт или восстанавливает сессию и запускает чат.

### One-shot режим

```bash
navi-code "объясни, что делает этот файл"
navi-code --new-session "напиши pytest-тест для функции foo"
```

### Параметры

| Флаг | Описание |
|---|---|
| `--base-url URL` | Базовый URL сервера Navi. |
| `--ws-url URL` | URL WebSocket (по умолчанию производный от `--base-url`). |
| `--profile-id ID` | Профиль для новой сессии. |
| `--new-session` | Создать новую сессию, даже если сохранена старая. |
| `--show-thinking` | Показывать блоки рассуждений модели. |
| `--no-events` | Скрывать события `tool_started` / `tool_call`. |
| `--mouse` / `--no-mouse` | Включить/выключить мышь в TUI на один запуск (перекрывает `tui.json`). |
| `--theme NAME` | Запустить TUI с указанной темой. |
| `--raw` | Запустить plain CLI вместо TUI (используется по умолчанию, когда передан позиционный запрос). |
| `--version` | Версия клиента. |
| `-h`, `--help` | Показать справку по использованию. |

Любой позиционный аргумент воспринимается как запрос и запускает plain CLI в one-shot режиме (например `navi-code "объясни этот файл"`). Неизвестные флаги передаются как часть запроса.

## Команды в интерактивном режиме

| Команда | Описание |
|---|---|
| `/help` | Список команд. |
| `/new` | Создать новую сессию. |
| `/sessions` | Список сессий на сервере. |
| `/switch <id>` | Переключиться на другую сессию (можно по префиксу id). |
| `/profile` | Показать текущий профиль и id сессии. |
| `/export [path]` | Экспортировать текущую сессию в Markdown; без пути — во временный файл и `$EDITOR`. Если редактор не запускается, ошибка выводится в чат. |
| `/themes` | Открыть выбор темы с live-preview. |
| `/mouse on|off` | Включить/выключить поддержку мыши (требует перезапуска). |
| `/thinking` | Переключить отображение thinking-блоков в текущей сессии. |
| `/compact` | Вручную запустить сжатие контекста текущей сессии. |
| `/clear` | Очистить локально сохранённый `session_id`.
| `/quit` | Выйти. |

## Интерфейс TUI

В интерактивном режиме (`navi-code`) экран разделён на три зоны:

- **Левая панель (`ChatPanel`)** — история сообщений, поле ввода и текущий статус.
- **Правая верхняя панель (`StatusPanel`)** — текущий профиль, модель, статус соединения, токены и оставшиеся итерации.
- **Правая нижняя панель (`SessionsPanel`)** — список сессий на сервере с колонками ID, профиль и превью. Клик или `Enter` на строке переключает сессию.

Список сессий обновляется автоматически при запуске и при выполнении `/new`, `/sessions`, `/switch`.

### Поле ввода

Поле ввода многострочное — перенос текста по ширине автоматический, высота поля растёт вместе с содержимым (в пределах ограничения). `Enter` отправляет сообщение целиком (вместе с переносами). Принудительный перенос строки не поддерживается: терминалы не различают `Ctrl+Enter` от обычного `Enter`, поэтому сделан только автоматический перенос.

### Карточки в чате

Помимо обычных сообщений и блоков рассуждений, чат рендерит карточки для специальных событий:

- **Планирование.** Пока работает планировщик, показывается rolling-индикатор `⚙ Planning · <фаза>` (обновляется на месте, а не плодит строки). Когда план готов — карточка `Plan` с содержимым плана.
- **Субагент (`spawn_agent`).** Отдельная карточка `↘ subagent · <профиль>` при запуске и `↙ subagent · <профиль> ✓/✗` с результатом. Имя задачи и брифинг показаны в теле карточки.
- **Вложенные события субагента.** Рассуждения, планирование, карточки инструментов и плана субагента показываются с отступом и приглушённым стилем, чтобы визуально отделить их от основного хода сессии (TUI использует плоскую модель, вложенность передаётся через отступ).

## Состояние

Клиент сохраняет `session_id` в `~/.navi_code/state.json`, чтобы восстановить диалог при следующем запуске. Удалите файл или используйте `/clear`, чтобы начать с чистого листа.

## Рендеринг событий

События WebSocket рендерятся по-разному в TUI и в plain CLI (`--raw`):

- `stream_delta` — печатается inline, как в обычном чате.
- `tool_started` / `tool_call` — карточки инструментов: имя, аргументы, краткий результат (если включено `--show-events` / `--no-events` не задан).
- `thinking_delta` / `thinking_end` — блоки рассуждений, показываются только с `--show-thinking`.
- `planning_status` — индикатор текущей фазы планирования (в TUI — rolling-строка `⚙ Planning · <фаза>`; в plain CLI — `[planning] <фаза>`).
- `plan_ready` — готовый план (в TUI — карточка `Plan`; в plain CLI — блок `[plan]…[/plan]`).
- `turn_thinking` — полный блок рассуждений субагента целиком (не стримится по частям); в TUI это `subagent thinking` с отступом, в plain CLI — `[thinking]…(subagent)`.
- `error` — красным цветом.

## Пример сессии

```bash
$ navi-code
Created session a1b2c3d4 (profile navi_code)
Navi Code interactive mode. Type /quit to exit, /help for commands.
You: напиши скрипт, который считает строки в текущей директории
[tool: terminal]
{'cmd': 'find . -type f | wc -l'}
[tool result: terminal success=True]
42

Я насчитал 42 файла в текущей директории и её поддиректориях.
You: /quit
```

## Разработка

Код CLI находится в `clients/terminal/`:

- `cli.py` — точка входа и интерактивный цикл.
- `ws_client.py` — WebSocket-клиент.
- `api.py` — REST-запросы к серверу.
- `render.py` — рендеринг событий в терминал.
- `state.py` — сохранение `session_id` в `~/.navi_code/state.json`.
- `config.py` — настройки из переменных окружения `NAVI_CODE_*`.
- `tui/tui_app.py` — Textual-приложение.
- `tui/widgets/` — виджеты (`ChatPanel`, `StatusPanel`, `SessionsPanel`, `InputBox`).
- `tui/renderers/` — рендереры карточек по типам событий (сообщения, рассуждения, инструменты, планирование, субагент); диспетчеризация через `RendererRegistry`.
- `tui/commands/` — slash-команды (`/new`, `/sessions`, `/switch`, `/export`, `/themes`, `/mouse`).
- `tui/settings.py` — persisted TUI config (`~/.navi_code/tui.json`).

Тесты: `tests/clients/test_terminal_client.py`, `tests/clients/test_terminal_ws.py`, `tests/clients/test_tui_*.py`.
