GitHub Trending (API)短讯
franzenzenhofer/big-arrow-on-the-screen ⭐323
一个开源的 Mac 屏幕标注工具,允许 AI Agent(如 Claude Code 和 Codex)通过 CLI 在屏幕上绘制大箭头、方框和文本。支持点击穿透,且标注会自动消失。采用 MIT 协议。
big-arrow-on-the-screen(简称 bigarrow)是一款 macOS 命令行工具,同时也是 Claude Code 和 Codex 的一项技能,它会在每个窗口上方绘制一个箭头和一个指示牌。点击事件会穿透到下方的应用程序中,键盘焦点保持原位不变,且箭头会自动消失。采用 MIT 许可证。

你的 AI 代理可以重构单体仓库、编写迁移脚本并解释单子(monads),但当它需要你点击一个按钮时,却会在你看不到的终端里打印出“请在对话框中点击允许”。bigarrow 给了它一根手指头。

bigarrow point --element "Allow" --app "System Settings" --text "Franz, click Allow: Ghostty may control your Mac"箭头存在于其自身的透明窗口中,该窗口位于所有其他窗口之上,并在每个显示器和每个 Space 上显示。对目标的点击会落入下方的应用程序中,且绘制过程完全不需要 macOS 权限。它是一个单一的 Swift 二进制文件:没有守护进程,没有菜单栏图标,无需账户,无遥测数据,而且我们检查了两次,里面也没有 AI。它就只是一个箭头。
这到底有什么用?
好问题。箭头自旧石器时代左右就已存在。这里的变化在于:软件代理现在能在你的 Mac 上执行实际工作,迟早它们会遇到只有人类才能完成的一步,或者人类希望学习如何执行的一步。
- “点击允许。”macOS 权限提示、OAuth 同意屏幕、“使用…打开?”对话框。代理可以找到按钮,但不能或无法替你按下它。现在它可以指向那个按钮。
- “轮到你了。”双重认证代码、验证码、通行密钥、支付确认、签名、法律复选框。这些是代理绝不应该自行点击的项目。它负责指出来,由你决定,然后它继续执行。
- “是这个窗口,不是那个。”你有 14 个 Chrome 窗口。代理知道它指的是哪一个:--window "Google Chrome:Pull request"。它甚至能选中正确的标签页:--app "Google Chrome:Pull request"。
- “我需要你,而你在煮咖啡。”--say 选项会将指示牌内容朗读出来。你的 Mac 会 literally(字面意义上地)把你叫回办公桌前。
- “教我怎么做。”询问你的代理如何在 Keynote、Blender 或系统设置中执行某项操作,它会依次指向每个控件,而不是描述它:开始,等待你操作,停止,下一步。就像产品导览,只是去掉了产品本身。一个完整的示例:如何在 Mac 上允许屏幕录制,每一张截图都是代理绘制的箭头。
- 帮助他人。安装在父母的 Mac 上,那里的代理可以教他们如何将文档保存为 PDF。指点比说“上面的按钮,不,另一个上面的”要有效得多。
- 远程协助。“不,是另一个网格图标。”直接指向它,而不是描述它。
- 演示、屏幕录像、文档。在录制时突出重要内容,或使用 --png 将箭头直接渲染为 PNG 以用于文档。
- 调试坐标。不确定你的辅助功能、截图或 Peekaboo 坐标是否正确?指向它们并查看。--dry-run --json 选项会在不绘制的情况下告诉你它将指向哪里。
它不是什么:不是供人类使用的屏幕标注工具,不是点击机器人,也不是截图工具。它从不点击、输入或捕获任何内容。它只负责指向。故意如此。
真实应用,真实用例
这次没有虚假的对话框。测试 Mac(macOS 27)上的真实应用,中性的演示内容,全新的浏览器配置文件,以及真实的 bigarrow,由 scripts/real-scenes.sh 脚本编排。下面的每条命令都是实际运行的内容;脚本仅为截图添加了 --no-animation --json 参数。

open "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"
bigarrow start --element Terminal_Toggle --app "System Settings" \
--text "Franz, switch this on: Terminal may control your Mac" --from right引导人类完成权限设置:深度链接打开了确切的窗格,箭头找到了唯一的开关,指示牌说明了其作用。(在 macOS 27 中,该窗格称为“设备控制与数据访问”。没人会通过旧名称找到它。)

