Newer
Older
navi-1 / docs / plan_navi_code_tui.md

План: 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:
    • ChatPanelScrollableContainer + 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/)

    • BaseRendererCodeRenderer, 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-режимом.