Andrey Epifancev fe43d2ea7b spec: headless panel service and client-side background (OpenSpec change)
Refs #4

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 20:31:09 +04:00

8.4 KiB
Raw Blame History

Spec Delta

Purpose

Определяет, где и как работает сервер панели «Claude»: фоновая служба пользователя, не зависящая от iTerm2, единственный владелец порта панели, тонкая регистрация в Toolbelt и установка/удаление.

ADDED Requirements

Requirement: Сервер панели работает без iTerm2

Сервер панели SHALL отдавать страницу, дерево сессий, лимиты и баланс на 127.0.0.1:<port> (по умолчанию 8766), пока пользователь вошёл в систему, независимо от того, запущен ли iTerm2.

Scenario: iTerm2 не запущен

  • WHEN пользователь вошёл в систему, iTerm2 не запущен, а сессия Claude Code работает в tmux
  • THEN http://127.0.0.1:8766/ отвечает 200 и показывает эту сессию с её субагентами, моделью, контекстом и worktree, а нижний блок показывает лимиты и баланс

Scenario: Имена сессий в tmux

  • WHEN сессия Claude Code работает в панели tmux
  • THEN её имя берётся из заголовка панели tmux или из сессия:окно имя_окна, как и раньше

Requirement: Служба стартует при входе и перезапускается при падении

Сервер панели SHALL запускаться автоматически при входе пользователя в систему и SHALL перезапускаться, если его процесс завершился.

Scenario: Вход в систему

  • WHEN пользователь входит в систему на Mac после перезагрузки
  • THEN сервер панели запускается без открытия iTerm2 и каких-либо действий пользователя

Scenario: Падение процесса

  • WHEN процесс сервера панели завершился (ошибка, kill)
  • THEN он снова запущен и отвечает на порту в пределах нескольких десятков секунд

Requirement: Порт панели занимает один процесс

На порту панели SHALL работать ровно один сервер; лимиты и баланс SHALL опрашиваться одним процессом, чтобы не удваивать запросы к API.

Scenario: iTerm2 запускается при работающей службе

  • WHEN служба уже отвечает на порту и пользователь запускает iTerm2
  • THEN второй сервер не запускается, в API лимитов идёт один поток запросов, а в Toolbelt появляется панель «Claude», показывающая ту же страницу

Requirement: Toolbelt показывает панель фоновой службы

Скрипт панели в iTerm2 SHALL регистрировать web view «Claude» в Toolbelt, указывающий на адрес фоновой службы, и SHALL NOT поднимать собственный сервер.

Scenario: Toolbelt при запущенной службе

  • WHEN iTerm2 запущен и пользователь выбирает Toolbelt → Claude
  • THEN панель показывает ту же страницу, что и http://127.0.0.1:8766/ в браузере

Scenario: Служба не отвечает при старте iTerm2

  • WHEN iTerm2 стартует, а служба на порту не отвечает
  • THEN скрипт просит launchd запустить службу и всё равно регистрирует web view

Requirement: Сервер доступен только локально

Сервер панели SHALL слушать только 127.0.0.1; доступ с других устройств возможен только через туннель (например, SSH local forward).

Scenario: Запрос из локальной сети

  • WHEN устройство в той же сети обращается к Mac по его LAN-адресу на порт панели
  • THEN соединение не устанавливается

Requirement: Действия по клику работают через tmux

Переход к сессии и открытие worktree по клику SHALL выполняться средствами tmux для сессий в tmux, независимо от iTerm2 и от того, на каком устройстве открыта страница.

Scenario: Переход к сессии с iPad

  • WHEN пользователь с iPad (страница через туннель) нажимает «↗ вкладка» у сессии в tmux
  • THEN клиент tmux переключается на окно и панель этой сессии

Scenario: Открытие worktree с iPad

  • WHEN пользователь нажимает ⎇ папка у сессии в tmux
  • THEN в том же окне tmux открывается новая панель с файловым менеджером в этой папке

Requirement: Установка и удаление службы

install.sh SHALL устанавливать, (пере)запускать службу и останавливать прежний сервер, державший порт; повторный запуск SHALL быть безопасным. uninstall.sh SHALL останавливать и удалять службу.

Scenario: Обновление старой установки

  • WHEN у пользователя стоит прежняя версия (сервер внутри iTerm2) и он запускает install.sh
  • THEN прежний сервер остановлен, служба установлена и отвечает на порту, а iTerm2-скрипт обновлён до регистратора

Scenario: Повторная установка

  • WHEN install.sh запускается второй раз подряд
  • THEN служба одна, отвечает на порту, записи хуков в settings.json не задублированы

Scenario: Запуск по SSH

  • WHEN install.sh или uninstall.sh запущен из SSH-сессии
  • THEN скрипт сообщает, что его нужно запускать за самим Mac, и завершается с ненулевым кодом, ничего не изменив: прежний сервер продолжает работать

Scenario: Удаление

  • WHEN пользователь запускает uninstall.sh
  • THEN служба остановлена, её описание удалено, порт свободен и после повторного входа в систему служба не запускается

REMOVED Requirements

Requirement: Тема панели из профиля iTerm2

Reason: Сервер больше не связан с iTerm2; фон задаётся на клиенте (см. panel-appearance). Migration: Выставить фон шестерёнкой ⚙ внизу панели; ключи use_profile_theme и theme_variant в config.json удалить (они игнорируются).

Requirement: Возможности iTerm2 для сессий вне tmux

Reason: Нужна живая связь сервера с iTerm2, а сервер теперь фоновый; пользователь держит все сессии в tmux. Migration: Запускать claude внутри tmux. Для сессий вне tmux имя берётся из заголовка сессии Claude Code или папки, переход во вкладку и lf в разделённой панели iTerm2 недоступны; режим tmux -CC не поддерживается для перехода.