☰
Peekaboo menubar 命令实战:用索引与名称精准操作 macOS 状态栏图标
2026/10/13 5:58:04 网站建设 项目流程
  • GUI 自动化
  • MCP 服务
  • AI 应用

【免费下载链接】Peekaboo

Peekaboo is a macOS CLI & optional MCP server that enables AI agents to capture screenshots of applications, or the entire system, with optional visual question answering through local or remote AI models.

项目地址:https://gitcode.com/gh_mirrors/peekaboo6/Peekaboo
点击查看免费下载

peekaboo menubar是 Peekaboo CLI 中专门用于操作 macOS 状态栏图标(status items,即 menu bar extras,例如 Wi-Fi、蓝牙、电池以及各类第三方托盘图标)的轻量级子命令。它通过MenuServiceBridge直接与菜单栏服务通信,帮助 AI Agent 以"先只读枚举、后显式授权点击"的安全方式完成状态栏交互,是自动化流程中点击系统托盘图标的标准化入口。读完本文,你将掌握menubar list/menubar click的完整参数用法、--foreground强制同意机制、按应用(--app/--pid)作用域定位 AX 状态项的原理,以及--verify多重弹窗验证策略。

命令定位:状态栏专用,与传统应用菜单互补

Peekaboo 的菜单类命令有明确分工:peekaboo menu处理传统的应用菜单(如 File、Edit),而peekaboo menubar严格面向菜单栏右侧的状态栏图标。在 MenuBarCommand.swift 的命令描述中可以看到,menubar的子命令注册为list与click两个真正的 Commander 子命令,且命令名不含连字符(不是menu-bar)。

两者的核心差异体现在交互代价上:

  • menubar list是只读操作,始终在后台完成,不打断用户当前工作;
  • menubar click会打开全局状态栏 UI(弹出 popover/菜单),因此强制要求显式的--foreground同意,其语义在源码中定义为 "Allow opening global menu bar UI (required for click)"(见 MenuBarCommand.swift)。

子命令与关键选项总览

menubar包含两个子命令,均支持全局的--json结构化输出与--verbose详细模式:

子命令说明
list打印每个可见状态栏图标及其索引;--json额外输出 bundle ID 与 AX 标识符
click按名称或索引点击状态栏图标;结合--app/--pid可点击特定应用拥有的 AX 状态项

click子命令的完整选项(与 MenuBarCommand.swift 的 Commander 绑定一一对应):

参数类型说明
[itemName]位置参数目标状态栏项目名称,传递给click
--index <n>数字按列表索引定位(与menubar list展示的排序一致,0 起)
--app <name-or-bundle-id>字符串仅限带名称的click:在指定应用中检查 AX 状态项,与--pid、--index互斥
--pid <pid>数字仅限带名称的click:在指定正 PID 进程中检查 AX 状态项,与--app、--index互斥
--foreground标志click必需;允许 Peekaboo 打开全局状态栏 UI 并打断当前前台工作流
--verify标志点击后确认同一 PID 拥有的 popover 出现,或焦点已转移到所属应用/窗口(含 OCR 兜底)
--includeRawDebug(仅list)标志在 JSON 输出中包含原始调试字段(窗口 owner/layer)
全局标志—--json输出结构化负载;--verbose在列出时增加描述信息

list:只读枚举状态栏清单

peekaboo menubar list通过MenuServiceBridge.listMenuBarItems获取清单(见 PeekabooBridgeClient+MenusDockDialogs.swift),底层走 Bridge 通道,不触发任何前台交互。

人类可读输出

默认输出格式由 MenuBarItemListOutput.swift 定义:

$ peekaboo menubar list Menu Bar Items (5): [0] <untitled> Frame: 0,0 24×22 [1] Wi-Fi Description: Wi-Fi status Frame: 300,0 20×20 ...

