🔶 NotchAgent:为 herdr 下运行的 AI Agent 提供原生 macOS 刘海屏控制
英文标题:🔶 NotchAgent – native macOS notch control for AI agents running under herdr
NotchAgent 是一款原生 macOS 工具,可通过 MacBook 刘海区域监控、审批或拒绝请求、回复问题,并快速跳转至由 herdr 管理的 AI 编程 Agent 终端窗格。herdr 负责将 15 种以上 Agent 统一为状态模型和 JSON Socket API,而 NotchAgent 作为 Socket 客户端与 `NSPanel` 刘海屏界面,持续同步 Agent 状态并保持所有操作由用户明确触发。该项目支持 Claude 和 Codex 的交互模式切换、全局快捷键、免打扰、开机启动及无 Dock 图标运行,并提供 `notchctl` 无头 CLI 用于诊断、审批和回复流程。对开发者而言,它展示了如何将多 Agent 终端工作流整合为轻量、可审计且以用户控制为中心的 macOS 原生交互层。
1.7 MB
50.0 KB
48.0 KB
115.9 KB
316.8 KB
97.2 KB
中文
一款原生 macOS 刘海屏控制界面,面向在你偏好终端中、由 herdr 运行的 AI 编程 Agent。你可以直接从 MacBook 刘海区域监控、审批或拒绝、回复,并跳转至你的 Agent,无需在众多终端窗格中寻找那个正等待你处理的窗口。
herdr 是状态权威来源(它将 15 种以上 Agent 归一化为统一状态模型和 JSON Socket API);本应用是一个 Socket 客户端 + 刘海屏 NSPanel UI。核心层从快照中水合数据、持续协调 Agent 状态,并将事件视为加速机制。UI 保持轻量,且每一次响应都明确由用户驱动。
- 在刘海下方显示极简的颜色编码状态线;悬停时显示 Agent 数量,也可按偏好始终显示。
- 当 Agent 被阻塞并需要输入时,打开相应的交互界面。
- 在一个总览中收集所有 herdr 会话,显示状态、提示内容、耗时,以及直接跳回对应终端窗格的入口。
- 将受支持的审批和问题转换为明确、可点击的操作;对于不确定的情况,保留终端回退方式。
- 通过当前焦点面板的 Mode 按钮显示并切换 Claude 和 Codex 交互模式,包括可用时的 Claude Auto 模式。
- 支持显示位置、全局快捷键、声音、免打扰和登录时启动,同时不添加 Dock 图标。
| 最小化阻塞指示器 | 悬停时显示 Agent 数量 |
|---|---|
![]() |
![]() |
一览所有 Agent
- 需要搭载 Apple Silicon 的 macOS 14+,以及 Swift 6.2 工具链(Xcode 16+)。
- 必须已安装并运行 herdr,且需有终端客户端连接到它,NotchAgent 才能发现或控制 Agent。
- 无第三方依赖(Foundation/AppKit/SwiftUI + POSIX sockets)。
使用 Homebrew:
brew install --cask ykushch/tap/notchagent
或者,从 GitHub Releases 下载 NotchApp-<version>.zip,解压后将 NotchApp.app 移动到 /Applications。
发布包使用 ad-hoc 签名而非公证签名,因此 macOS 可能会阻止首次启动。右键点击应用并选择 Open,或移除隔离属性:
xattr -dr com.apple.quarantine /Applications/NotchApp.app
从源代码构建应用程序包:
./bundle.sh && open build/NotchApp.app
首次启动时,请在 系统设置 → 隐私与安全性 → 辅助功能 中授予 Notch Agent 访问权限。全局快捷键和 Agent 操作需要此权限;如果存在陈旧的已拒绝条目,请先使用 − 按钮将其移除。
swift build # 所有目标
swift test # 完整测试套件(swift-testing)
GitHub Actions 会在 macos-15 runner 上使用 Xcode 16.4,为每次推送到 main 的提交和每个拉取请求进行构建与测试。推送版本标签会运行相同测试,构建 NotchApp-<version>.zip,验证应用和归档文件签名,发布带有自动生成说明的 GitHub Release,并更新 Homebrew cask。
发布工作流需要一个名为 HOMEBREW_TAP_TOKEN 的仓库密钥。创建一个细粒度个人访问令牌,将其限制为 ykushch/homebrew-tap 仓库,并授予 Contents: Read and write 权限;然后在此仓库的 Settings → Secrets and variables → Actions 中添加它。内置的 GITHUB_TOKEN 用于发布 Release 本身,不需要额外密钥。
配置好该密钥后,发布只需执行:
git tag -a v1.2.3 -m "NotchAgent 1.2.3"
git push origin v1.2.3
标签必须包含由点分隔的数字版本号(v1.2.3);该工作流会将版本传给 bundle.sh,并将生成归档文件的 SHA-256 写入 tap。
notchctl —— 无头 CLI 测试工具
在使用 UI 之前或不使用 UI 时,对整个核心层(客户端 + 存储 + 分类器 + 操作)进行内部验证。它是轻量封装:所有逻辑都位于 HerdrClient 库中。
swift run notchctl list # 列出所有 Agent + 汇总状态(F1)
swift run notchctl watch # 流式输出状态变化;对阻塞进行分类(F1/F2/F4)
swift run notchctl read <pane> # 显示某个窗格已分类的提示(F4)
swift run notchctl --json read <pane> # 归一化证据 + 建议的响应计划
swift run notchctl --json inspect <fixture> # 验证并检查离线 .fixture 目录
swift run notchctl --json dry-run <pane> option 2 # 重新读取 + 规划;绝不发送输入
swift run notchctl resolve <pane> <choice> # choice = approve | deny | <option number>(F3/F4)
swift run notchctl reply <pane> <text...> # 自由文本回复,按 Enter 提交(F4/F9)
swift run notchctl jump <pane> # 聚焦该窗格并显示其终端(F5)
全局标志:--json(机器可读输出)、--sock <path>(显式 Socket 路径;否则依次从 HERDR_SOCKET_PATH → HERDR_SESSION → ~/.config/herdr/herdr.sock 解析)。
示例:
$ swift run notchctl list
● w3:p1 working claude /Users/you/project *
○ w1:p1 idle claude /Users/you/other
resolve/reply 会通过 pane.read --source detection 读取窗格当前提示、对其分类,并发送经验证的按键组合令牌(herdr 会拒绝 prefix+ 绑定)。未知提示形态会回退为原始视图——该工具绝不会编造按键操作。
read --json 会报告归一化的提供商和屏幕适配器、稳定指纹、交互类型与内容、选项/步骤、展示状态、能力、置信度、窗格版本,以及每一个建议的响应计划或明确拒绝。输出键按排序排列,因此相同证据会产生字节完全一致的 JSON。原始终端字节会被刻意排除;请使用 capture 获取原始证据,并使用 inspect 获取归一化诊断信息。
inspect <path> 无需连接 herdr,即可验证并解析一个内容寻址的 .fixture 目录。它也支持独立的检测文件,可搭配 --agent ID,以及可选的 --visible FILE、--pane ID 和 --revision N 使用。
dry-run <pane> <intent> 会读取交互一次,随即再次读取,将稳定指纹进行比较,并依据最新展示状态规划操作。其核心边界不具备操作/传输发送器,且无法写入输入。支持的 intent 包括 option N、check N、uncheck N、type TEXT、text TEXT、option-text N TEXT、add-notes、clear-notes、previous、next、step N、submit、approve、deny 和 cancel。传入 --expected-fingerprint HEX 可审计此前观察到的身份标识。
它以辅助应用形式运行(无 Dock 图标,且绝不抢占焦点)。一个不激活、始终置顶的 NSPanel 位于刘海周围:极简状态线会在悬停时显示 Agent 数量(也可按偏好始终显示),而被阻塞的 Agent 会直接打开为可操作的交互界面。有关手动测试清单,请参阅 Sources/NotchApp/README.md。
Sources/HerdrClient/—— M1 核心层(Socket 客户端、模型、状态存储、提示分类器、操作层)。有关架构以及影响其设计的协议事实,请参阅CLAUDE.md。Sources/notchctl/—— CLI 测试工具。Sources/NotchApp/—— 刘海屏 UI(M2)。Tests/HerdrClientTests/—— 基于录制 fixture 的 swift-testing 测试套件。
English / 原文
A native macOS notch control surface for AI coding agents running under herdr in your preferred terminal. Monitor, approve or deny, answer, and jump to your agents from the MacBook notch — without hunting through terminal panes for the one that needs you.
herdr is the state authority (it normalizes 15+ agents into one status model and a JSON socket API); this app is a socket client + notchNSPanel UI. The core hydrates from snapshots, reconciles agent state continuously, and treats events as an accelerator. The UI stays thin and every response remains explicitly user-driven.
- Shows a minimal color-coded status line below the notch, revealing the agent count on hover or keeping it visible if you prefer.
- Opens the relevant interaction when an agent becomes blocked and needs input.
- Collects every herdr session in one overview with status, prompt, elapsed time, and a direct jump back to its terminal pane.
- Turns supported approvals and questions into explicit, clickable actions while preserving a terminal fallback for anything uncertain.
- Displays and cycles Claude and Codex interaction modes from the focused panel's Mode button, including Claude Auto mode when it is available.
- Supports display placement, global hotkeys, sounds, Do Not Disturb, and launch at login without adding a Dock icon.
| Minimal blocked indicator | Agent count on hover |
|---|---|
![]() |
![]() |
See every agent at a glance
- macOS 14+ on Apple Silicon, Swift 6.2 toolchain (Xcode 16+).
- herdr must be installed and running, with a terminal client attached to it, before NotchAgent can discover or control agents.
- No third-party dependencies (Foundation/AppKit/SwiftUI + POSIX sockets).
With Homebrew:
brew install --cask ykushch/tap/notchagent
Alternatively, download NotchApp-<version>.zip from GitHub Releases, extract it, and move NotchApp.app to /Applications.
Release bundles are ad-hoc signed rather than notarized, so macOS may block the first launch. Right-click the app and choose Open , or remove quarantine:
xattr -dr com.apple.quarantine /Applications/NotchApp.app
To build an app bundle from source:
./bundle.sh && open build/NotchApp.app
On first launch, grant Notch Agent access in System Settings → Privacy & Security → Accessibility. This permission is required for global shortcuts and agent actions; if a stale denied entry exists, remove it with the − button first.
swift build # all targets
swift test # full test suite (swift-testing)
GitHub Actions builds and tests every push and pull request to main on the macos-15 runner with Xcode 16.4. A pushed version tag runs the same tests, builds NotchApp-<version>.zip, verifies the app and archive signatures, publishes a GitHub Release with generated notes, and updates the Homebrew cask.
The release workflow needs one repository secret named HOMEBREW_TAP_TOKEN. Create a fine-grained personal access token restricted to the ykushch/homebrew-tap repository with Contents: Read and write , then add it under Settings → Secrets and variables → Actions in this repository. The built-in GITHUB_TOKEN publishes the release itself and does not need another secret.
Once that secret is configured, releasing is just:
git tag -a v1.2.3 -m "NotchAgent 1.2.3"
git push origin v1.2.3
Tags must contain numeric dot-separated versions (v1.2.3); the workflow passes the version to bundle.sh and writes the resulting archive SHA-256 into the tap.
notchctl — headless CLI harness
Dogfoods the whole core (client + store + classifier + actions) before/without the UI. Thin wrapper: all logic lives in the HerdrClient library.
swift run notchctl list # list all agents + rollup status (F1)
swift run notchctl watch # stream status changes; classify blocks (F1/F2/F4)
swift run notchctl read <pane> # show the classified prompt for a pane (F4)
swift run notchctl --json read <pane> # normalized evidence + proposed response plans
swift run notchctl --json inspect <fixture> # verify and inspect an offline .fixture directory
swift run notchctl --json dry-run <pane> option 2 # re-read + plan; never send input
swift run notchctl resolve <pane> <choice> # choice = approve | deny | <option number> (F3/F4)
swift run notchctl reply <pane> <text...> # free-text reply, submits with enter (F4/F9)
swift run notchctl jump <pane> # focus the pane + present its terminal (F5)
Global flags: --json (machine-readable output), --sock <path> (explicit socket path; otherwise resolved from HERDR_SOCKET_PATH → HERDR_SESSION → ~/.config/herdr/herdr.sock).
Example:
$ swift run notchctl list
● w3:p1 working claude /Users/you/project *
○ w1:p1 idle claude /Users/you/other
resolve/reply read the pane's current prompt via pane.read --source detection, classify it, and send validated key-combo tokens (herdr rejects prefix+ bindings). Unknown prompt shapes fall back to a raw view — the tool never fabricates a keystroke.
read --json reports the normalized provider and screen adapter, stable fingerprint, interaction kind/content, choices/steps, presentation state, capabilities, confidence, pane revision, and every proposed response plan or explicit refusal. Output keys are sorted so identical evidence produces byte-identical JSON. Raw terminal bytes are deliberately excluded; use capture for raw evidence and inspect for normalized diagnostics.
inspect <path> verifies and parses a content-addressed .fixture directory without connecting to herdr. A standalone detection file is also supported with --agent ID and optional --visible FILE, --pane ID, and --revision N.
dry-run <pane> <intent> reads the interaction once, immediately re-reads it, compares stable fingerprints, and plans from the fresh presentation. Its core boundary has no action/transport sender and cannot write input. Supported intents are option N, check N, uncheck N, type TEXT, text TEXT, option-text N TEXT, add-notes, clear-notes, previous, next, step N, submit, approve, deny, and cancel. Pass --expected-fingerprint HEX to audit a previously observed identity.
Runs as an accessory app (no Dock icon, never steals focus). A non-activating always-on-top NSPanel sits around the notch: a minimal status line reveals the agent count on hover (or stays visible by preference), and a blocked agent opens directly into its actionable interaction. See Sources/NotchApp/README.md for the manual test checklist.
Sources/HerdrClient/— the M1 core (socket client, models, state store, prompt classifier, action layer). SeeCLAUDE.mdfor architecture + the protocol facts that shaped it.Sources/notchctl/— the CLI harness.Sources/NotchApp/— the notch UI (M2).Tests/HerdrClientTests/— swift-testing suite over recorded fixtures.




