spec: archive headless-panel change (#4)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
5320bc2c46
commit
521182d4a4
64
openspec/specs/panel-appearance/spec.md
Normal file
64
openspec/specs/panel-appearance/spec.md
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# panel-appearance Specification
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
Позволяет пользователю выбрать фон панели прямо на странице, отдельно на каждом устройстве
|
||||||
|
(Safari на iPad, Toolbelt на Mac), чтобы панель не резала глаза рядом с его терминалом.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
### Requirement: Шестерёнка настройки фона
|
||||||
|
Нижняя строка панели (рядом с «обновлено ЧЧ:ММ:СС») SHALL содержать значок ⚙. Тап по нему SHALL
|
||||||
|
раскрывать строку с образцами фона, кнопкой «свой цвет» и кнопкой «сброс»; повторный тап SHALL её
|
||||||
|
сворачивать. В свёрнутом виде, кроме значка, ничего нового на странице не видно.
|
||||||
|
|
||||||
|
#### Scenario: Раскрыть и свернуть
|
||||||
|
- **WHEN** пользователь нажимает ⚙
|
||||||
|
- **THEN** появляется строка образцов; при повторном нажатии она скрывается
|
||||||
|
|
||||||
|
#### Scenario: Попадание пальцем
|
||||||
|
- **WHEN** страница открыта в Safari на iPad
|
||||||
|
- **THEN** ⚙, образцы и кнопки нажимаются пальцем без промахов (не мельче привычных элементов
|
||||||
|
управления iPadOS)
|
||||||
|
|
||||||
|
### Requirement: Выбор фона
|
||||||
|
Выбор образца или своего цвета SHALL сразу менять фон всей панели, включая окно сообщений. Цвет
|
||||||
|
основного текста, приглушённого текста, линий дерева и разделителей SHALL подстраиваться под
|
||||||
|
яркость фона, чтобы оставаться читаемым. Цвета статусов и лимитов (зелёный, жёлтый, красный)
|
||||||
|
SHALL оставаться прежними.
|
||||||
|
|
||||||
|
#### Scenario: Светлый фон
|
||||||
|
- **WHEN** пользователь выбирает светлый образец
|
||||||
|
- **THEN** фон становится светлым, а текст — тёмным и читаемым
|
||||||
|
|
||||||
|
#### Scenario: Свой цвет
|
||||||
|
- **WHEN** пользователь нажимает «свой цвет» и выбирает цвет в системной палитре
|
||||||
|
- **THEN** фон панели становится этим цветом, текст подстраивается
|
||||||
|
|
||||||
|
### Requirement: Выбор хранится на устройстве
|
||||||
|
Выбранный фон SHALL сохраняться средствами того браузера или web view, где он выбран, и SHALL
|
||||||
|
применяться при каждом открытии и автоматической перезагрузке страницы без мелькания темы по
|
||||||
|
умолчанию. Выбор на одном устройстве SHALL NOT влиять на другие. Если клиент не сохраняет данные
|
||||||
|
страницы между своими перезапусками (возможно, web view Toolbelt), после перезапуска клиента
|
||||||
|
показывается тема по умолчанию; на сервере выбор не хранится.
|
||||||
|
|
||||||
|
#### Scenario: Клиент без постоянного хранилища
|
||||||
|
- **WHEN** выбор фона сделан в Toolbelt, а web view Toolbelt не сохраняет данные между
|
||||||
|
перезапусками iTerm2, и iTerm2 перезапущен
|
||||||
|
- **THEN** панель в Toolbelt показывает тему по умолчанию
|
||||||
|
|
||||||
|
#### Scenario: Перезагрузка страницы
|
||||||
|
- **WHEN** пользователь выбрал фон в Safari на iPad и страница перезагрузилась (сама раз в минуту
|
||||||
|
или вручную)
|
||||||
|
- **THEN** сразу отображается выбранный фон
|
||||||
|
|
||||||
|
#### Scenario: Разные устройства
|
||||||
|
- **WHEN** в Safari на iPad выбран светлый фон
|
||||||
|
- **THEN** панель в Toolbelt на Mac сохраняет свой фон
|
||||||
|
|
||||||
|
### Requirement: Сброс к теме по умолчанию
|
||||||
|
«Сброс» SHALL удалять сохранённый выбор и возвращать тему, которую отдаёт сервер. Тема по умолчанию
|
||||||
|
SHALL выглядеть как нынешний профиль iTerm2 пользователя (`Chat`: фон `#002b36`, текст `#aacace`).
|
||||||
|
|
||||||
|
#### Scenario: Сброс
|
||||||
|
- **WHEN** пользователь нажимает «сброс»
|
||||||
|
- **THEN** панель показывает тему по умолчанию, и после перезагрузки она остаётся по умолчанию
|
||||||
96
openspec/specs/panel-service/spec.md
Normal file
96
openspec/specs/panel-service/spec.md
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
# panel-service Specification
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
Определяет, где и как работает сервер панели «Claude»: фоновая служба пользователя, не зависящая
|
||||||
|
от iTerm2, единственный владелец порта панели, тонкая регистрация в Toolbelt и установка/удаление.
|
||||||
|
|
||||||
|
## 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** служба остановлена, её описание удалено, порт свободен и после повторного входа в систему
|
||||||
|
служба не запускается
|
||||||
Loading…
x
Reference in New Issue
Block a user