Обычный день: пять агентов работают одновременно. Claude Code рефакторит модуль в одной панели. Codex подкручивает тесты в другой. OpenCode в третьей. А где-то в окне tmux номер 4 агент уже пять минут как закончил и ждёт, пока я это замечу.
Вот ровно из-за последнего и появился этот пост.
Тихая проблема CLI-агентов
CLI-агенты расплодились. Claude Code, Codex, OpenCode, Aider, Cursor в режиме терминала, свои питон-скрипты поверх API. Разработчики, которые ещё год назад не открывали терминал, теперь в нём живут. И почти каждый запускает больше одного агента одновременно — задачи параллелятся: здесь сгенерить миграцию, там набросать README, в третьем месте гонять флакающий тест.
Проблема становится очевидной за неделю: ты теряешь контроль.
Какой агент сейчас думает? Какому нужно дать разрешение на выполнение команды? Какой закончил десять минут назад и просто мигает курсором, которого никто не видит? Никакого общего статус-бара для агентов нет. Узнать можно только одним способом — переключиться в каждую панель.
Ренессанс терминала
За последние пару лет произошло тихое: терминал снова стал модным. tmux в частности всё чаще всплывает в сетапах и скриншотах там, где пять лет назад был бы IDE. Часть причины — эстетика. Большая часть — в том, что AI-агенты прилетают в терминал первыми. Claude Code — это CLI. Codex — это CLI. Почти вся агентская UX сейчас — это текст, льющийся в pty.
tmux под это ложится идеально. Одно окно на проект, панели под агента и логи и свободный шелл, сессии для переключения между клиентами. Терминал перестал быть местом исключительно для ls и vim.
Но у tmux нет нативного понятия «в этой панели агент, которому ты нужен».
Что я хотел
Сигнал, который говорит мне без переключения панелей:
- где сейчас работает агент
- где агент ждёт ввода (разрешение, уточнение, блокирующий вопрос)
- где агент закончил и ждёт
И чтобы это было пассивно. Без всплывающих окон, ворующих фокус. Без звуков, срабатывающих посреди встречи. Просто изменение того, на что я и так смотрю: статус-бар, рамка панели, заголовок окна.
Среди готовых плагинов tmux полно часов, CPU, git-веток и погоды. Агентов не трекает никто.
Пришлось написать.
tmux-agent-indicator
accessd/tmux-agent-indicator — плагин для tmux, отслеживающий три состояния на панель: running, needs-input, done. Каждое состояние управляет четырьмя визуальными каналами:
- цвет рамки панели
- фон панели (по умолчанию выключен, чтобы не бил по глазам)
- фон и цвет заголовка окна
- иконка в статус-баре, отдельная на агента (
claude=🤖,codex=🧠,opencode=💻)
Короткое видео того, как это работает. Панель завершается, заголовок окна меняется, рамка обновляется. Если я фокусирую панель, состояние сбрасывается само.
Три кадра-примера:
![]() |
![]() |
![]() |
|---|---|---|
| needs-input: жёлтый заголовок окна | done: красный заголовок окна | done: смена фона панели |
Как состояние вообще попадает внутрь
Плагин ничего не поллит. Переходы состояний идут через хуки:
- Claude Code стреляет хуки
UserPromptSubmit,PermissionRequest,Stop. Инсталлер прописывает их в~/.claude/settings.json. - У Codex есть команда
notifyв~/.codex/config.toml, плагин вешается туда. - OpenCode имеет систему JS-плагинов. Инсталлер кладёт файл в
~/.config/opencode/plugins/. - Любой другой агент может звать
scripts/agent-state.sh --agent <name> --state <state>из своего хука или враппера.
Для агентов, у которых хуков нет вообще, есть фолбэк через детект процессов: плагин смотрит настроенные имена процессов (claude, codex, aider, cursor, opencode) и помечает панель как running, когда они запущены.
Отложенный сброс
Одна маленькая деталь, которой я особенно дорожу. Когда панель переходит в done, визуальное состояние не чистится в момент хука. Оно чистится, когда ты реально посмотришь на панель (переведёшь фокус). Иначе done — это призрак, который мигает и пропадает до того, как ты его заметил, а смысл был ровно в обратном.
Session dots
Если у тебя больше трёх-четырёх сессий, есть опциональный индикатор сессий в статус-баре. Каждая сессия — точка. Текущая заполнена. Сессии, где агент просит внимания, подсвечиваются другим цветом. Четыре сессии, вторая активна, четвёртая требует внимания — выглядит как ○●○●.
Установка
curl -fsSL https://raw.githubusercontent.com/accessd/tmux-agent-indicator/main/install.sh | bash
Инсталлер предложит интерактивный визард по цветам, его можно перезапустить потом. И автоматически пропишет интеграции с Claude, Codex и OpenCode, если они установлены. Если предпочитаешь TPM:
set -g @plugin 'accessd/tmux-agent-indicator'
И добавь #{agent_indicator} (и при желании #{agent_session_dots}) в status-right.
За пределами tmux: agent-indicator
tmux-agent-indicator — плагин исключительно под tmux. Полезен тем, кто живёт в tmux, бесполезен остальным.
Мне хотелось тот же сигнал о состоянии и в других поверхностях: обычные табы терминала, системные уведомления, звуки, push на телефон. Так появился отдельный проект — accessd/agent-indicator.
Та же модель хуков, те же три состояния, четыре бэкенда:
- Terminal. Ставит заголовок таба через OSC 2, тонирует фон через OSC 11, дёргает bell на
needs-input, а на iTerm2 просит внимания в доке черезOSC 1337;RequestAttention. Работает и внутри tmux, и снаружи — последовательности оборачиваются в tmux passthrough, когда надо. Проверено на iTerm2, WezTerm, Kitty, Ghostty, Alacritty, Windows Terminal, GNOME/VTE. - Sound. Играет звуковые алерты на
needs-inputиdone. Использует звуковые паки формата CESP с no-repeat-логикой, чтобы один и тот же динь не звучал подряд. Фолбэк по плееру:afplay,paplay,aplay,play. - Desktop. Системные попапы, отдельно от уровня терминала. На macOS —
terminal-notifierилиosascript. На Linux/WSL —notify-send. - Push. HTTP-уведомления на телефон через ntfy, Pushover или Telegram. Вот этот бэкенд даёт отойти от ноутбука и всё равно знать, что агент ждёт.
Все четыре независимы и тогглятся по отдельности. По умолчанию после установки включён только terminal, остальные выключены. Визард проводит через каждый бэкенд.
Установка:
bash <(curl -fsSL https://raw.githubusercontent.com/accessd/agent-indicator/main/install.sh)
Конфиг живёт в ~/.config/agent-indicator/config.json. У каждого бэкенда свой dotpath и config.py, который читает и пишет значения.
Почему два проекта, а не один
Потому что tmux-специфичные штуки (рамки панелей, стили заголовка окна, анимация Knight Rider, session dots, семантика reset-on-focus) не имеют никакого отношения к звуку и push, а тянуть tmux как зависимость на пользователей без tmux — неправильно. Живёшь в tmux — бери плагин. Нужны звук и push, а стили tmux неинтересны — бери agent-indicator. Нужно и то и то — запускай бок о бок, у них общий хук-контракт.
Итог
Ренессанс терминала — не про ностальгию. Он про то, что самый быстрый и компонуемый интерфейс для нового поколения AI-инструментов оказался тем же, что у нас уже был. tmux даёт структуру, хуки дают расширяемость, агенты дают рычаг.
Не хватало простого: способа понимать, что делают твои агенты, не глядя на каждого из них. Два проекта закрывают этот пробел для меня. Если закроют и для тебя — звёзды приятны, PR-ы ещё приятнее.
Since you scrolled this far, you might as well take a look at some other things I wrote !
- A Flipper Zero That Buzzes When My AI Agents Need Me
- Seeing What Your AI Agents Are Doing in tmux
- Weekend Hack: Combining ChatGPT, Claude & More to Build TaleShade
- Non-Standard Temperature Monitoring in an Apartment
- Нестандартный мониторинг температуры в квартире
- MacOS: tiling window manager
- Деплоим с докером без простоя
- Vim: Путь ниндзя
- How to resize a VirtualBox Virtual Machine hard disk with LVM
- Slack deploy bot
- Все мои компы
- 10 лет рабства
... or some other article from my blog.


