Complete rewrite from tmux + JSONL parsing to a clean PTY-based approach. The proxy spawns Claude CLI in a pseudo-terminal via node-pty and relays terminal I/O as binary WebSocket frames to the simple-chat backend, which forwards them to the browser where xterm.js renders a full terminal. - node-pty PTY manager with 50KB replay buffer per session - Binary frame protocol with chatId multiplexing - WebSocket client with auto-reconnection and heartbeat - Directory listing and session listing for the web UI - README with setup instructions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8.0 KiB
8.0 KiB
Claude CLI Proxy — Требования
Функциональные требования
FR-1: WebSocket-соединение с бэкендом
- Подключение к бэкенду simple-chat через WebSocket по настраиваемому URL
- Аутентификация с помощью
PROXY_TOKEN - Отправка идентификации устройства при подключении
- Поддержание постоянного соединения с автоматическим переподключением
FR-2: Управление tmux-сессиями
- Управление одной tmux-сессией (настраиваемое имя, по умолчанию
claude-proxy) - Создание новых tmux-окон по запросу (одно на чат)
- Запуск
claudeCLI в новых окнах илиclaude --resume <sessionId>для существующих сессий - Закрытие окон при завершении чатов
- Отправка нажатий клавиш в окна (сообщения пользователя, клавиши)
- Захват содержимого панели для скриншотов
FR-3: Мониторинг JSONL-транскриптов
- Отслеживание JSONL-файлов транскриптов Claude CLI на предмет нового содержимого
- Инкрементальное чтение с отслеживанием смещения в байтах (без полного перечитывания)
- Парсинг JSONL-записей: сообщения пользователя, сообщения ассистента, вызовы инструментов, результаты инструментов
- Фильтрация системных/внутренних сообщений (события инициализации, конфигурации)
- Определение правильного пути к файлу через карту сессий и закодированную рабочую директорию
- Интервал опроса: 2 секунды
FR-4: Мониторинг строки состояния терминала
- Захват последних 3 строк каждой активной tmux-панели
- Парсинг строки состояния для извлечения:
- Названия проекта
- Названия модели и размера контекстного окна
- Процента использования контекста
- Процентов использования сессии и недели
- Режима разрешений
- Обнаружение интерактивных состояний UI (запросы разрешений, запросы ввода)
- Интервал опроса: 1 секунда
FR-5: Маппинг сессий через хук
- Установка хука SessionStart в настройках Claude CLI (
~/.claude/settings.json) - Хук захватывает sessionId и текущий tmux windowId при запуске Claude CLI
- Сохранение маппинга в
~/.claude-proxy/session_map.json - Чтение карты сессий для нахождения JSONL-файлов активных окон
FR-6: Выполнение команд
- Выполнение произвольных команд в tmux-панелях по запросу бэкенда
- Захват вывода команды и возврат на бэкенд (
send_command_capture)
FR-7: Список директорий и сессий
- Получение списка доступных рабочих директорий по запросу
- Получение списка возобновляемых сессий Claude CLI по запросу
FR-8: Скачивание файлов
- Скачивание файлов по URL из MinIO, на которые есть ссылки в сообщениях
- Обеспечение доступа к файлам через веб-интерфейс
FR-9: Синхронизация состояния
- При переподключении отправка полного состояния всех активных окон на бэкенд (
sync_state) - Отчёт о создании окон (
window_ready) и их закрытии (window_closed)
Нефункциональные требования
NFR-1: Надёжность
- Переподключение к бэкенду с экспоненциальной задержкой при разрыве соединения
- Возобновление мониторинга после переподключения без потери состояния
- Корректная обработка падений tmux-процессов
- Обработка отсутствующих или повреждённых JSONL-файлов без аварийного завершения
NFR-2: Производительность
- Опрос терминала с интервалом 1 секунда не должен вызывать заметную нагрузку на CPU
- Опрос JSONL с интервалом 2 секунды использует отслеживание смещения в байтах, чтобы не перечитывать файлы целиком
- Кеш mtime полностью пропускает неизменённые файлы
- Эффективные tmux-операции через прямой
execFile(без накладных расходов на shell)
NFR-3: Переносимость
- Работает на macOS (основная машина разработчика)
- Требования: Node.js, tmux, Claude CLI (
claudeв PATH) - Без Docker, без пайплайна деплоя
NFR-4: Безопасность
- Аутентификация по токену для WebSocket-соединения
- Отсутствие слушающих портов (только исходящие соединения)
- Карта сессий хранится локально без удалённого доступа
NFR-5: Поддерживаемость
- TypeScript со строгой типизацией
- Общие конфиги из @vigdorov/dev-configs (ESLint, Prettier, TSConfig)
- Модульная структура: connection, tmux, monitor, hook, files
Обработка граничных случаев
| Сценарий | Поведение |
|---|---|
| Бэкенд недоступен при запуске | Повтор с экспоненциальной задержкой |
| Бэкенд отключается во время сессии | Переподключение и синхронизация состояния |
| JSONL-файл ещё не создан | Пропуск мониторинга, повтор при следующем опросе |
| JSONL-файл удалён или перемещён | Сброс смещения в байтах, повторное обнаружение |
| tmux-сессия не запущена | Автоматическое создание сессии |
| Процесс tmux-окна завершился | Обнаружение через захват, отчёт window_closed |
| Карта сессий отсутствует | Создание пустого файла карты |
| Хук не установлен | Автоустановка при запуске прокси |
| Конфликт нескольких прокси | Один прокси на tmux-сессию по дизайну |
| Большие JSONL-файлы | Инкрементальное чтение через смещение в байтах, без полного перечитывания |
| Claude CLI отсутствует в PATH | Ошибка при создании окна, отчёт на бэкенд |