
CC Watch:把 Claude Code 戴在手腕上——给 AI Agent 做一块佳明表盘
上一篇里,我把 Claude Code 会话桥接进了我天天在用的每一个聊天 app,离开电脑不再意味着离开工作。但那套系统还剩一个盲区:连手机都不方便掏的时刻。游泳。开车。开会时掏手机,等于当面宣布“我已经不在听你说话了”。
而这些场合我都戴着表。一块佳明 Descent G2——潜水电脑表,因为我潜水。它有开发者 SDK。你已经猜到接下来发生了什么。
这篇讲 CC Watch:一块抬腕就能看到我整个 Claude Code 世界的表盘——订阅窗口还剩多少额度、有没有 agent 正在干活,以及所有人第一眼都会先问的那个——一只像素蟹,agent 忙的时候它敲鼓,闲的时候它冲你眨眼。它从空项目到提交 Connect IQ 商店用了四天,顺便教会了我“怎么调试一块绑在手腕上的屏幕”——学到的比预想的多。

表盘,刻意做得很密:顶部日期天气;中间两行 Claude 订阅窗口(5H 12% 3H33M——5 小时窗口用了 12%,3 小时 33 分后重置;7D 64% 2D13H——周窗口同理);边缘一圈健康数据——血氧、睡眠、身体电量、VO2max、步数;一颗数据链路灯(绿=新鲜,红=过期);还有那只蟹。
不做通知,是故意的
把 agent 搬上手表,最顺手的做法是通知——手机收到什么,手腕上震什么。“任务完成,来拍板”那最后一下推送我本来就有,那一刻它刚刚好。
但除那一刻之外全是错的。一支 agent 舰队会产出大量中间消息,一块为中间消息震个不停的表,下场是被摘下来。更糟的是整天往表上灌通知流会谋杀电池——在一块一周一充的潜水表上,这是一票否决。
所以 CC Watch 从不接收任何东西。它只拉:后台任务每十分钟醒一次,发一个 HTTPS 请求,存下一小坨 JSON,回去睡觉。表盘渲染的永远是最后那坨数据。可一瞥、零打扰、便宜到在电量曲线里找不到它。
设计哲学和 bridge 一脉相承:agent 汇报,我扫一眼。 手腕上没有任何东西向我索要注意力;它只负责提前答好我正要问的问题——有活在跑吗?今晚还有额度干一场大重构吗?
管线:一个端点、十分钟、390 个像素
数据路径很短,因为大部分本来就有:
Descent G2(Monkey C 后台服务,每 10 分钟)
└── HTTPS GET https://<我的云主机 IP>/watch?token=…
└── Mac mini 上的 hub 服务(经 SSH 反向隧道)
├── Claude Code statusline 缓存 → 用量窗口
├── tmux 抓帧探测 → 各项目忙/闲
└── 佳明云端睡眠快照 → (对,你没看错——见下文)
hub 就是驱动我 web 驾驶舱的那个小 aiohttp 服务;/watch 只是多出来的一条路由,把手表要的一切压平成一小份 JSON。它用独立 token 鉴权——和 web 密码门分开,表 token 就算泄了,也只能读到一个用量数字,别的什么都干不了。
有两个约束让这事没有听起来那么顺:
佳明要求后台请求必须 HTTPS,而我的端点是一个裸 IP——域名还卡在 ICP 备案的炼狱里(中国自托管的故事,值得单开一篇)。解法是我这周之前根本不知道存在的东西:Let’s Encrypt 现在给 IP 地址签证书了。 acme.sh 直接为裸 IP 申一张证书,定时器每六天自动续。没有域名,HTTPS 有效,手表满意。
屏幕 390×390,而我用满了每一格。 每个元素都是对着圆形表圈逐像素排的——这也是为什么商店提交表单问“支持自动迁移到新机型吗?“时,我选了否。在这么密的表盘上,未来某块 416×416 屏幕上”大致正确“的布局,意思就是错。
那只蟹
一盘数字能回答问题,但你得读它。我想让“忙/闲”这个答案是前注意的——在意识反应之前就被看见,就像余光里的移动。
于是:一只逐帧画的像素蟹,住在表盘下方。任何项目忙碌时(表盘会亮 ✻ 和计数),蟹轮流敲钳——左、右、左、右,一秒一拍。全部空闲时,它坐在那儿偶尔眨眨眼。我老婆第一次看到忙碌动画的评语,原话,“哇塞,外星人在敲锣打鼓”——我选择把这理解为前注意设计的成功,而不是对我像素画功底的评价。

