bigarrow — ИИ-агент рисует стрелки на экране Mac, чтобы показать, куда нажать
📂 Исходный код на GitHubbigarrow — консольная утилита для macOS, которая рисует стрелку и подпись поверх любого окна. Клики проходят насквозь, фокус клавиатуры не перехватывается, стрелка исчезает сама. Внутри нет ИИ. Лицензия MIT.
ИИ-агент умеет переписать монорепозиторий и объяснить теорию категорий. Но когда он упирается в шаг, который обязан сделать человек, агент пишет в терминал «нажмите Allow в диалоге». Проблема в том, что терминал в этот момент вы не смотрите.
Утилита bigarrow решает именно эту задачу. Она рисует поверх любого окна большую стрелку с подписью и говорит, куда нажать. Клики проходят насквозь, фокус клавиатуры остаётся на месте, а стрелка исчезает сама. Внутри утилиты нет ИИ — это просто стрелка. Проект открыт под лицензией MIT.
Что внутри
Один бинарный файл на Swift. Без демона, без иконки в меню, без аккаунта, без телеметрии. Одно прозрачное окно поверх всего — на каждом дисплее и в каждом Space. Само рисование стрелки не требует никаких разрешений macOS.
Разрешения нужны только для того, чтобы найти цель. Инструмент умеет показывать и список разрешений, и список доступных дисплеев — команда bigarrow doctor.
В комплект входит навык в формате Agent Skills для Claude Code и для Codex. Навык объясняет агенту, когда стоит показать стрелку, как выбрать цель и что писать в подписи.
Три команды, которые нужны агенту
# найти кнопку по подписи
bigarrow point --element "Allow" --app "System Settings" --text "Franz, click Allow"
# указать в точку на экране
bigarrow point --at 760,500 --text "Franz, click HERE"
# показать окно и остановить стрелку вручную
bigarrow start --window "Safari:Inbox" --text "This window" && bigarrow stop
Любая команда принимает флаг --json. Коды возврата простые: 0 — всё в порядке, 2 — ошибка во входных данных, 3 — цель не найдена, 4 — не хватает разрешения.
Как агент находит нужное место
Цель выбирается одним из способов:
| Что известно | Как указать |
|---|---|
| Подпись элемента в обычном или Electron-приложении | --element "Allow" --app "System Settings" |
| Приложение или одно из его окон | --window "Safari" или --window "Safari:Inbox" |
| Место внутри вкладки Chrome | --rect x,y,w,h --app "Google Chrome:<название вкладки>" |
| Место на скриншоте | --at X,Y --app "<приложение>" |
Координаты считаются в логических точках от левого верхнего угла экрана — так их отдают Accessibility и Peekaboo. Флаг --display N делает координаты относительными одного дисплея. Отрицательные значения тоже работают.
Ключевой момент: --app сначала выводит нужное приложение, окно или вкладку на передний план. Стрелка, которая указывает на окно, скрытое за терминалом, бесполезна. Если поверх цели позже окажется другое приложение, стрелка спрячется и вернётся, когда цель снова станет видимой. Отключить это поведение можно флагом --no-raise.
Команда bigarrow elements --app X показывает, по каким подписям вообще можно искать. Команда с --dry-run --json отвечает на вопрос «куда бы указывала стрелка», ничего не рисуя. Это удобно, когда нужно проверить, бьёт ли Accessibility по нужным координатам.
Стрелка убирается сама
Главная неприятная черта подобных инструментов — их приходится убирать руками. Здесь это не так:
| Причина | Что происходит |
|---|---|
| Время истекло | --duration 10 (у point 8 секунд, у start 300 секунд, 0 — без ограничения) |
| Агент закончил работу | стрелка исчезает вместе с процессом агента (берётся из CLAUDE_PID или BIGARROW_OWNER_PID) |
| Вы ответили | bigarrow stop --hook, подключённый как хук UserPromptSubmit в Claude Code, убирает все стрелки этой сессии |
| Вы нажали | --close-button добавляет крестик в подпись (включается по запросу) |
| Вы кликнули по самой стрелке | клик по подписи или по стержню убирает стрелку; под курсором она приглушается |
Разрешения macOS
Команда doctor называет приложение, которому нужно выдать доступ, и нужную панель настроек. Если разрешения нет, утилита завершается с кодом 4 и прямо говорит, что открыть.
| Что вы используете | Нужное разрешение |
|---|---|
--at, --rect, --mouse, --window App, --peekaboo, --app App |
не нужно |
--element, elements, --until-click, --app App:заголовок |
Accessibility |
--window App:заголовок |
запись экрана, плюс Accessibility для вывода окна вперёд (не нужен с --no-raise) |
Важная деталь: macOS выдаёт разрешения тому приложению, которое запустило bigarrow. Это Terminal, iTerm2, Ghostty, VS Code или Claude, а не сам bigarrow. Включать доступ нужно именно там.
Внутри веб-страниц в Chrome поиск по подписи работает только с дополнительным ключом --force-renderer-accessibility или включённым VoiceOver: Chrome игнорирует обычный запрос (проверено в октябре 2026). Панель инструментов самого Chrome работает всегда. В приложениях на Electron всё работает без оговорок.
Поверх окон, но без фокуса
На macOS «быть сверху» и «быть в фокусе» — разные вещи. Стрелка живёт на уровне заставки: она выше окон, диалогов и полноэкранных приложений, но никогда не становится активным окном. Поэтому она не перехватывает то, что вы печатаете.
Это была самая трудная ошибка в проекте. Вызов NSApplication.run() незаметно активирует процесс, даже если у него нет терминала. Утилита качает события сама, а тесты проверяют, что самое переднее приложение не меняется.
Клик проходит насквозь везде, кроме подписи и стержня стрелки. Клик по самой цели или рядом с её остриём уходит приложению напрямую и не забирает фокус. Поддерживаются несколько мониторов (включая отрицательные координаты), полноэкранные приложения, Stage Manager и Spaces. Если монитор отключили, пока на нём была стрелка, стрелка вежливо исчезает. Пульсирующая стрелка ест 1,4 % CPU на CI-машине — работу делает Core Animation на стороне рендерера.
Подпись, кнопка копирования и голос
Внешний вид задаётся флагами:
--shape bend|straight|zigzag|spiral— зигзаг для срочного, спираль обходит подпись кругом, чтобы её невозможно было не заметить;--style arrow|ring|box— кольцо и рамка рисуются контуром, поэтому цель остаётся видна;--size S|M|Lи--corners round|sharp;--color red|orange|yellow|green|teal|blue|purple|pink|black|white|#RRGGBB;--border shadow|white-black|blackи отдельные--border-color,--text-color.
Заглушка {{значение}} в подписи превращается в кнопку «скопировать». Нажатие копирует значение в буфер обмена, стрелка остаётся на месте. Это удобный способ передать человеку команду, которую агент выполнять не должен.
Флаг --say читает подпись вслух — Mac буквально окликает вас, если вы отошли от стола. Флаг --follow двигает стрелку вместе с окном или элементом, --until-click убирает её после клика по цели, а --png рисует результат прямо в файл — пригодится для документации и демонстраций.
Сколько стоит навык для агента: 182 токена — это описание, его агент видит всегда. Инструкции на 1528 токенов подгружаются только тогда, когда агент решил показать стрелку. Ещё 1118 токенов с идентификаторами панелей и флагами внешнего вида нужны совсем редко.
Навык для агента
Навык лежит в skill/big-arrow, подробности — в reference.md. Он учит агенту нескольким вещам. Открыть нужную страницу или панель агент должен сам, а человеку показать одну кнопку, а не водить его по меню. Подпись — полное предложение с названием действия, а не слово «здесь». Если человек может отойти, нужно добавить --say. Нажали на кнопку — сразу bigarrow stop.
Установка
brew install franzenzenhofer/tap/bigarrow
bigarrow install-skill # учит Claude Code (~/.claude/skills) и Codex (~/.agents/skills)
Сборка из исходников: swift build -c release — нужен Xcode 16+ и macOS 14+. Готовый бинарный файл лежит в .build/release/bigarrow. Сам бинарник — чистый Swift, каталог scripts/ только снимает скриншоты и гоняет тесты.
Чтобы хук работал, добавьте в ~/.claude/settings.json:
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{ "type": "command", "command": "bigarrow stop --hook" }
]
}
]
}
}
Как это проверено
- 104 автоматических теста: геометрия, размещение, стыки, эталонное изображение, кнопки копирования, записи window server, заготовки Accessibility и Peekaboo, живой window server (клик насквозь, фокус не двигается, тайминги остановки). CI работает на macOS 15, проект проверен на macOS 26 и 27.
- 18 проверок поведения на чистом раннере, описанных в visual.yml: клик по крестику, кнопка копирования,
--until-click,--follow, вывод окна вперёд и--no-raise, прятанье при перекрытии, выбор вкладки Chrome, выход владельца,stop --hook,--say, полный экран, Stage Manager, Spaces, второй монитор и два монитора, отключение монитора посреди работы, нагрузка на CPU. - Свежий агент, которому дали только навык и задачу «покажи Францу, где в Chrome кнопка Reload», нашёл её по подписи и собрал правильную команду. Заодно он нашёл ошибку, которая теперь стала тестом. Расшифровка сеанса лежит в репозитории.
Честные ограничения
Утилита не нажимает кнопки, не печатает текст и не делает скриншоты. Она только указывает — и это сделано намеренно.
Разработчики отдельно спрашивают себя, не сможет ли агент обмануть человека, например закрыв кнопку «Отклонить». Ответ: агент, который умеет выполнять команды в терминале, и так способен на большее, а bigarrow не даёт ему ничего нового. Тем не менее каждое из этих правил закреплено тестом: рамки и кольца рисуются контуром, подпись не перекрывает цель, клик по подписи или стержню убирает стрелку, любая стрелка исчезает сама. Навык требует писать в подписи, что именно сделает клик.
Приложения для аннотаций экрана не подходят: они рассчитаны на человека, который рисует мышью. Здесь сценарий другой — программа указывает на объект из командной строки и возвращает коды возврата. Авторы сначала проверили 26 инструментов, результаты лежат в docs/research.
С чего началось
Идею подсказали два готовых проекта Питера Стайнбергера: Peekaboo и Nameplate. Из них взяли рецепт прозрачного окна поверх всех окон и упаковку навыка. bigarrow умеет читать вывод Peekaboo (see --json) как один из способов найти цель. Иконки копирования и галочки взяты из Feather.
План работ, список решений, результаты проверок и история изменений лежат в репозитории: PLAN.md, каталог решений, матрица проверок, CHANGELOG.md.