bigarrow start --element Animate --app Keynote --role radiobutton --text "1. Click Animate" --from right bigarrow start --element "Add an Effect" --app Keynote --text "2. Add an Effect" --from right
教一个应用程序:“我要在哪里添加过渡效果?”两个带编号的步骤,都在屏幕上,在一个已经放弃使用文字的工具栏中。

bigarrow start --element PDF --role button --app TextEdit \
--text "妈妈,点击 PDF,然后另存为 PDF" --from bottom在没有那二十分钟“那个小按钮,左下角,不,左边”的情况下帮助父母进行屏幕共享。

bigarrow start --app "Google Chrome:Sourdough" --element "Sourdough - Wikipedia" --role radiobutton \
--text "是这个标签页,不是其他 13 个" --from top--app "App:tab title" 会将正确的窗口带到前台并在指向之前选择该标签页。代理知道它指的是哪个标签页。现在你也知道了。

bigarrow start --element Group --role menubutton --app Finder \
--text "不,是另一个网格图标。就是这个。" --from top远程帮助,已针对 macOS 27 更新:齿轮图标不见了,但现在有两个网格图标,而且总是另一个。
这不是玩笑应用:如何在 Mac 上允许屏幕录制,这是一份真正的逐步指南,其中的每一张截图都是代理用 bigarrow 绘制的箭头。
安装
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/ 中的 shell 和 Python 文件用于录制屏幕截图并运行测试。
代理需要的三个命令
每个箭头都会自行结束。没有人需要清理忘记退出的代理留下的痕迹:
| 时间限制 | bigarrow point ... --duration 10(默认 8 秒;启动 300 秒;--duration 0 = 无限制) |
| 开始和停止 | bigarrow start ... 立即返回;bigarrow stop(或 stop --all)将其移除 |
| 代理离开 | 当绘制箭头的代理进程退出时,箭头结束(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),bigarrow 首先将该应用程序、窗口或 Chrome/Safari 标签页带到前台,因为指向隐藏在你终端后面的窗口是一种特别没有帮助的行为。如果后来另一个应用程序覆盖了目标,箭头将隐藏,直到目标再次可见。--no-raise 让你的窗口保持在原位。bigarrow elements --app X 列出 --element 可以匹配的内容。bigarrow doctor 显示权限、所有者以及你的显示器。
每个命令都接受 --json。退出代码:0 表示成功,2 表示输入错误,3 表示未找到目标,4 表示缺少权限。代理喜欢退出代码。人类容忍它们。
外观
它是一个箭头,所以我们花了不合理的时间来研究它的外观。




