112 lines
8.4 KiB
Markdown
112 lines
8.4 KiB
Markdown
# 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` не поддерживается для перехода.
|