每行展示[索引] 名称,并在可用时附带 Description 与屏幕坐标 Frame。当列表非空时,命令还会打印一行提示,引导你使用peekaboo menubar click --index <index> --foreground或peekaboo menubar click "<name>" --foreground(此行为同样有测试覆盖,见 MenuBarCommandConsentTests.swift)。若未检测到任何状态项,则输出No menu bar items detected.。

JSON 输出字段

--json输出包含items与menu_bar_items(同一数组的别名,兼容不同消费方)以及count。每个MenuBarItemInfo条目(定义于 MenuServiceProtocol.swift)包含:

字段含义
title面向用户展示的名称
rawTitle系统报告的原始名称(可能形如Item-0)
index菜单栏中的序号
isVisible当前是否可见
description可选描述
bundleIdentifier所属应用的 bundle ID(如com.apple.controlcenter)
ownerName所属应用名或 owner 字符串(如Control Center)
identifier/axIdentifierAX 稳定标识符
axDescriptionAX 帮助文本
frame屏幕坐标包围盒
rawWindowID/rawWindowLayer/rawOwnerPID原始窗口 ID、窗口层(菜单项常见 24/25)、拥有进程 PID
rawSource数据来源(如cgs、cgwindow、ax-control-center)
selectionEvidence精确的状态项身份与有序清单摘要,供后续点击操作校验

--verbose模式会追加 owner 名称与隐藏状态等诊断信息;--includeRawDebug则会补全rawWindowID/rawWindowLayer等原始调试字段。

click:名称、索引与应用作用域三种定位方式

menubar click的目标解析分为**无作用域(全局清单)与应用作用域(--app/--pid)**两条路径,两者都要求先满足--foreground。

强制的前置同意:--foreground

在 MenuBarCommand.swift 中,clickMenuBarItem的第一道关卡就是检查--foreground;缺失时直接抛出MenuBarClickPreflight.foregroundConsentRequired,其错误信息为 "Menu bar clicks require --foreground because status items open global UI."。这保证在任何状态项查找之前就完成拒绝,避免产生无谓的查询与副作用。

对应的测试foreground consent precedes explicit named preparation与named click without foreground refuses before lookup or dispatch验证了:缺少--foreground时prepareCalls、listCallCount、namedClickCalls、indexClickCalls全部为零,即不触发任何查找或分发(见 MenuBarCommandConsentTests.swift)。

无作用域:按索引或按名称

无--app/--pid时,命令先通过listMenuBarItems拿到当前显示的 WindowServer 清单,再由MenuBarItemSelector(见 DeterministicDesktopLeafSelector.swift)完成匹配:

  • 按索引:--index <n>直接对应list展示的序号。索引越界/过期会以MENU_ITEM_NOT_FOUND拒绝,提示重新执行menubar list获取当前索引。
  • 按名称:大小写不敏感的模糊匹配(匹配字段覆盖title、rawTitle、identifier、axDescription、ownerName)。

关键的设计保证是名称目标在分发阶段始终保持名称绑定:即使两次调用之间状态栏发生重排,点击也不会被错误重定向到另一个索引——resolveClickTarget中索引选择器只负责"定位候选",真正下发时仍走 named 请求(MenuBarItemActionRequest(named:...)),相关测试foreground named click preserves name-based dispatch断言namedClickCalls == ["Wi-Fi"]而indexClickCalls为空(见 MenuBarCommandConsentTests.swift)。

此外,无作用域的名称/索引保留"显示的 WindowServer 清单 + 精确窗口路径":一个唯一显示的名称不会触发全局 AX 扫描,因此无关的图形辅助进程无法阻塞该路径;只有含糊匹配或过期的显示证据会在分发前被拒绝。

应用作用域:--app 与 --pid

