spec: headless panel service and client-side background (OpenSpec change)
Refs #4 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
3ae32fadf9
commit
fe43d2ea7b
2
openspec/changes/headless-panel/.openspec.yaml
Normal file
2
openspec/changes/headless-panel/.openspec.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-10-18
|
||||
141
openspec/changes/headless-panel/design.md
Normal file
141
openspec/changes/headless-panel/design.md
Normal file
@ -0,0 +1,141 @@
|
||||
# Design: панель без iTerm2 + фон на клиенте
|
||||
|
||||
Issue: #4. Ветка: `feat/4-headless-panel`.
|
||||
|
||||
## Намерение
|
||||
|
||||
Пользователь смотрит панель с iPad: Termius держит SSH local forward `8766 → 127.0.0.1:8766` на Mac,
|
||||
страница открыта в Safari рядом с Termius (Split View). Все сессии Claude Code — в обычном tmux,
|
||||
который работает сам по себе. Сейчас страница пропадает, если на Mac не запущен iTerm2, потому что
|
||||
сервер поднимает скрипт AutoLaunch iTerm2. Переключение сессий с iPad уже работает — через tmux.
|
||||
Нужно: страница доступна всегда, пока Mac включён и пользователь вошёл; фон меняется прямо на
|
||||
странице, потому что тема по умолчанию в Safari раздражает.
|
||||
|
||||
Успех: iTerm2 закрыт → в Safari на iPad видно дерево сессий, лимиты и баланс; клики переключают
|
||||
tmux; фон выставлен под тему Termius и держится между перезагрузками.
|
||||
|
||||
## Цели
|
||||
- Фоновый сервер панели, независимый от iTerm2, автозапуск при входе, перезапуск при падении.
|
||||
- Один владелец порта 8766; iTerm2-скрипт только регистрирует web view в Toolbelt.
|
||||
- Шестерёнка ⚙ внизу панели (вариант A из мокапов): образцы фона, «свой цвет», «сброс»;
|
||||
выбор хранится на устройстве; текст подстраивается под яркость фона.
|
||||
- `install.sh`/`uninstall.sh` управляют службой; обновление старой установки без ручных шагов.
|
||||
|
||||
## Не цели
|
||||
- Досыл названий вкладок iTerm2 и цветов профиля в фоновый сервер (решено пользователем:
|
||||
в tmux имена и так из tmux; цвет — шестерёнкой, в Toolbelt тоже).
|
||||
- Доступ к странице из сети напрямую (только через туннель).
|
||||
- Мод Claude Code / TUI-версия панели (обсуждались, отложены).
|
||||
- Запуск службы без входа пользователя в систему на самом Mac (см. «Открытые вопросы»).
|
||||
|
||||
## Анти-цели (провал, даже если «работает»)
|
||||
- Два сервера одновременно или удвоенный опрос лимитов (эндпоинт отвечает 429).
|
||||
- Порт открыт наружу: в панели видны тексты сообщений сессий.
|
||||
- Мелькание темы по умолчанию при каждой автоперезагрузке страницы (раз в минуту) после выбора фона.
|
||||
- Установщик ломает чужие хуки/настройки или требует ручных шагов при обновлении.
|
||||
|
||||
## Ограничения
|
||||
- Python 3.8+, только стандартная библиотека; модуль `iterm2` — только в режиме регистратора.
|
||||
- macOS, `launchctl`; LaunchAgent в сессии пользователя (Aqua).
|
||||
- В LaunchAgent минимальный `PATH`: путь к `python3` фиксируется установщиком абсолютным; поиск
|
||||
`tmux`/`ps` уже идёт через `EXTRA_PATH` в коде.
|
||||
- Токен лимитов — из Keychain через `security`; служба должна работать в GUI-сессии пользователя,
|
||||
где Keychain разблокирован.
|
||||
- Сервер слушает только `127.0.0.1`.
|
||||
|
||||
## Решения, принятые с пользователем
|
||||
- Вариант 0 (SSH-туннель + Safari) — основной сценарий, мод/TUI не делаем.
|
||||
- Фоновая служба через LaunchAgent; один сервер на порту; iTerm2-скрипт — регистратор.
|
||||
- Цвет профиля iTerm2 не досылать и не читать (вариант 3): в Toolbelt фон тоже ставится шестерёнкой.
|
||||
- Место настройки фона — шестерёнка в нижней строке (вариант A).
|
||||
- Перезагрузка Mac без GUI-входа — не решаем сейчас, запоминаем на будущее.
|
||||
- `install.sh` / `uninstall.sh` запускаются только за самим Mac (не по SSH). При запуске из SSH-сессии
|
||||
(`SSH_CONNECTION`/`SSH_TTY` заданы) установщик предупреждает и завершается, ничего не меняя;
|
||||
в README — строка об этом.
|
||||
|
||||
## Как устроено (то, что решено)
|
||||
|
||||
### Режимы `claude_agents.py`
|
||||
Один исходный файл, два режима:
|
||||
- **Фоновый сервер** (`--headless`, запускает launchd системным `python3`): `asyncio.start_server` на
|
||||
`127.0.0.1:PORT`, `refresher(None)`, `usage_poller`, `balance_poller`; без `iterm2`, без
|
||||
`theme_poller`, без регистрации web view. `live=None` → `build_tree` уже судит о сессиях по PID и
|
||||
tmux. Блок `__main__` запускает этот режим при флаге независимо от наличия `iterm2`.
|
||||
- **Регистратор** (запуск iTerm2 из AutoLaunch, без флага): проверяет, отвечает ли порт; если нет —
|
||||
`launchctl kickstart gui/<uid>/<label>`; затем `async_register_web_view_tool` на
|
||||
`http://127.0.0.1:PORT/` и остаётся жить (`run_forever`), ничего больше не делая.
|
||||
- `theme_poller`, `live_sessions`, использование `_app` в `activate`/`open_worktree`,
|
||||
`USE_PROFILE_THEME`, `THEME_VARIANT` и их ключи в `CONFIG_KEYS` удаляются. Старые ключи в чужом
|
||||
`config.json` просто игнорируются (`load_config` берёт только известные ключи).
|
||||
- `activate`/`open_worktree` для целей не из tmux становятся no-op.
|
||||
|
||||
### LaunchAgent
|
||||
- Метка `com.andrey.claude-agents` (совпадает с идентификатором web view).
|
||||
- `ProgramArguments`: абсолютный путь к `python3`, путь к установленному `claude_agents.py`, `--headless`.
|
||||
- `RunAtLoad=true`, `KeepAlive=true`, `ThrottleInterval` по умолчанию.
|
||||
- stdout/stderr — в `~/Library/Logs/claude-agents/panel.log`.
|
||||
|
||||
### install.sh / uninstall.sh
|
||||
- install: как раньше хук и `settings.json`; копирует `claude_agents.py` в AutoLaunch (регистратор);
|
||||
пишет plist в `~/Library/LaunchAgents/`; останавливает всё, что слушает порт (прежний сервер
|
||||
внутри iTerm2); `launchctl bootout` (если была) + `bootstrap gui/<uid>` + `kickstart -k`; ждёт,
|
||||
пока порт ответит, и сообщает результат; если iTerm2 запущен с включённым API — перезапускает
|
||||
скрипт AutoLaunch (как сейчас через `osascript`).
|
||||
- uninstall: `launchctl bootout`, удаляет plist, остальное как сейчас; `--purge` удаляет и лог службы.
|
||||
|
||||
### Фон на клиенте
|
||||
- В `render_page`: в `<head>` до отрисовки маленький скрипт читает выбор из `localStorage`
|
||||
(в `try/catch`) и выставляет CSS-переменные `--bg`, `--fg`, `--dim` на `:root` — без мелькания.
|
||||
- Производные цвета: по относительной яркости фона выбирается светлый или тёмный текст;
|
||||
`--dim` — смесь текста с фоном (как `_mix` на сервере, коэффициент 0.6). Линии дерева и
|
||||
разделители уже считаются от `--fg` через `color-mix`, отдельно не трогаются.
|
||||
- ⚙ — в строке `.foot` блока лимитов. Блок лимитов перерисовывается сервером раз в 15 с через
|
||||
`/limits`, поэтому ⚙ и строка образцов живут вне перерисовываемого HTML (отдельный элемент
|
||||
рядом с `#limits` или восстанавливаются после вставки), чтобы раскрытая строка не схлопывалась.
|
||||
- Образцы: текущий по умолчанию (`#002b36`), нейтральный тёмный (`#1e1e1e`), чёрный (`#000000`),
|
||||
тёмно-фиолетово-серый (`#2b2b3a`), светлый (`#fdf6e3`). «Свой цвет» — `<input type="color">`
|
||||
(на iPad открывает системную палитру). «Сброс» удаляет ключ и возвращает тему сервера.
|
||||
- Тема сервера по умолчанию — `DEFAULT_THEME`, выровненная по нынешнему профилю iTerm2 `Chat`
|
||||
(снято с работающей панели 2026-10-18): `bg #002b36`, `fg #aacace`, `dim #668a91`,
|
||||
`green #859900`, `yellow #b58900`, `red #dc322f`, шрифт `'MesloLGLNF', 'MesloLGLNF-Regular',
|
||||
ui-monospace, monospace`, размер 13. Значения зашиты в код, профиль не читается.
|
||||
- Если web view Toolbelt не сохраняет `localStorage` между перезапусками iTerm2 — принимаем это:
|
||||
после перезапуска в Toolbelt тема по умолчанию (она и есть вид профиля `Chat`). Серверного
|
||||
хранения выбора нет. Проверить поведение в начале реализации и записать результат сюда.
|
||||
|
||||
## Оставлено исполнителю
|
||||
- Точное расположение установленного `claude_agents.py` для службы (та же копия в AutoLaunch или
|
||||
отдельная) — при условии одного исходного файла в репозитории.
|
||||
- Размер и вид ⚙ и образцов в пределах требований спеки (пальцем на iPad, ничего лишнего в
|
||||
свёрнутом виде).
|
||||
- Тесты: pytest по чистым функциям (`settings_hooks`, генерация plist, расчёт производных цветов,
|
||||
если он на сервере) и ручная проверка сценариев спеки, которые завязаны на launchd/iPad.
|
||||
|
||||
## Риски
|
||||
- Сохраняется ли `localStorage` в web view Toolbelt iTerm2 между перезапусками iTerm2 — не проверено.
|
||||
Решено с пользователем: если нет, фон в Toolbelt сбрасывается к теме по умолчанию (вид профиля `Chat`).
|
||||
- Доступ `security` к элементу Keychain `Claude Code-credentials` из процесса launchd может
|
||||
потребовать подтверждения пользователя один раз.
|
||||
- `/usr/bin/python3` без установленных Command Line Tools — заглушка; установщик уже проверяет, что
|
||||
`python3` реально работает, и фиксирует его путь.
|
||||
|
||||
## Открытые вопросы
|
||||
- После перезагрузки Mac без входа на нём (только SSH с iPad) LaunchAgent не стартует, а Keychain
|
||||
заблокирован. Пользователь такого не делал, но не исключает; решение отложено.
|
||||
|
||||
## Decisions made without discussion
|
||||
- 2026-10-18 — Сервер остаётся только на `127.0.0.1`. Обоснование: в панели тексты сообщений
|
||||
сессий; с iPad и так заходят через туннель. Цена ошибки: если понадобится LAN — добавить ключ
|
||||
`bind` в конфиг.
|
||||
- 2026-10-18 — Возможности iTerm2 для сессий вне tmux (имена вкладок, переход во вкладку, `lf` в
|
||||
split iTerm2, `tmux -CC`) убираются целиком, а не только в фоновом режиме. Обоснование: следствие
|
||||
«один сервер на порту» + «не досылать данные из iTerm2»; пользователь держит всё в tmux. Цена
|
||||
ошибки: для сессий вне tmux теряется переход по клику; вернуть можно досылом из регистратора.
|
||||
- 2026-10-18 — Подстраивается только фон, а производные (текст, приглушённый, линии) считаются
|
||||
автоматически; цвета статусов не меняются. Обоснование: пользователь говорил о фоне. Цена
|
||||
ошибки: добавить выбор цвета текста.
|
||||
- 2026-10-18 — Регистратор при неотвечающем порте делает `launchctl kickstart`, а не поднимает свой
|
||||
сервер. Обоснование: один код сервера, нет гонки за порт. Цена ошибки: если launchd-службы нет
|
||||
(не переустановлено), в Toolbelt пустая страница до `install.sh`.
|
||||
- 2026-10-18 — Метка LaunchAgent `com.andrey.claude-agents`, лог в `~/Library/Logs/claude-agents/`.
|
||||
Цена ошибки: переименование при следующей установке.
|
||||
44
openspec/changes/headless-panel/proposal.md
Normal file
44
openspec/changes/headless-panel/proposal.md
Normal file
@ -0,0 +1,44 @@
|
||||
# Proposal
|
||||
|
||||
## Why
|
||||
|
||||
Панель «Claude» сейчас живёт только внутри iTerm2: её HTTP-сервер на `127.0.0.1:8766` поднимает
|
||||
скрипт AutoLaunch, и когда iTerm2 закрыт, страницы нет. Пользователь смотрит панель с iPad —
|
||||
Termius держит SSH-туннель к `127.0.0.1:8766` на Mac, страница открыта в Safari, а сами сессии
|
||||
Claude Code крутятся в tmux, которому iTerm2 не нужен. Панель должна быть доступна, пока Mac
|
||||
включён и пользователь вошёл в систему, независимо от iTerm2. Заодно тема по умолчанию
|
||||
(Solarized dark) в Safari на iPad «мозолит глаза», и её нужно менять прямо на странице.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Новый фоновый режим панели (`--headless`): HTTP-сервер, дерево сессий, лимиты и баланс без
|
||||
iTerm2. Запускается LaunchAgent'ом при входе в систему, перезапускается при падении.
|
||||
- Порт 8766 всегда занимает только фоновый сервер. Скрипт AutoLaunch в iTerm2 больше не поднимает
|
||||
сервер, а только регистрирует web view «Claude» в Toolbelt на тот же адрес.
|
||||
- **BREAKING**: подстройка цветов и шрифта под профиль iTerm2 убрана; ключи `use_profile_theme`
|
||||
и `theme_variant` в `config.json` больше ничего не делают.
|
||||
- **BREAKING**: возможности, которым нужна живая связь с iTerm2, уходят: названия вкладок iTerm2 для
|
||||
сессий вне tmux, переход во вкладку iTerm2 для сессий вне tmux, переключение панелей `tmux -CC`,
|
||||
открытие `lf` в разделённой панели iTerm2 для сессий вне tmux. Сессии в обычном tmux работают
|
||||
как раньше (имена, переход, `lf` — через tmux).
|
||||
- Новая настройка фона на клиенте: шестерёнка ⚙ в нижней строке панели раскрывает образцы фона,
|
||||
«свой цвет» и «сброс». Выбор хранится на устройстве (браузере/web view), текст подстраивается.
|
||||
- `install.sh` ставит и запускает LaunchAgent, `uninstall.sh` его останавливает и удаляет.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `panel-service`: где и как работает сервер панели — фоновая служба без iTerm2, единственный
|
||||
владелец порта, регистрация в Toolbelt, установка/удаление.
|
||||
- `panel-appearance`: как пользователь меняет фон панели на своём устройстве.
|
||||
|
||||
### Modified Capabilities
|
||||
<!-- openspec/specs/ пуст — изменяемых спек нет -->
|
||||
|
||||
## Impact
|
||||
|
||||
- `files/claude_agents.py`: точка входа с двумя режимами (фоновый сервер / регистратор Toolbelt),
|
||||
удаление `theme_poller` и чтения профиля, клиентский JS/CSS для фона в `render_page`.
|
||||
- `install.sh`, `uninstall.sh`: LaunchAgent (`~/Library/LaunchAgents/`), лог службы.
|
||||
- `files/config.example.json`, README.md: убрать ключи темы, описать фоновую службу и шестерёнку.
|
||||
- Внешние зависимости не добавляются (только стандартная библиотека Python, `launchctl`).
|
||||
@ -0,0 +1,65 @@
|
||||
# Spec Delta
|
||||
|
||||
## Purpose
|
||||
|
||||
Позволяет пользователю выбрать фон панели прямо на странице, отдельно на каждом устройстве
|
||||
(Safari на iPad, Toolbelt на Mac), чтобы панель не резала глаза рядом с его терминалом.
|
||||
|
||||
## ADDED 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** панель показывает тему по умолчанию, и после перезагрузки она остаётся по умолчанию
|
||||
111
openspec/changes/headless-panel/specs/panel-service/spec.md
Normal file
111
openspec/changes/headless-panel/specs/panel-service/spec.md
Normal file
@ -0,0 +1,111 @@
|
||||
# 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` не поддерживается для перехода.
|
||||
Loading…
x
Reference in New Issue
Block a user