Зачем NeuroSquad: агенты на холсте, а не в ряду вкладок
Три недели от первого коммита до первой публичной сборки. Какую задачу она решает — и три решения, на которых держится всё остальное в приложении.
Сегодня вышел NeuroSquad 0.1.91 — установщик для Windows, десять агентских CLI и холст. Первый коммит был 3 сентября, и по ходу дела агенты, запущенные в карточках самого NeuroSquad, помогали его строить. Эта запись — о том, почему он устроен именно так.
Проблема: ряд вкладок, за которыми надо присматривать
Агентские CLI стали настолько хороши, что узким местом один из них уже не является. Вы запускаете второй на тесты, третий на документацию, может быть, четвёртый — в другом репозитории. И дальше работа превращается в наблюдение: какая вкладка закончила, какая десять минут висит на вопросе вроде «можно выполнить эту команду?», какая всё ещё работает.
Вкладки для этого не годятся. Они прячут всё, кроме той, что перед глазами, ничего не говорят о состоянии и ничего не знают друг о друге. Агент в третьей вкладке не может заглянуть в браузер в пятой, даже когда ему нужно именно это.
Поэтому NeuroSquad делает три ставки. Каждый агент — это карточка с настоящим терминалом на холсте, который видно целиком. Приложение само сообщает, когда агент закончил ход или ждёт вас, — больше не нужно проверять вручную. А стрелка между двумя карточками даёт агенту пользоваться тем, на что она указывает.
Карточка — это настоящий терминал, и он не должен умирать
Карточка — не окно чата, которое притворяется агентом. Это тот самый CLI, которым вы уже пользуетесь, — Claude Code, Codex CLI, OpenCode, Qwen Code и ещё шесть, — запущенный в настоящем псевдотерминале, со своим интерфейсом, своими клавишами и своими причудами. Если CLI обновится завтра, завтра же обновится и карточка.
Этот выбор задал первый инвариант всей кодовой базы: компонент терминала нельзя размонтировать, пока его агент жив, потому что размонтирование убивает процесс. Звучит очевидно. Оказалось, что это определяет почти каждую функцию холста:
- Переключение воркспейса не заменяет холст. Каждый открытый за сессию воркспейс держит свой холст смонтированным, а неактивные просто скрыты.
- Приближение к группе карточек — это полёт камеры к рамке группы, а не фильтр: фильтр размонтировал бы карточки за её пределами.
- Разворот карточки на весь экран — это вьюпорт 1:1 плюс сохранённая геометрия, а не другой компонент.
- Библиотека холста удаляет выделенную ноду по клавише Delete. Здесь это означало бы убить сессию одним нажатием, поэтому библиотеке удалять ноды не разрешено вовсе: наш собственный обработчик собирает выделение и один раз спрашивает в диалоге.
Под той же ставкой лежит много сантехники Windows. CLI резолвится в абсолютный путь штатным поиском системы, потому что десктопное приложение видит не тот PATH, что ваш терминал. Пути передаются с прямыми слэшами, потому что библиотека псевдотерминала портит обратные, — кроме cmd.exe, который читает C:/… как набор ключей. Переменные, которые родительский агент оставляет в окружении, вычищаются перед запуском дочернего, иначе тот молча перестаёт сохранять транскрипт. Ничего из этого не видно, и всё это пришлось находить, запуская настоящие программы.
«Закончил» и «ждёт вас» — разные события
Весь смысл холста в том, что вы отворачиваетесь. Значит, приложение должно знать, когда вас позвать, — и причины бывают две, очень разные. Закончил — агент завершил ход, и ответ можно прочитать когда угодно. Ждёт вас — агент заблокирован прямо сейчас, пока вы что-то не одобрите.
Первая версия их не различала. Она следила за терминалом: если заголовок окна не менялся 1,2 секунды, а вывод молчал 2,5 секунды, ход считался законченным. Для «закончил» догадка неплохая — и ровно та же тишина, что у агента, который ждёт ответа на запрос разрешения.
Решение — спросить самого агента. У Claude Code есть хуки жизненного цикла, поэтому каждая карточка запускает его с небольшим файлом настроек поверх ваших: когда вы отправляете промпт, он сообщает работает, когда поднимает уведомление — ждёт вас, когда останавливается — закончил. Каждый хук — одна строка curl к серверу, который приложение держит на loopback-интерфейсе, а токен карточки лежит в самом адресе, а не в заголовке, — так команда переживает любую оболочку.
Агенты, которые сообщают о себе через хуки, выключают для себя старый угадывающий детектор, иначе пришло бы два оповещения, и угаданное «закончил» перезаписало бы настоящее «ждёт вас». CLI без хуков по-прежнему работают на эвристике. Клик по уведомлению переносит камеру холста к карточке, и та мигает зелёным достаточно долго, чтобы ещё мигать, когда камера долетит.
Стрелки — это инструменты
О третьей ставке спрашивают чаще всего. NeuroSquad держит собственный MCP-сервер на 127.0.0.1, и каждый агент, который умеет MCP, получает на нём сессию. Что в эту сессию входит, решают стрелки на холсте.
- Стрелка к карточке браузера даёт агенту инструменты
browser_*: настоящий Chrome, видимый в карточке, в котором агент кликает и печатает у вас на глазах. - Стрелка к карточке терминала даёт
terminal_*: выполнить команду именно в этой оболочке и прочитать её экран. - Стрелка к заметке даёт
note_*, к списку задач —todo_*. - Стрелка к другому агенту даёт
agent_*, и у этой стрелки есть направление: от ведущего к помощнику. Помощник не может отправить работу обратно наверх.
Стрелка и есть разрешение. Нет стрелки — нет инструмента, и поэтому холст честно показывает, до чего может дотянуться каждый агент. Каждый вызов рисуется на своей стрелке в момент вызова: видно, как ведущий передаёт задачу помощнику, и не нужно читать об этом в логе.
Ведущий агент раскладывает работу на доске и передаёт каждую часть по стрелке; каждый помощник — Codex, Qwen, OpenCode — сам берёт свою задачу и переносит её на ревью, когда закончит.
Локально по умолчанию
Ни аккаунта, ни нашего сервера посередине. Воркспейсы, карточки и стрелки — JSON-файлы в папке данных приложения. Диктовка распознаётся на вашем компьютере — Parakeet или Whisper. Раздел расхода читает токены и стоимость из логов самих агентов, а не через прокси перед ними. Удаление карточки никогда не трогает папку проекта.
В выпуске есть и то, что в эту запись не поместилось: удалённый доступ, который запускает всё приложение в браузере телефона, изолированные git worktree для каждого агента и тормоз бюджета, который прерывает всех агентов воркспейса, когда достигнут лимит трат, — через Ctrl+C, а не kill, так что ни одна сессия не теряется.
Что дальше
Первая сборка — это установщик на 550 МБ, и большая его часть — модель распознавания речи, которую загрузят только те, кто диктует. Это первое, что нужно исправить. Дальше — установщик, который прямо говорит, что ему мешает, и обновления, которые ставятся сами.
Полный список того, что вошло в 0.1.91, — в журнале изменений.