click <name> --app ...或--pid ...走 scoped 准备路径:命令先通过MenuBarClickPreflight.prepare调用MenuServiceBridge.prepareMenuBarItem,在指定应用代(generation)内部、带有 deadline 地准备一份AXExtrasMenuBar清单。参数校验规则在 MenuBarCommand.swift 中明确:

  • --app与--pid二选一,同时给出报VALIDATION_ERROR;
  • --index不能与--app/--pid组合;
  • PID 必须是正数,空字符串、PID:0前缀等非法应用标识会被拒绝;
  • 名称与索引不能同时给出。

准备阶段会记录原始 owner 选择器、进程代与选中项证据;分发阶段对证据做复验,并在最终读取之间核对原生叶节点身份,不借用 Control Center 代理的窗口 ID,且准备过程从不聚焦应用。若应用名/bundle ID 指向的应用在当前代中缺失、不可读、已变化或匹配含糊,一律在分发前拒绝;不确定的 AX 提交绝不通过其他路由重试。

作用域内匹配的细节语义:在显式 owner 内,项目文本只匹配原生叶节点的 title、help、description 或 identifier;应用名与 bundle ID 是 owner 选择器,不是额外的项目名别名。作用域点击与无作用域点击一样强制--foreground,且不能使用--index,也绝不回退到其他应用或全局清单。若运行时未协商scopedMenuBarActions,较旧的 Bridge host 会直接拒绝而非忽略 owner 作用域(见 PeekabooBridgeClient+MenusDockDialogs.swift)。

同时,兼容性说明:既有的编程式clickMenuExtraAPI 仍保留仅依赖 Accessibility 的系统菜单路径(不需要 CG 窗口或 Event Synthesizing 权限);原始命名的 SDK 调用保留 AX 优先查找与既有的安全分发前兜底。这两条兼容路由都不会取代CLI 与当前受证明的远程命名调用所使用的"证据绑定"请求。

错误输出契约

名称缺失、索引过期、作用域不匹配等失败统一在分发前以MENU_ITEM_NOT_FOUND拒绝,JSON 负载包含effect: refused、retry_safe: true、mutation_dispatched: false(源码定义于 MenuBarCommand.swift)。测试missing named item is one typed pre-dispatch refusal断言了完整的错误消息Menu bar item not found: Missing及上述字段(见 MenuBarCommandConsentTests.swift)。

verify:点击后的多重弹窗验证链

--verify的核心实现在 MenuBarClickVerifier.swift,验证按以下优先级逐步进行,任一步成功即返回verified: true及对应method:

  1. popover 解析(无 OCR):轮询MenuBarPopoverResolver,在给定超时(默认 1.5s)内寻找与点击项同 PID 的弹出窗口。解析依据依次为 owner PID(置信度 1.0)、owner 名称(0.9)、排名/首选 X 坐标(0.4),原因标记如owner_pid、owner_name、preferred_x、window_rank(见 MenuBarPopoverResolver.swift)。
  2. 焦点窗口变化:确认点击后前台应用是否变为 owner,或聚焦窗口的 ID/标题是否发生变化(focused_window,置信度 0.7)。
  3. owner 窗口出现:检查 layer 0 上是否出现 owner 的可见窗口(owner_pid_window,置信度 0.6),通过ObservationMenuBarWindowCatalog按 PID 或按名称/标题匹配。
  4. OCR 兜底(默认开启):对排名靠前的候选窗口执行 OCR,要求 popover 文本包含目标标题/owner 名,并将验证锚定到点击项的 X 坐标;区域 OCR 兜底(ocr_area)也在允许时启用。OCR 需要屏幕录制(Screen Recording)权限。
  5. AX 菜单检查(默认关闭):仅当环境变量PEEKABOO_MENUBAR_AX_VERIFY=1时才通过isMenuExtraMenuOpen检查 AX 菜单是否展开(ax_menu)。

两个验证开关的环境变量语义:

环境变量默认作用
PEEKABOO_MENUBAR_OCR_VERIFY=0OCR 开启显式关闭 OCR 验证(仍要求 popover 文本包含目标标题/owner)
PEEKABOO_MENUBAR_AX_VERIFY=1AX 关闭显式开启 AX 菜单检查(可选,依赖 Accessibility)

