内容
# MacKnock
一个可以由AI发起的很轻量的 macOS 原生可交互弹窗,适合放进脚本、自动化流程或 AI Agent 的工具箱里。
调用后,桌面中央会出现一张带标题、正文和选项按钮的小卡片。用户点击哪个按钮,程序就把对应的按钮文字输出到终端,脚本可以接着根据结果做下一步处理。
UI使用浅色毛玻璃、胶囊按钮、缓慢流动的渐变描边和呼吸光效。整个项目只需要 Swift 和 macOS 自带的 AppKit。
<p align="center">
<img src="assets/mac-knock-demo.png" width="900" alt="MacKnock 原生交互弹窗示意">
</p>
## 运行环境
- macOS 13 或更新版本
- Swift 5.9 或更新版本
## 编译
在项目目录运行:
```sh
swift build -c release
```
编译完成后,可执行文件位于:
```text
.build/release/mac-knock
```
## 基本用法
```sh
.build/release/mac-knock \
--title "休息一下?" \
--message "已经专注一阵子了,现在想怎么安排?" \
--buttons "休息五分钟,继续工作" \
--timeout 120
```
如果点击了“休息五分钟”,终端会收到:
```text
休息五分钟
```
如果一直没有选择,弹窗会在设定时间后自动消失,并输出:
```text
gave up
```
## 在脚本里读取选择
```sh
choice=$(
.build/release/mac-knock \
--title "今晚吃什么?" \
--message "选一个吧。" \
--buttons "寿司,意面,再想想" \
--timeout 60
)
case "$choice" in
"寿司") echo "那就去吃寿司" ;;
"意面") echo "开始找意面店" ;;
"再想想") echo "晚点再决定" ;;
"gave up") echo "这次没有选择" ;;
esac
```
只要能够执行本地命令并读取标准输出,就可以用同样的方式把它接进自己的工具或 Agent。
## 参数
```text
--title, -t TEXT 弹窗标题,默认为 MacKnock
--message, -m TEXT 正文内容,必填
--buttons, -b A,B,C 一到三个选项,用英文逗号分隔,默认为 OK
--timeout SECONDS 自动消失时间,可填 0–600 秒;0 表示不自动消失
--help, -h 查看帮助
--version 查看版本
```
正文也可以直接写成一个位置参数:
```sh
.build/release/mac-knock "你好,今天过得怎么样?"
```
按下回车会选择第一个按钮。弹窗可以拖动,按钮文字支持中文和英文。
## UI
弹窗外观集中写在 [`Sources/mac-knock/DialogWindow.swift`](Sources/mac-knock/DialogWindow.swift) 里,可以自行修改。
| 源码里的变量 | 控制的部分 |
|---|---|
| `cyan`、`ice`、`violet` | 流动描边的渐变颜色 |
| `accent` | 标题文字和第一个主按钮的颜色 |
| `tint.layer?.backgroundColor` | 毛玻璃卡片上覆盖的底色 |
| `shadowColor`、`shadowRadius`、`shadowOpacity` | 卡片外侧辉光的颜色、范围和亮度 |
| `cardWidth`、`padding`、`cornerRadius` | 卡片宽度、内容留白和圆角 |
| `titleFont`、`messageFont`、`buttonFont` | 标题、正文和按钮字号 |
| `buttonHeight`、`buttonSpacing` | 按钮高度和按钮之间的距离 |
| `glowBreath.values`、`glowBreath.duration` | 呼吸光的明暗范围和速度 |
| `flow.duration` | 渐变描边旋转一圈所需的时间 |
| `scale.duration`、`fade.duration` | 弹窗出现时的缩放和淡入速度 |
窗口默认位于屏幕中央稍微靠上的位置,对应 `y` 计算末尾的 `+ 60`。改成 `+ 0` 就会回到正中央。调整完成后重新运行 `swift build -c release` 即可。
## 从 VPS 远程调用
如果 Agent 跑在 VPS 上,也可以让弹窗显示在自己的 Mac 上。仓库里的 [`RemoteBridge`](RemoteBridge/README.md) 示例包含完整链路:
- Mac 端的本地 HTTP 桥
- 由 Mac 主动建立的反向 SSH 通道
- VPS 端可直接调用的 HTTP 接口
- 可注册到 Agent 中的 MCP 适配器
按钮结果会沿原路返回给 VPS 上的 Agent。具体配置和测试方法见 [RemoteBridge 使用说明](RemoteBridge/README.md)。
## License
MIT © 2026 Kitty and Nelio