MiMoCode 干完活儿发通知
Posted | stdout
AI在 coding 的时候我其实在玩别的。希望agent 每次干完活,macOS 弹个通知。
手上是 MimoCode,就让它自己写个。啪,很快写好了。结果还是折腾了好一会儿, 记录几个有意思的小坑。
首先是如果当前CLI是活动的,就不弹通知。
需要判断活动窗口。最初用 osascript
osascript -e 'tell application "System Events" to get name of first application process whose frontmost is true'
直接报错 Not authorized to send Apple events to System Events (-1743)。
于是换 lsappinfo,走 macOS Launch Services API,不需要任何额外授权:
lsappinfo info -only name $(lsappinfo front)
# → "LSDisplayName"="Terminal"
还能拿 PID:lsappinfo info -only pid $(lsappinfo front)。
然后如何判定活动窗口是不是 CLI?
写死个["iTerm2", "Terminal", "Alacritty", "kitty", ...] 列表
太笨了。当前hook是子进程,直接遍历 parent 进程树啊!找到终端模拟器的 PID,再跟前台 app 的 PID 比对。
但是在 tmux 里爬出来是这样的:
node → zsh → tmux → launchd(1) → init(0)
Terminal.app 的 PID 根本不在树上。因为 tmux server 启动后被 reparent 到了 launchd,跟 Terminal.app 断开了父子关系。
又想到一个办法,直接查 $TMUX_PANE 是否是当前 active pane:
tmux list-panes -F '#{pane_id} #{pane_active}' | awk '$2==1 {print $1}'
如果 $TMUX_PANE == active pane ID,说明用户就在看这个窗口,不需要通知。完全不需要知道前台是哪个 app。
非 tmux 场景才用进程树 + lsappinfo 的 PID 比对。
然后就是挑选具体哪些事件要弹通知了。
权限通知:permission.ask,但文档说 "not yet wired"。试了一下,确实没触发。尴尬。雷军!!!金凡!!!
最后的方案:注册 permission.ask 占位,如果哪天接入了就能精确捕获。目前靠 tool.execute.before 抢占并推断。工具跑完了说明权限已过或不需要。
还有个情况就是 Subagent 完成也给我哐哐弹。最初硬编码了 SUBAGENT_TYPES = ["general", "explore"];后来发现 actor.preStop / actor.postStop 的 input 里有 mode: "subagent" | "peer"。于是就做了个计数器
最后通知到时候带上 Session 名字,折腾了一圈 直接 sqlite3 ~/.local/share/mimocode/mimocode.db "SELECT title FROM session WHERE id = '$SESSION_ID'"
完整代码放在
https://github.com/est/snippets/blob/master/mimocode-hooks/notify-done.ts
复制到 ~/.config/mimocode/hooks/ 就可以试试效果
Comments