- --shape bend|straight|zigzag|spiral(当情况非常紧急时使用 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 会在后台渲染每种组合,并放大查看每个接口(连接处),因为接缝出现在接口处显然是不可接受的。
创意箭头
使用中性演示对话框进行布置,并在干净的 CI 运行器上使用真实的 bigarrow 录制(BACKDROP_ARGS=--cover scripts/funny-scenes.sh)。对话框是虚构的,但感受是真实的。







常见问题解答
是否需要“屏幕录制”或“辅助功能”权限?绘图本身不需要任何权限。但某些查找目标的方式需要:
| 你使用的功能 | 所需权限 |
|---|---|
| --at, --rect, --mouse, --window App, --peekaboo, --app App | 无 |
| --element, elements, --until-click, --app App:title(提升窗口或选择标签页) | 辅助功能 |
| --window App:title(macOS 26 隐藏了窗口标题) | 屏幕录制,以及用于提升窗口的辅助功能(除非使用 --no-raise) |
macOS 会将这些权限授予启动 bigarrow 的应用程序,即你的终端或 IDE(Terminal、iTerm2、Ghostty、VS Code、Claude),而绝不会授予 bigarrow 本身。因此,你需要在系统设置中开启的是那个应用程序的权限。bigarrow doctor 命令会告诉你具体是哪个应用,如果缺少权限,该命令将以退出码 4 退出,并指明缺失权限的应用及对应的设置面板。
它不会抢占焦点。那它如何保持在最前面?在 macOS 上,“位于顶层”和“拥有键盘焦点”是两回事。箭头的窗口位于屏幕保护程序窗口层级,高于普通窗口、对话框和全屏应用,但它永远不会成为活动窗口,因此你正在输入的内容会继续在原位进行。使用 --app 参数时,被指向的应用会首先被带到前台。
在我打字时会窃取我的焦点吗?不会。这是该项目中最难修复的一个 bug:NSApplication.run() 会静默激活一个没有终端进程,导致分离式箭头抢占了焦点。bigarrow 改为自行泵送事件,并且测试用例确保最前端的 app 永远不会改变。
我可以点击穿透它吗?可以,除了标志和箭杆部分:点击那里会移除箭头(指针下移时箭头会略微变暗以示提示)。点击目标区域,或靠近箭头头部的任意位置,点击事件会直接传递到对应应用。点击箭头本身永远不会获取焦点。
多显示器?全屏应用?Stage Manager?Spaces?是的,是的,是的,是的。包括主显示器左侧或上方的显示器(负坐标)。如果在箭头位于某显示器时拔掉该显示器,箭头会礼貌地离开。请参阅验证矩阵。
一个脉动箭头消耗多少 CPU?在 CI 运行器上测得为 1.4%。Core Animation 在渲染服务器中完成工作。
--element 在网页内部有效吗?在 Electron 应用中,是的。在 Chrome 中,仅当 Chrome 以 --force-renderer-accessibility 运行时(或 VoiceOver 开启时)才有效;Chrome 会忽略通常用于暴露页面内容的请求,此结论已于 2026 年 10 月在 Chrome 中得到验证。Chrome 自身的工具栏始终有效。否则,请指向页面的坐标,技能说明中对此有解释。
智能体能否利用这一点来欺骗我,例如遮挡“拒绝”按钮?它确实可以覆盖在按钮上绘制。但是,一个能够运行 shell 命令的智能体已经可以读取你的文件并运行任何程序,因此 bigarrow 并未赋予它任何新能力。bigarrow 本身保证的每一项内容均经过测试验证:方框和圆环是轮廓线,因此目标保持可见;只要周围有空隙,标志牌就会放置在远离目标的位置;如果没有空隙(即目标占据了大部分显示区域),它会尽可能少地重叠目标;点击标志牌或箭杆即可移除箭头;每个箭头最终都会自行消失。它从不点击、输入或捕获任何内容。当智能体要求你批准某项操作时,技能会指示它在标志牌上写明点击的效果,以便你在掌握事实的情况下做出决定。
为什么做成一个技能?这会占用大量 token 吗?智能体始终只能看到技能的描述,约 190 个 token。完整的指令约 2,200 个 token(使用 Anthropic 的 Claude Opus 5.5 token 计数 API 统计),仅在智能体决定指向时才加载。它们教导智能体何时指向、如何找到目标以及在标志牌上写什么。你也可以跳过该技能,直接调用 bigarrow。
为什么不直接使用 [某个屏幕标注应用]?那些是给人类在屏幕上绘图用的。这是给程序从 shell 中指向事物使用的,并带有退出码。在编写代码之前检查了 26 种工具(研究)。没有一种能做到这一点。
这是 AI 吗?不是。它是你的 AI 栈中最不智能的部分,并且以此为荣。
我们如何知道它有效
- 91 个自动化测试:几何、放置、连接平滑度、黄金图像、录制的窗口服务器、Accessibility 和 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、全屏应用、Stage Manager、Space 切换、第二个显示器、2x 显示器、在箭头中途拔掉显示器、CPU。上面的演示 GIF 由相同的工作流程录制,在一台没有任何个人数据的桌面上。
- 一个仅获得技能和“显示 Franz Chrome 中重新加载按钮在哪里”的新智能体,通过标签找到了它并构建了正确的命令(转录记录)。它还发现了一个 bug,现在已转化为测试。
对于智能体(以及配置它们的用户)
skill/big-arrow/ 中的技能同时适用于 Claude Code 和 Codex(一个 SKILL.md,Agent Skills 格式,以及 agents/openai.yaml 用于 Codex)。它告诉智能体何时指向、如何选择目标、在标志牌上写完整句子、在你可能没在看时添加 --say,并在你采取行动后停止。
计划、决策、研究
docs/plan/PLAN.md(目标、架构、风险),docs/plan/TICKETS.md(从 docs/plan/tickets.json 生成),docs/decisions/,docs/research/(带链接的验证事实),docs/verification/,docs/skill-tests/,CHANGELOG.md。
先例与致谢
Peter Steinberger 的 Peekaboo 可视化器(https://github.com/openclaw/Peekaboo)和 Nameplate(https://github.com/steipete/Nameplate)展示了叠加窗口配方和智能体技能打包方式。两者都没有绘制带标签的指向箭头,这正是本项目填补的空白。bigarrow 将 Peekaboo 的 see --json 作为可选的目标源进行读取。
许可证
MIT。负责任地使用。
译文已达到本站中文翻译的字数上限,剩余内容请查看原文。