验证成功后,JSON 输出的verified为true,effect 升级为confirmed;验证失败会抛出operationError("Menu bar verification failed: popover not detected")。此外,点击结果会记录屏幕坐标数据(若可得),便于你关联交互发生的屏幕位置。

完整可运行的实战示例

# 1. 只读列出所有状态栏图标及其索引(后台进行,无需 --foreground) peekaboo menubar list # 2. 按名称点击 Wi-Fi 图标(必须显式 --foreground) peekaboo menubar click "Wi-Fi" --foreground # 3. 点击并验证 popover 已打开(OCR 验证默认开启) peekaboo menubar click "Wi-Fi" --verify --foreground # 4. 直接按索引点击第三个图标,并输出结构化 JSON peekaboo menubar click --index 3 --foreground --json # 5. 显式定位第三方应用 AX 拥有的状态项(按 bundle ID) peekaboo menubar click "Status Item" --app com.example.StatusApp --foreground --json # 6. 把命名项绑定到从应用列表取得的 PID peekaboo menubar click "Status Item" --pid 12345 --foreground --json # 7. 带原始调试字段的 JSON 清单(list 专属) peekaboo menubar list --json --includeRawDebug

click --foreground --json的成功负载示例(ClickJSONOutput,见 MenuBarCommand.swift)包含success、clicked(元素描述)、executionTime、verified与selectedLeafEvidence数组;非 JSON 模式下,验证成功会额外打印✅ Clicked menu bar item: ...与🔎 Verified menu bar click (<method>),--verbose下还会显示耗时。

故障排查

  • 先确认权限:使用peekaboo permissions status验证 Screen Recording 与 Accessibility 权限均已授予(OCR 验证依赖屏幕录制,AX 依赖辅助功能)。
  • 确认进程与当前 UI:用peekaboo app list确认目标进程,用peekaboo window list确认其精确窗口,再用peekaboo see查看当前界面,再重试。
  • 用结构化输出定位问题:重跑时加--json或--verbose,可以拿到具体的错误码(如MENU_ITEM_NOT_FOUND、VALIDATION_ERROR)、hint与retry_safe字段,便于判断是名称/索引过期、作用域冲突还是缺少同意。
  • 索引过期:状态栏重排后索引会失效,先peekaboo menubar list刷新,再按新索引操作;名称目标则不受重排影响。
  • 验证失败:若--verify报 "popover not detected",先确认点击确实产生了弹出 UI;可临时设PEEKABOO_MENUBAR_OCR_VERIFY=0排除 OCR 因素,或设PEEKABOO_MENUBAR_AX_VERIFY=1尝试 AX 路径。

小结

peekaboo menubar把 macOS 状态栏交互收敛为"只读枚举 + 显式授权点击"两段式流程:list始终在后台提供权威清单,click以--foreground作为强制门槛,再通过名称/索引/应用作用域三种定位与--verify的五级验证链(popover、焦点变化、owner 窗口、OCR、AX),在可审计的证据绑定机制下完成点击。理解这些选项与拒绝语义,你就能在自动化流程中安全、可靠地驱动 Wi-Fi、蓝牙、电池等系统状态项与第三方托盘应用。

  • GUI 自动化
  • MCP 服务
  • AI 应用

【免费下载链接】Peekaboo

Peekaboo is a macOS CLI & optional MCP server that enables AI agents to capture screenshots of applications, or the entire system, with optional visual question answering through local or remote AI models.

项目地址:https://gitcode.com/gh_mirrors/peekaboo6/Peekaboo
点击查看免费下载

相关推荐

上一篇:SMS Backup+ OAuth2认证机制揭秘:如何安全备份短信到Gmail
下一篇:Amphion Singing Voice Conversion(SVC)指南:基于多语义内容特征与扩散声学模型的歌声转换全流程实战

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询