Терминальный клиент для общения с Navi через WebSocket.
CLI устанавливается вместе с пакетом navi:
pip install -e .
После установки доступна команда navi-code. Внутри репозитория можно запускать без установки:
python -m clients.terminal
navi-code
Клиент подключается к http://localhost:8000, создаёт или восстанавливает сессию и запускает чат.
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 |
Создать новую сессию, даже если сохранена старая. |
--resume <session_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 "объясни этот файл"). Неизвестные флаги передаются как часть запроса.
При закрытии TUI печатается подсказка вида Resume with: navi-code --resume <session_id> — чтобы продолжить ту же сессию в следующий раз.
| Команда | Алиасы | Описание | |
|---|---|---|---|
/help |
Список команд. | ||
/new |
clear |
Создать новую сессию (в TUI clear — алиас new, а не очистка локального state). |
|
/sessions |
resume, continue |
Открыть picker сессий, отфильтрованный по профилю navi_code, с кнопкой «✚ New session» и поиском по типу. |
|
/switch [id] |
Гибридный режим: без аргумента / неоднозначный префикс → picker, префильтрованный по вводу; точный id или уникальный префикс navi_code → мгновенное переключение. |
||
/profile |
Показать текущий профиль и id сессии. | ||
/export [path] |
save |
Экспортировать текущую сессию в Markdown; без пути — во временный файл и $EDITOR. |
|
/themes |
Открыть выбор темы с live-preview. | ||
| `/mouse on\ | off` | Включить/выключить поддержку мыши (требует перезапуска). | |
/thinking |
Переключить отображение thinking-блоков в текущей сессии. | ||
/compact |
Вручную запустить сжатие контекста текущей сессии (шлёт {"type":"compact"}). |
||
/quit |
exit, q |
Выйти. |
Подсказки к slash-командам появляются inline над полем ввода при вводе /: Up/Down подсвечивают вариант, Enter выполняет подсвеченный, Tab дополняет имя.
В интерактивном режиме (navi-code) экран состоит из пяти регионов:
ChatPanel (левая колонка) — история сообщений и карточки событий.Vertical(StatusPanel, TodoPanel):
StatusPanel — профиль, сессия, текущая модель, статус соединения, backend, тема, hotkey-подсказки.TodoPanel — живой список todo текущей сессии: in_progress наверху, затем pending, потом failed/skipped, done внизу. Todo субагентов сюда не попадают (они изолированы). Обновляется по событию todo_updated, при подключении подтягивается через REST.InputBox (под чатом) — многострочное поле ввода.StatusBar (нижняя строка, заменяет стандартный Textual Footer) — activity-индикатор (анимированный braille-спиннер + фаза), live-таймер длительности запроса, gauge заполнения контекстного окна (used/max · pct%, цвет по уровню), hotkey-комбинации.Sessions-панели в правой колонке больше нет — переключение сессий через модальный picker (/sessions, /switch).
Поле ввода многострочное — перенос текста по ширине автоматический, высота поля растёт вместе с содержимым. Enter отправляет сообщение целиком. Префикс ! выполняет локальную shell-команду (passthrough, не уходит на сервер). @путь раскрывает ссылку на файл и прикрепляет его к сообщению.
max_visible_items); более старые сворачиваются в подсказку «… N earlier messages not shown». Рендер кэшируется по сигнатуре.StatusPanel показывается «reconnecting…».⚙ Planning · <фаза> (обновляется на месте). Когда план готов — карточка Plan.spawn_agent). Карточка ↘ subagent · <профиль> при запуске и ↙ subagent · <профиль> ✓/✗ с результатом; задача и брифинг — в теле./compact) — карточка Context compressed: N → M messages с dim markdown-текстом саммари внутри.stream_end — строка ⏱ … с длительностью запроса и gauge заполнения контекста.Ctrl+P) — поиск команд по имени.| Комбинация | Действие |
|---|---|
Ctrl+P |
Command palette |
Ctrl+X C |
/compact (сжатие контекста) |
Ctrl+X T |
/thinking (toggle thinking-блоков) |
Ctrl+X Q |
/quit |
Esc |
Остановить стрим |
Клиент сохраняет session_id в ~/.navi_code/state.json, чтобы восстановить диалог при следующем запуске. Удалите файл или используйте --new-session, чтобы начать с чистого листа. TUI-настройки (тема, мышь, max_visible_items) хранятся в ~/.navi_code/tui.json.
События WebSocket рендерятся по-разному в TUI и в plain CLI (--raw):
stream_start — запускает activity-индикатор и live-таймер.stream_delta — печатается inline, как в обычном чате.stream_end — метаданные хода (⏱ длительность + gauge контекста).stream_stopped — отметка об остановке пользователем.tool_started / tool_call — карточки инструментов: имя, аргументы, краткий результат (если не задан --no-events). В metadata.step_text для todo-update передаётся текст изменённого шага.thinking_delta / thinking_end / turn_thinking — блоки рассуждений (только с --show-thinking); turn_thinking — полный блок субагента целиком.planning_status — rolling-строка фазы (в plain CLI — [planning] <фаза>).plan_ready — карточка Plan (в plain CLI — [plan]…[/plan]).model_info — обновляет модель в StatusPanel.todo_updated — обновляет TodoPanel.compression_started — activity-фаза «compression».context_compressed — карточка Context compressed: N → M messages с саммари.error — красным цветом.heartbeat / session_sync — служебные, в чат не выводятся.$ 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
Resume with: navi-code --resume a1b2c3d4
Код CLI находится в clients/terminal/:
cli.py — точка входа, разбор аргументов, raw-режим, resume-hint.ws_client.py — низкоуровневый WebSocket-клиент.api.py — REST-запросы к серверу.render.py — рендеринг событий в терминал (plain CLI).state.py — сохранение session_id в ~/.navi_code/state.json.config.py — настройки из переменных окружения NAVI_CODE_*.tui/tui_app.py — Textual-приложение, bindings, диспетчер событий.tui/ws_bridge.py — владеет жизненным циклом WebSocket в TUI (включая auto-reconnect).tui/chat_model.py — модель чат-айтемов и преобразование WS-событий.tui/widgets/ — ChatPanel, InputBox, CommandHints, StatusBar, StatusPanel, TodoList (+ ActivityIndicator, ElapsedTime).tui/renderers/ — рендереры карточек по типам событий (сообщения, markdown, рассуждения, инструменты, планирование, субагент, todo, summary, turn_meta, diff, artifact, error); диспетчеризация через RendererRegistry.tui/commands/ — slash-команды (builtin.py: /help, /new, /sessions, /switch, /profile, /export, /themes, /mouse, /thinking, /compact, /quit).tui/screens/ — модальные экраны: command_palette, sessions_picker, theme_picker, permission_dialog.tui/permissions.py, tui/shell_runner.py, tui/file_refs.py, tui/duration.py, tui/context.py, tui/events.py — диалоги разрешений, !shell, @file-refs, таймеры, контекст, вспомогательные события.tui/settings.py — persisted TUI config (~/.navi_code/tui.json).tui/themes.py — палитры тем.Тесты: tests/clients/test_terminal_client.py, tests/clients/test_terminal_ws.py, tests/clients/test_tui_*.py.