Командная строка как часть продукта
Каждая кнопка, клавиша и пункт меню запускает действие по имени, и те же имена доступны из оболочки. Что показывает окно, читается как JSON, а что в нём меняется, приходит потоком, за которым может следить скрипт.
Ни сокета, ни порта, ни службы
Команда это файл, записанный в папку настроек, и окно видит изменение. Ничего не слушает сетевой адрес, и ничего не работает само по себе в фоне. Поэтому проверки интерфейса ведут всю программу через эту командную строку: то, что она делает для скрипта, делают кнопки для руки.
Командная строка ставится вместе с программой в ~/.config/vobuda/bin/vobuda. Сделайте на неё ссылку в /usr/local/bin или вызывайте по пути. VOBUDA_CONFIG направляет её в другую папку настроек, и тогда каждая команда действует только на окно с этой папкой: так проверка ведёт свой экземпляр, не трогая рабочее окно. vobuda mcp отдаёт агенту те же команды как инструменты MCP.
Читать окно
Четыре команды, которые только смотрят. Окно они не меняют.
| Команда | Что даёт | Пример |
|---|---|---|
vobuda state | Окно как JSON: вкладки, дерево блоков, что работает в каждом блоке, его папка, слушаемые порты, отметки приглашений, копия проекта, в которой он стоит, открытая панель, тема, числа агентов. По блоку: id, view, running, agent, tree, cwd, ports, prompts, copy. По вкладке: id, title, signal | vobuda state | jq '.tabs[0].blocks[] | {id, running, ports, cwd}' |
vobuda events [--since N] [--no-follow] | Что меняется, по одной JSON-строке, по мере того как происходит. В каждой строке есть seq (число, которое только растёт), at (миллисекунды эпохи), window и kind, затем поля этого вида. --since N сначала печатает всё, что пришло после строки N, потом следит дальше; --no-follow останавливается после этой предыстории | vobuda events | jq -c 'select(.kind=="signal" and .signal=="waiting")' |
vobuda log [lines] | Журнал ядра и интерфейса, последние строки (по умолчанию 40). Ошибки веб-вида попадают сюда же | vobuda log 100 |
vobuda where | Путь к папке настроек | vobuda where |
Журнал событий это events.jsonl рядом с настройками, он обрезается с начала, когда перерастает два мегабайта. Следящий смотрит за путём, поэтому обрезка ему ничего не стоит.
Поток событий
То, чего скрипт может ждать без опроса и без угаданного числа секунд.
| Вид | Поля | Когда |
|---|---|---|
tab.open, tab.close | tab, title | Вкладка появилась или исчезла |
block.open, block.close | block, tab, view, by | Блок появился или исчез. by говорит, что его закрыло: крестик, действие (клавиша или командная строка), вопрос «ещё работает», завершившийся vobuda run, переехавшая страница, своя вкладка, восстановление или неизвестно что |
signal | tab, title, signal | Вкладку отметили как готовую или ждущую |
block.start, block.finish | block, tab, program, after | Программа запустилась или закончилась в блоке |
block.cwd | block, cwd | Папка блока сменилась |
ports | block, ports | Слушаемые порты блока изменились |
command.exit | block, code | Команда закончилась, прочитано по отметкам приглашения оболочки |
run.exit | block, run, code | Закончился vobuda run |
guard.refused | tool, kind, what, cwd | Ограда остановила агента: удаление, запись вне проекта или ключ |
copy.open, copy.removed, copy.kept | path, branch, root, ahead, dirty | Копия проекта сделана, снята или оставлена, потому что в ней есть работа |
review.accept, review.put-back, review.tell, review.commit, review.merge, review.pr | path, hunk, root, hash, branch, url | Решения проверки правок |
snapshot.taken, snapshot.restored | cwd, prompt, at, files | Снимок проекта и снимок, возвращённый на место |
project.publish, project.github, project.packed | folder, path | Проект передан дальше |
Управлять окном
За клавишами, кнопками, меню, Cmd+K и этой командной строкой стоит один словарь действий. Неизвестное действие отклоняется, а не игнорируется, и отказ виден в журнале.
| Команда | Что делает | Пример |
|---|---|---|
vobuda do <action> | Любое действие по имени. Аргумент идёт после двоеточия. Полный список это правая часть файла сочетаний клавиш плюс список команд (Cmd+K в окне) | vobuda do "tab.new:/path/to/project" |
vobuda send <text> | Печатает в активный блок. Завершающий \n это клавиша возврата; раскрываются только \n и \t, остальное дело оболочки | vobuda send 'npm test\n' |
vobuda run <command> | Запускает команду в отдельном блоке рядом с активным, ждёт и завершается её кодом. В заголовке сначала «running», потом код выхода; блок с успехом закрывается через мгновение, если его не оставили, блок с ошибкой остаётся. Для команды, которая должна идти там, где человек может за ней следить | vobuda run cargo test && echo green |
vobuda button <id> | Нажимает кнопку дока по её id, как мышью | vobuda button files |
vobuda ui | Всё, что есть на экране и до чего дотянулась бы рука, как JSON: id, одинаковый на любом языке, имя, вид (button, field, toggle, tab, row, item, link), состояние, почему кнопка серая, если серая, блок, в котором она стоит, содержимое, если это поле. Элемента за закрытым меню в списке нет, потому что рука его тоже не нажмёт | vobuda ui | jq '.[] | select(.kind == "row") | .name' |
vobuda press <id|name> [--block N] | Вызывает собственный клик элемента, то же событие, что делает рука. Если на имя откликаются два элемента, нажатия не будет: отказ перечислит оба по id и вернёт ненулевой код; --block решает вопрос. Ответ говорит, что появилось, что ушло и что включилось или выключилось. Указатель мыши это не двигает | vobuda press block.close --block 2 |
vobuda type <name> <text>, vobuda key <name> <key> | Текст в именованное поле или одна клавиша: Enter, Escape, Tab, стрелки, Backspace, буква, с модификаторами впереди (shift+Enter, cmd+Left, ctrl+c). Оба идут теми событиями, которые слушает интерфейс, поэтому поиск фильтрует, а переименование сохраняется | vobuda type search quiet |
vobuda click <name> <col,row> | Клик по одной ячейке терминала, счёт от нуля с левого верхнего угла: нажатие и отпускание, как делает рука | vobuda click "Terminal input" 8,3 |
vobuda shot [--block] [--element <name>] | Снимок всего окна и путь к нему. --block берёт блок, в котором клавиатура, --element один элемент по имени. Каждый снимок это отдельный файл с названием по времени | vobuda shot |
vobuda wait <key> <value>, vobuda wait --control <name> | Ждёт, пока окно не скажет своё, вместо сна. Ключ это путь в vobuda state. Ожидание, которое вышло по времени, говорит, чем ключ остался, и возвращает ненулевой код. Тридцать секунд, если --timeout не говорит иного | vobuda wait agentBusy false |
vobuda signal done|waiting|clear | Отмечает активную вкладку: значок, звук, уведомление. Это то, что вызывают хуки агентов; любая программа в блоке может сделать то же через printf '\e]9;done\a' | vobuda signal waiting |
vobuda workspace list|open <name>|new|delete <name> | Рабочее пространство это отдельное окно проекта со своими вкладками | vobuda workspace open shop |
Настройки и остальной набор
Каждая настройка это файл в папке настроек, и окно следует за файлом. Точечная правка записывает значение своего типа и оставляет остальной файл целым.
| Команда | Что делает | Пример |
|---|---|---|
vobuda set <file> <key> <value> | Вложенный ключ в файле настроек, с типом | vobuda set settings.json signals.quiet.enabled true |
vobuda theme, vobuda skin, vobuda dock | Тема по имени, оболочка монитора, сторона дока | vobuda theme dark |
vobuda edit <file> | Файл в вашем $EDITOR | vobuda edit settings.json |
vobuda backup [file.zip], vobuda restore <file.zip> | Вся папка настроек одним файлом и обратно | vobuda backup |
vobuda pack [folder] | Проект одним архивом для разработчика, рядом с проектом, с описанием сверху: что это, как запускается, что менялось последним, что ключи оставлены за бортом. node_modules, .git, сборки и любые .env в него не входят. Печатает путь к архиву | vobuda pack |
Для хуков агентов
Это то, что окно записывает в настройки Claude Code и Codex. Человек или скрипт тоже может их вызвать.
| Команда | Для чего |
|---|---|
vobuda ask | Где открыть эту страницу? Здесь, в новой вкладке, в своём окне или в браузере |
vobuda note <kind> | Заметки рядом с числами агента: сжатие, сжато, помощник включён, помощник выключен, папка, правка, сбой |
vobuda brief | Памятка окна для агента в начале сессии |
vobuda snapshot | Папка проекта как есть, перед ходом; ключ в запросе остановлен |
vobuda guard | Перед запуском инструмента: ограда, «никогда не удалять», ключи, последний инструмент записан |
Что каждый из них записывает, куда и как это убрать, написано на странице о том, что vobuda делает с вашей машиной.
Два примера
Первый это скрипт, который открывает проект так, как нравится человеку, и потом слушает. Второй это то, что делает агент из своего блока.
#!/bin/shvobuda do "tab.new:$HOME/work/shop"vobuda do block.splitvobuda do agent.claudevobuda do block.prevvobuda send 'npm run dev\n'# а в другом скрипте сказать вслух, когда агент ждётvobuda events | jq -c 'select(.kind=="signal" and .signal=="waiting")' | while read -r line; do say "the agent is waiting"; done # прочитать окноvobuda state | jq '.tabs[0].blocks[] | {id, running, ports}'# запустить команду там, где человек видит, и получить её код выходаvobuda run cargo test# ждать окно, а не спатьvobuda wait agentBusy false# изменить настройку, записав файлvobuda set settings.json monitor.every 5 Чем это не является
Не протокол с версией: интерфейс это файлы, и это те же файлы, что правит человек. Не способ говорить с выбранным окном среди нескольких: адресовать окно дело рабочего пространства. Не способ запустить программу или присмотреть за ней: команда это записка, оставленная работающему окну.
Попробуйте из своей оболочки
Командная строка идёт вместе с программой, а собственная папка настроек это одна переменная.
curl -fsSL https://vobuda.com/install.sh | sh