64 lines
6.0 KiB
Markdown
64 lines
6.0 KiB
Markdown
# cc-agents-iterm-plugin
|
||
|
||
## Что это
|
||
Панель «Claude» для iTerm2 Toolbelt. Сверху — дерево активных сессий Claude Code и их субагентов
|
||
(название, модель, размер контекста, worktree, статус), снизу — лимиты подписки (5 ч, неделя,
|
||
разбивка по продуктам) и баланс extra usage. Для одного пользователя на его Mac: видеть, что
|
||
делают все запущенные `claude` и сколько осталось лимитов, и в один клик переходить в нужную
|
||
вкладку или панель tmux.
|
||
|
||
## Стек и ограничения
|
||
- Python 3.8+, только стандартная библиотека; модуль `iterm2` предоставляет сам iTerm2
|
||
(скрипт AutoLaunch). Без зависимостей из pip — пользователь ставит панель `./install.sh`.
|
||
- Хук — POSIX `sh` + `jq`. Хук никогда не мешает Claude Code: ничего не выводит, всегда `exit 0`.
|
||
- Только macOS + iTerm2 с включённым Python API. Токен OAuth берётся из Keychain
|
||
(`Claude Code-credentials`) или `~/.claude/.credentials.json`.
|
||
- Установщик не трогает чужие хуки и настройки: правит `~/.claude/settings.json` только через
|
||
`settings_hooks.py` (маркер `agents_panel_hook`), перед заменой кладёт копии в
|
||
`~/.claude-panel-backup/<дата>/`. Повторный запуск `install.sh` идемпотентен.
|
||
|
||
## Архитектура
|
||
- `files/agents_panel_hook.sh` — хук Claude Code на SessionStart/End, UserPromptSubmit, Stop,
|
||
Notification, SubagentStart/Stop, PostModelSwitch, PreToolUse(Agent|Task). Дописывает событие
|
||
в `~/.cache/claude-agents/<session_id>.jsonl` вместе с PID процесса `claude`,
|
||
`ITERM_SESSION_ID` или сокетом/панелью tmux.
|
||
- `files/claude_agents.py` — скрипт iTerm2 AutoLaunch, один файл:
|
||
- `refresher` раз в `poll_sec` перечитывает jsonl (`load_sessions` → `replay`), сверяет с живыми
|
||
сессиями iTerm2, процессами (`ps`) и панелями tmux, дочитывает из транскриптов модель и токены,
|
||
из git — worktree; собирает `state["tree"]` (`build_tree`).
|
||
- `usage_poller` / `balance_poller` ходят в `api.anthropic.com/api/oauth/usage` и
|
||
`.../prepaid/credits` (запасной путь — claude.ai с `sessionKey` из Keychain).
|
||
- HTTP-сервер на `127.0.0.1:8766` (`handle`) отдаёт страницу, которую iTerm2 показывает как web view
|
||
tool: `/`, `/fragment` (дерево), `/limits`, `/message` (последние сообщения), `/activate`,
|
||
`/open-wt`, `/raw` (отладка).
|
||
- `theme_poller` подстраивает цвета под профиль iTerm2.
|
||
- `files/settings_hooks.py` — добавляет/убирает хуки панели в `settings.json` (`add` / `remove`).
|
||
- `files/config.example.json` — все ключи настроек; рабочий файл `~/.config/claude-agents/config.json`
|
||
перечитывается на лету, кроме `port`.
|
||
- `install.sh` / `uninstall.sh [--purge]` — раскладывают файлы по местам (таблица в README.md).
|
||
|
||
## Команды
|
||
- `./install.sh` — установить или обновить у себя; затем Toolbelt → Claude и перезапуск сессий `claude`.
|
||
- `./uninstall.sh` — удалить (`--purge` — вместе с настройками и логами).
|
||
- `python3 -m py_compile files/*.py && sh -n files/agents_panel_hook.sh && bash -n install.sh && bash -n uninstall.sh` —
|
||
синтаксическая проверка; сборки нет.
|
||
- `curl -s http://127.0.0.1:8766/raw` — что видит запущенная панель: логи хука, причины скрытия
|
||
сессий, ошибки лимитов и баланса.
|
||
|
||
## Тесты
|
||
- Автотестов пока нет. `claude_agents.py` импортируется без iTerm2 (`iterm2 = None`), так что чистые
|
||
функции (`replay`, `build_tree`, `parse_limits`, `parse_balance`, `session_name`, `settings_hooks.add/remove`)
|
||
можно покрывать pytest без iTerm2. Сеть, Keychain, `ps` и tmux в тестах мокаются.
|
||
- Фикстуры — образцы jsonl хука и ответов API в `tests/fixtures/`.
|
||
|
||
## Где лежит код
|
||
- Код — в `files/`; хук require-plan защищает его через `.claude/code-paths`. `install.sh` и
|
||
`uninstall.sh` в корне хуком не покрыты (он умеет только каталоги).
|
||
|
||
## OpenSpec и superpowers
|
||
- Вход в любую задачу — superpowers:brainstorming. Skills openspec-propose и openspec-explore сами по себе не запускать.
|
||
- Когда brainstorming классифицировал задачу как architectural, структуру change создать через `openspec new change <id>` (или `/opsx:propose <id>`), а содержимое proposal.md, specs/ и design.md написать по итогам brainstorming. tasks.md из OpenSpec не заполнять — задачи живут в плане superpowers.
|
||
- `/opsx:apply` не использовать: исполнение идёт через writing-plans и SDD/executing-plans.
|
||
- `openspec archive <id>` — после merge PR, как часть чеклиста закрытия.
|
||
- Хук require-plan защищает любой каталог `src/` на любой глубине. Если код лежит иначе — перечислить каталоги (префиксы от корня, по одному в строке) в `.claude/code-paths`.
|