AppleScript 操控 Chrome 给 AI 发消息:一个 macOS 菜单栏工具的技术复盘
背景
一个实际的技术需求:每天在浏览器里找 AI 标签页 50+ 次,在终端里 cd 路径启动 Claude Code 30+ 次。能不能用一个全局快捷键搞定所有 AI 的启动?
我用 Swift + AppleScript 做了个 macOS 菜单栏工具来解决这个问题。下面是完整的技术方案和踩坑记录。
最终产品叫 GroAsk,是一个 macOS 菜单栏的 AI 启动器。按 ⌥Space 全局唤起输入框,直接发消息给任意 AI。
技术方案
整体架构
纯 Swift + AppKit,没用 SwiftUI @main(菜单栏应用用 SwiftUI 生命周期有坑),没用 Electron。SPM 管理依赖。
入口是 main.swift 手动创建 NSApplication,通过 AppDelegate 注册全局快捷键。
Web AI 通道
核心思路:AppleScript 操控 Chrome 浏览器。
流程:用户输入消息 → Router.swift 判断当前通道类型 → WebManager.swift 构建 AppleScript 异步队列 → 定位或创建 Chrome 标签页 → WebScriptGenerator.swift 生成针对目标网站的 JS 注入脚本 → 填入文本并模拟发送。
踩坑点:
- AppleScript 异步队列。 AppleScript 执行是阻塞的,多个操作串行执行容易卡 UI。用异步队列包装,确保主线程不阻塞。
- 各 AI 网站 DOM 差异大。 ChatGPT、Claude、Gemini 的输入框、发送按钮选择器都不一样,需要为每个站点维护独立的注入脚本。DOM 结构一更新就得跟着改。
- Chrome 标签页状态同步。 需要判断目标标签页是否已打开、是否已加载完成,处理各种边界情况。
CLI 通道
核心思路:AppleScript 操控终端应用。
TerminalBridge.swift 负责桥接。支持 Terminal.app 和 iTerm2。用户在图形界面选择项目目录后,自动拼接 cd /path && claude 命令发送到终端执行。
踩坑点:
- 终端别名自动补全。 用户可能在
.bashrc或.zshrc里定义了claude的别名,需要检测并处理。 - 路径中的特殊字符。 空格、中文、引号等都需要正确转义。
全局快捷键
通过 CGEvent.tapCreate 注册系统级事件监听,拦截 ⌥Space 组合键。需要辅助功能权限(Accessibility)。
通道配置
所有 AI 通道的定义放在 Channel.swift,配置从 config.json 生成。新增一个 AI 通道只需要加配置项 + 写注入脚本,不需要改架构。
开发效率
整个项目从零到上线两周,代码基本由 Claude Code 生成。我的角色更像产品经理:定义需求、验证结果、处理边界情况。一个人覆盖了 Swift 客户端、Cloudflare Workers 后端、静态官网、Apple 签名公证全链条。
现状
目前完全免费,macOS 专属,已迭代接近 30 个版本。
下载不到 5MB,免费使用:groask.com/zh/
AppleScript 异步队列和 Chrome 标签页状态管理这块坑不少,有做类似自动化的朋友欢迎评论区交流方案。
本作品采用《CC 协议》,转载必须注明作者和本文链接
关于 LearnKu
记得applescript 也能实现gui ,之前让ai 实现php gui的时候,ai 写了一版 applescript 运行的gui
对,AppleScript 确实有
display dialog、choose from list这些原生 GUI 能力,做简单交互完全够用。GroAsk 最终选了纯 Swift + AppKit 做界面,主要是需要自定义的交互(输入框联想、通道切换等),AppleScript GUI 的定制空间比较有限。项目里 AppleScript 专门负责"操控 Chrome 和终端"这块自动化,各司其职。PHP GUI 用 AppleScript 跑这个思路挺有创意的,AI 找了个最短路径哈哈