← 返回信息流

GitHub Trending (API)短讯

franzenzenhofer/big-arrow-on-the-screen ⭐323

github.com开源AI评分:50/100

一个开源的 Mac 屏幕标注工具,允许 AI Agent(如 Claude Code 和 Codex)通过 CLI 在屏幕上绘制大箭头、方框和文本。支持点击穿透,且标注会自动消失。采用 MIT 协议。

big-arrow-on-the-screen(简称 bigarrow)是一款 macOS 命令行工具,同时也是 Claude Code 和 Codex 的一项技能,它会在每个窗口上方绘制一个箭头和一个指示牌。点击事件会穿透到下方的应用程序中,键盘焦点保持原位不变,且箭头会自动消失。采用 MIT 许可证。

CI
CI
License: MIT
License: MIT
Hacker News with five bigarrow arrows: the actual article is in here, finally an arrow bigger than this one, same desig…
Hacker News with five bigarrow arrows: the actual article is in here, finally an arrow bigger than this one, same desig…

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

bigarrow pointing at a dialog's Allow button
bigarrow pointing at a dialog's Allow button
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 参数。

System Settings, Device Control and Data Access: Franz, switch this on: Terminal may control your Mac
System Settings, Device Control and Data Access: Franz, switch this on: Terminal may control your Mac
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 中,该窗格称为“设备控制与数据访问”。没人会通过旧名称找到它。)

Keynote: 1. Click Animate, 2. Add an Effect
Keynote: 1. Click Animate, 2. Add an Effect

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

教一个应用程序:“我要在哪里添加过渡效果?”两个带编号的步骤,都在屏幕上,在一个已经放弃使用文字的工具栏中。

TextEdit print dialog: Mom, click PDF, then Save as PDF
TextEdit print dialog: Mom, click PDF, then Save as PDF
bigarrow start --element PDF --role button --app TextEdit \
  --text "妈妈,点击 PDF,然后另存为 PDF" --from bottom

在没有那二十分钟“那个小按钮,左下角,不,左边”的情况下帮助父母进行屏幕共享。

Chrome, three windows, 14 tabs: It's this tab, not the other 13
Chrome, three windows, 14 tabs: It's this tab, not the other 13
bigarrow start --app "Google Chrome:Sourdough" --element "Sourdough - Wikipedia" --role radiobutton \
  --text "是这个标签页,不是其他 13 个" --from top

--app "App:tab title" 会将正确的窗口带到前台并在指向之前选择该标签页。代理知道它指的是哪个标签页。现在你也知道了。

Finder: No, the other grid icon. This one.
Finder: No, the other grid icon. This one.
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 表示缺少权限。代理喜欢退出代码。人类容忍它们。

外观

它是一个箭头,所以我们花了不合理的时间来研究它的外观。

Big arrows with signs: click here, sign here, over here, you are here, type your name, read this first, no the other on…
Big arrows with signs: click here, sign here, over here, you are here, type your name, read this first, no the other on…
every border style and colour option: default white border with shadow, white-black, black, close button, custom border…
every border style and colour option: default white border with shadow, white-black, black, close button, custom border…
default, white-black, black, close button, custom colours and a black arrow, each over six backgrounds
default, white-black, black, close button, custom colours and a black arrow, each over six backgrounds
every style, shape, size and colour
every style, shape, size and colour
  • --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)。对话框是虚构的,但感受是真实的。

Delete node_modules? Yes. Obviously.
Delete node_modules? Yes. Obviously.
Cookie banner: Franz, nobody reads these either
Cookie banner: Franz, nobody reads these either
Software update: Twirl. Then click.
Software update: Twirl. Then click.
2FA: This is where you sigh and find your phone
2FA: This is where you sigh and find your phone
Friday deploy: the agent strongly suggests Cancel
Friday deploy: the agent strongly suggests Cancel
Three arrows, one Save button
Three arrows, one Save button
Grant Accessibility to Terminal, not to bigarrow
Grant Accessibility to Terminal, not to bigarrow

常见问题解答

是否需要“屏幕录制”或“辅助功能”权限?绘图本身不需要任何权限。但某些查找目标的方式需要:

你使用的功能所需权限
--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。负责任地使用。

译文已达到本站中文翻译的字数上限,剩余内容请查看原文。

阅读原文