吉祥物。隔着半个房间一眼:钳子在动=agent 在干活,眨眼=天下太平。最外圈是秒针指示——一颗只在高功耗模式下才走的橙点,后来意外成了调试工具。
这只蟹还上了本周最便宜的一课。真机上它看起来一动不动——模拟器里动画明明正常,我于是开始追渲染 bug。根本没有 bug。表盘只在高功耗窗口(抬腕后的几秒)才有每秒重绘,其余时间一分钟一帧;而我每次“目击 bug”时,busy 恰好是零——一只空闲的蟹本来就该坐着不动。修复是认识论层面而非技术层面的:外圈那颗秒点现在能立刻告诉我此刻处于哪种功耗模式,而我再也不凭记忆诊断动画问题了。先观测,再立论。
午饭前迭代五版
模拟器会撒谎,温柔地撒。Descent G2 模拟器把表盘渲染在一块完美的白底圆盘上;真表是一块更暗的 OLED,藏在弧面玻璃后,戴在一只晃动的手腕上,这点差别足以生吞设计。7 月 8 日那天是这么过的:v5.0 侧载上表 → 边缘太挤 → v5.1 → 秒环怼上表圈 → v5.2 → 整圈几何重排(圆弦数学,不是目测)→ v5.3 →“哇塞,外星人在敲锣打鼓”→ v5.4,提审候选。五个版本,一天,每一版都是一个 .prg 文件过数据线拷上表。
物理迭代环无可替代。到最后我的规矩是:模拟器管逻辑,手腕管设计,任何没抬过真胳膊就拍的像素决定都只算草稿。
靠缺席撒谎的 API
这次构建里最好的故事,是睡眠那一格。
表盘要显示昨晚睡眠。佳明 Connect IQ SDK 提供 Complications API——一张类型化的数据目录,列着手表能喂给表盘的数据:心率、身体电量、VO2max,以及,文档写着,睡眠时长。我的代码按官方示例的写法、带着防御性检查去请求 COMPLICATION_TYPE_SLEEP_TIME。编译通过。运行正常。显示 --,永远。
先查的都是惯犯:也许值回来是 Float,我的 instanceof Number 把它扔了(几周前真踩过——Monkey C 的数值有四种类型,instanceof Number 会默默拒掉其中三种)。加固了。还是 --。也许单位是秒不是分钟。兜住了。还是 --。
然后我做了本该第一步就做的事:去读这台设备自己的 API 清单——每个佳明型号都带一份 XML,写明它实际实现了什么。Descent G2 的 complication 枚举有 37 项。身体电量:在。血氧:在。恢复时间、呼吸率、压力、训练状态:都在。所有睡眠相关的项:缺席。 不是坏了——是根本没有。这块表每晚记录我的睡眠,在手机 app 里展示,同步到佳明云端……唯独不把它开放给本机型的表盘。新旗舰有。我这块没有,再正确的代码也改变不了。has :COMPLICATION_TYPE_SLEEP_TIME 从头到尾都在返回 false;我的防御性检查忠实地掩盖了一个平台缺口。
绕道方案很诚实,也很荒诞:Mac mini 每半小时登录佳明云端,取回我的手表上传的睡眠数据,交给 hub,再由 hub 喂回给当初测量它的那块表。我的睡眠数据如今要途经两个数据中心,才能完成这趟零米的旅行。
(给想抄作业的人一颗中国区专属地雷:流行的 garminconnect Python 库对中国区账号只支持一半——SSO 在 garmin.cn 成功,接着却拿国际域名换 token,卡死在墙外。直接用更底层的 garth,configure(domain="garmin.cn"),通。token 有缓存,密码只碰一次。)
调试一块 attach 不上去的屏幕
周中,数据链路灯红了两个小时,我获得了远程调试手腕的实战机会。nginx 日志说手表每十分钟准时来取 /watch,状态 200,像钟表一样规律。手表说数据过期了。两边都说的是真话:请求成功了,而在手机的佳明代理和手表存储之间的某处,结果蒸发了。两小时后它自愈,再未复发。
你没法 tail -f 一块表盘。你能做的,是让表盘自带黑匣子:现在的版本在链路灯变红时会显示三个小小的诊断数字——手表自己看到的 HTTP 状态码、最后一次错误码、后台任务距上次唤醒的分钟数。下次红灯亮起,一张手腕照片就是一份完整的 bug 报告。为无法复现的故障做设计,因为它总会在你不看的那周复发。
从侧载到商店
头三天,CC Watch 是一个靠 USB 线传输的 .prg 文件——我自己够用,对别人毫无意义。商店化是一个独立的小工程:
- 把秘密从二进制里拿出来。 我的端点 URL 和 token 原本是编译期常量。商店版改从设置页读取(佳明的 Properties API),装好后在 Connect Mobile app 里就能填。
build_store.sh出一个 token 留空的商店包——我自己的侧载版保留烤死的便利。 - companion 开源。 没有端点的表盘毫无用处,所以参考服务开成了公开仓库:一个单文件、纯标准库的 Python 服务,读 Claude Code 本地的用量缓存,吐出
/watchJSON。不用 pip、没有框架——python3 ccwatch_companion.py加一个 token,任何 Claude Code 用户都能把表盘指向自己的机器。 - 商店材料:名字、分类(他们真有一个“Geek”分类,合理)、截图、以蟹为主角的宣传图。7 月 8 日 23:37 提交——不到两天过审。CC Watch 已在 Connect IQ 商店上架:蟹开始在别人的手腕上敲鼓了。
接下来
两件事,都已经在路上。
一块潜水表盘。 这块表本来就是潜水电脑,而愿意装我作品的朋友里一半是潜水员。同一套架构,不同的灵魂——顺便查清这个平台究竟把海洋的哪些数据开放给了表盘(我现在学会先读设备清单了)。
让 agent 把环闭上。 眼下表盘的“用户”除我之外都还只存在于理论中;商店上架后,真实用户意味着真实 bug 报告。计划是把反馈入口直接接进这个博客一直在写的那套系统:一条 bug 报告落地,一条消息唤醒一个 Claude Code 会话,会话对着代码库复现问题、起草修复,然后 ping 我的手腕要一个单词的批准。显示 agent 的表,变成批准 agent 工作的表。那才是我真正想写的那篇文章。
CC Watch 已上架 Connect IQ 商店,companion 服务在 GitHub。如果你以做表盘为生,并且对上文任何一处皱了眉——我和蟹都欢迎你的 bug 报告。