bigarrow:让AI代理在macOS屏幕上画箭头指向需人工点击的元素
Let your AI agents paint big arrows, boxes and text on your screen
开发者发布macOS开源工具bigarrow,让AI代理在屏幕上画出大箭头和文本,指示用户点击权限弹窗、OAuth授权、2FA等无法自动操作的元素。
提供macOS下用屏幕箭头引导AI代理把不可自动点击的界面交还给人工确认的CLI与Skill方案,思路可迁移到其他桌面系统的代理工作流。
big-arrow-on-the-screen(bigarrow):一个小巧的 macOS CLI 和一项 agent 技能。点击穿透,从不抢占焦点,自己消失。MIT 许可。
你的 AI agent 可以重构 monorepo、撰写迁移脚本、讲解 monad,但当它需要你点击一个按钮时,却把"请在对话框中点击 Allow"打印到你没在看的终端里。
bigarrow给它一根手指。
bigarrow point --element "Allow" --app "System Settings" --text "Franz, click Allow"
一支又大又友好的箭头,带着一个牌子,浮在最上层,指向目标,再自己消失。它能点击穿透,从不抢占焦点,在每个显示器和每个 Space 上工作,绘图完全无需任何权限。它就是一个小的 Swift 二进制文件。没有守护进程,没有菜单栏图标,没有账号,没有遥测,而且,我们检查了两遍,里面没有 AI。它就是一支箭头。
这到底用来做什么?
问得好。箭头大约自旧石器时代就已存在。变化在于:软件 agent 现在会在你的 Mac 上做真正的工作,却反复撞上同一面墙——那部分只有人才能做的事。
- "点击允许。"macOS 权限提示、OAuth 授权页面、"打开方式……?"对话框。Agent 找得到按钮,却不能——或不该——替你按下它。现在它可以指向它。
- "轮到你了。"双重认证验证码、CAPTCHA、Passkey、付款确认、签名、法律勾选项——这些是 agent 绝不该自行点击的东西。它指,你定,它继续。
- "是这个窗口,不是那个。"你有 14 个 Chrome 窗口。Agent 知道它指的是哪一个:
--window "Google Chrome:Pull request"。它甚至会选对标签页:--app "Google Chrome:Pull request"。 - "我需要你,而你正在冲咖啡。"
--say会把牌子上的字念出来。你的 Mac 真的会把你叫回桌前。 - 引导式设置和上手流程。一步步带人走过设置面板:
start,等他们操作完,stop,下一步。像产品导览,但没有产品本身。 - 远程协助。"不,是另一个齿轮图标。"与其描述,不如直接指给它看。
- 演示、屏幕录像、文档。录制时突出重点,或者用
--png直接把箭头渲染成 PNG 用于文档。 - 调试坐标。不确定你的辅助功能、截屏或 Peekaboo 坐标是否正确?指过去看看。
--dry-run --json会在不绘制的情况下告诉你会指向哪里。
我们都经历过的场景
使用一个中性的演示对话框搭建场景,并用真正的 bigarrow 在一台干净的 CI runner(BACKDROP_ARGS=--cover scripts/funny-scenes.sh)上录制。对话框是假的,感受是真的。
![]() |
![]() |
--color green |
--shape zigzag --color orange |
![]() |
![]() |
--color purple |
--close-button,因为最终决定权在人 |
![]() |
![]() |
三支 start,一个按钮,零歧义 |
--style box --corners sharp,外加一节 macOS 权限小课 |
![]() |
|
--shape spiral:先绕牌子一圈,再指向按钮 |
它不是什么:它不是给人用的屏幕标注工具,不是点击机器人,也不是截屏工具。它从不点击、输入或截取任何东西。它只指。故意的。
安装
brew install franzenzenhofer/tap/bigarrow
bigarrow install-skill # teaches Claude Code (~/.claude/skills) and Codex (~/.agents/skills)从源码编译:swift build -c release(Xcode 16 或更新版本,macOS 14 或更新版本),二进制文件位于 .build/release/bigarrow。
agent 需要的三条命令
bigarrow point --element "Allow" --app "System Settings" --text "Franz, click Allow" # by label bigarrow point --at 760,500 --text "Franz, click HERE" # by coordinate bigarrow start --window "Safari:Inbox" --text "This window" && bigarrow stop # until stopped
每支箭头都会自己消失。没人需要替一个忘了收尾的 agent 收拾残局:
| 时限 | bigarrow point ... --duration 10(默认 8 秒;start 300 秒;--duration 0 = 无限制) |
| 开始与停止 | bigarrow start ... 立刻返回;bigarrow stop(或 stop --all)移除它 |
| agent 退出 | 箭头会在画出它的 agent 进程退出时消失(CLAUDE_PID,或 BIGARROW_OWNER_PID) |
| 人给出答复 | bigarrow stop --hook 作为 Claude Code 的 UserPromptSubmit 钩子会清除该会话的所有箭头 |
| 人手动关闭 | --close-button 在牌子上放一个可点击的 X(需主动开启) |
目标:--at X,Y、--rect X,Y,W,H、--mouse、--window App[:title]、--element Label --app App、--peekaboo ID --snapshot see.json(来自 Peekaboo 的 see --json)。坐标是全局左上角逻辑点,即 Accessibility、CGWindowList 和 Peekaboo 报告的空间。--display N 将 --at 和 --rect 变为相对于某个显示器的坐标。
一个箭头绑定到它所指的应用。--app App[:window or tab title](或 --window)会先把那个应用、窗口或 Chrome/Safari 标签页置顶,因为指向藏在终端后面的窗口是特别没用的一种行为;当另一个应用遮挡目标时,箭头会隐藏并随之回来。--no-raise 则不触碰你的窗口。bigarrow elements --app X 列出 --element 能匹配的内容。bigarrow doctor 显示权限、它们的拥有者以及你的显示器。
每条命令都接受 --json。退出码:0 表示成功,2 表示输入错误,3 表示未找到目标,4 表示缺少权限。Agent 喜欢退出码。人类容忍它们。
外观
它是一个箭头,所以我们花了不合理的时间在它的外观上。
在一台干净的测试机上截取的真实截图,六种外观覆盖白色、macOS 灰色、深色、黑色、红色和一个内容密集的网页:
--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:默认是白色描边(在浅色背景上为深色)加投影;white-black在白色描边外加一圈细黑边代替投影;black仅是一圈细黑轮廓- 颜色都由你定:
--border-color、--text-color、--edge-color,X 标记的--close-color和--close-x-color也一样。若省略,每项自动选择一个可读的颜色 --close-button在标志的右端内部放置一个 X(白色圆圈,X 使用箭头颜色),它从不遮住文字也不会超出屏幕--follow跟随窗口或元素移动,--until-click在点击目标时结束,--say会朗读标志- 多个箭头同时存在时,标志彼此保持距离
箭杆通过一个喇叭形的关节从标志中长出,从不与圆角相交。scripts/gallery.py 在屏幕外渲染每种组合并放大每个关节(接合处),因为关节处出现接缝显然是无法接受的。
常见问题
它需要屏幕录制或辅助功能权限吗?
绘图两者都不需要。--element、elements、--until-click 和 front --window 使用辅助功能权限,macOS 会把它授予运行你的 shell 的应用(Terminal、iTerm2、Ghostty、VS Code、Claude),而绝非 bigarrow 本身。bigarrow doctor 会指明那个应用,退出码 4 则准确告诉 agent 应该向你请求什么。--window App:title 会读取窗口标题,macOS 26 在没有屏幕录制权限时会隐藏它们;--window App 单独使用时不需要任何权限。
我打字时它会抢走焦点吗?
不会。这是整个项目中难度最高的 bug:NSApplication.run() 会悄悄激活一个没有终端关联的进程,因此分离运行的箭头会夺取焦点。bigarrow 改为自行发送事件,并且测试会验证最前面的应用始终没有变化。
我能透过它点击吗? 可以,除了标志和箭杆之外:在这两处点击会移除箭头(在指针下轻微变暗以示)。点击目标,或箭头头部附近的任何地方,都会直接穿透到应用。点击箭头永远不会夺走焦点。
多显示器?全屏应用?台前调度?调度空间? 可以、可以、可以、可以。包括位于主显示器左侧或上方的显示器(负坐标)。在箭头条所在显示器上拔掉显示器,箭头会礼貌离开。查看 验证矩阵。
一个脉冲箭头占用多少 CPU? 在 CI runner 上测得 1.4%。渲染工作在渲染服务器的 Core Animation 中完成。
--element 在网页里能用吗?
在 Electron 应用里可以。在 Chrome 里,只有当 Chrome 带 --force-renderer-accessibility 运行时(或 VoiceOver 开启)才行;Chrome 会忽略通常的暴露页面内容请求,已于 2026 年 10 月在 Chrome 上验证。Chrome 自带的工具栏始终可用。否则请指向页面对应的坐标,具体方法在技能里有说明。
为什么不用某个屏幕标注应用? 那些是为人类在屏幕上绘制而设计的。这个工具是为程序指东西用的,从 shell 调用,并带有退出码。在写第一行代码之前检查了二十六个工具(研究)。没有一个能做到这件事。
这是 AI 吗? 不是。它是你的 AI 技术栈中最不智能的部分,并以此为荣。
我们怎么知道它能用
- 87 项自动化测试:几何、放置、关节平滑度、金标准图像、录制的窗口服务器、无障碍和 Peekaboo 4.9.0 固件,以及针对真实窗口服务器的测试(窗口层级 1000、点击穿透、焦点永不转移、分离与停止时机)。CI 在 macOS 15 上运行这些测试;它们在 macOS 26 和 macOS 27 上也通过了。
- 在干净的运行器上进行 17 项行为检查(visual.yml):对 X、
--until-click、--follow的真实点击,置顶(以及--no-raise),被遮挡时隐藏,选择 Chrome 标签页,与所属进程一同结束,stop --hook、--say,全屏应用,舞台管理,空间切换,第二显示器,2x 显示器,箭头显示中途拔出显示器,CPU。上面的演示 GIF 由同一工作流录制,来自一台没有个人内容的桌面。 - 一个全新的代理仅获得技能和指令"告诉 Franz Chrome 中刷新按钮的位置",便通过标签找到了它并构建了正确的命令(记录)。它还发现了一个 bug,该 bug 现已转化为测试。
给代理(以及配置它们的人类)
skill/big-arrow/ 中的技能同时适用于 Claude Code 和 Codex(一个 SKILL.md,Agent Skills 格式,加上给 Codex 用的 agents/openai.yaml)。它会告诉代理何时该指、如何选择目标、如何在标识牌上写完整的句子、当你可能不在看时添加 --say,以及在你操作完成后 stop。
计划、决策、研究
docs/plan/PLAN.md(目标、架构、风险),docs/plan/TICKETS.md(由 docs/plan/tickets.json 生成),docs/decisions/,docs/research/(带链接的已核实事实),docs/verification/、docs/skill-tests/、CHANGELOG.md。
先例与致谢
Peekaboo 的可视化器(https://github.com/openclaw/Peekaboo)和 Peter Steinberger 的 Nameplate(https://github.com/steipete/Nameplate)展示了覆盖窗口方案与代理技能打包方式。两者都没有绘制带标签的指向箭头,这正是本项目所填补的空白。bigarrow 可读取 Peekaboo 的 see --json 作为可选的目标来源。
许可证
MIT。请负责任地指。
来源:Hacker News · github.com












