Buddy 桌面灵宠
把 Codex / Claude / Enter 的会话状态,变成桌上一只会蜷缩、会奔跑、会踉跄、也会起舞的 64×64 像素小宠物。
审批提示埋在 200 行工具输出下面,你 10 分钟后才发现。这是 Buddy 想解决的那个具体问题。
AI agent 已经像一个真正的队友,但它的状态依然藏在终端滚动日志里。Buddy 不做监控面板,它做一个更低压力、更有温度的存在感:你不用切屏,也不用死盯日志——桌角那只小生物蜷缩着,说明它在思考;猛跑起来,说明工具链正在执行;停下来用眼神望向你,说明它在等你拍板。
它怎么工作
Codex / Claude / Enter
│
buddy CLI(监听会话状态)
│
MQTT snapshot(v1 协议)
│
M5StickS3 固件(HiBuddy)
│
135×240 像素宠物屏幕
Buddy 由两部分组成:桌面侧的 hibuddy CLI 和设备侧的 HiBuddy 固件。
CLI 把 agent 的会话阶段归一成稳定的 snapshot(版本号 + 时间戳 + pet_state + session_states + requires_user + token 计数),通过 MQTT 推送到设备。固件收到 snapshot 后驱动宠物动画、Overview 总览页和 Info 设备页三个界面切换。
六种状态,六种表情
| 状态 | 触发条件 | 宠物表现 |
|---|---|---|
| Thinking | Agent 正在推理 | 宠物蜷缩,眼神迷离 |
| Busy | 工具链正在执行 | 宠物全速奔跑 |
| Waiting | 需要人工审批或输入 | 宠物停住,直视你 |
| Error | 任务失败 | 宠物踉跄摔倒 |
| Done | 任务完成 | 宠物短暂起舞庆祝 |
| Idle | 无任务 | 宠物慢速呼吸,小睡 |
宠物的内心世界
宠物本地维护三个属性:mood(影响表情)、energy(影响动作幅度)、focus(影响停顿频率)。这些属性不需要每次从云端下发,设备根据接收到的 snapshot 自主缓慢演化,动画因此有了自然的连续感。
动画系统包含:微移动、随机停顿、状态变体、抖动、面朝下睡眠行为。
快速上手
安装 CLI:
npm install -g hibuddy
配对设备(需要 Buddy 硬件):
buddy init --key buddy_xxx # 从控制面板拿到 key
buddy whoami # 验证配置
接入 Codex:
buddy codex
接入 Claude:
buddy install-claude-hooks # 写入 Claude Code hooks
buddy claude # 启动并监听
本地调试(无需硬件):
buddy status # 查看最新 snapshot 内容
没有硬件也能用:把 output 模式设为 local,CLI 会把 snapshot 写到本地文件,方便开发调试。
CLI 完整命令
| 命令 | 说明 |
|---|---|
buddy init --key <key> |
初始化并配对设备 |
buddy whoami |
查看当前配置 |
buddy codex |
代理 Codex 会话 |
buddy install-claude-hooks |
安装 Claude/Enter hooks |
buddy remove-claude-hooks |
彻底移除 hooks |
buddy status |
查看最新 snapshot |
Snapshot 协议(v1)
{
“version”: 1,
“updated_at”: “ISO8601”,
“pet_state”: 0,
“session_states”: [],
“requires_user”: false,
“total_tokens”: 0,
“today_tokens”: 0
}
pet_state 枚举:idle(0) / thinking(1) / busy(2) / waiting(3) / error(4) / done(5) / sleep(6)
设备侧把 Buddy 视为黑盒:消费 snapshot,不解析 Codex/Claude 的内部 payload,不重建会话优先级逻辑。
硬件规格
- 主控:M5StickS3 / ESP32-S3
- 屏幕:135×240 竖屏
- 传感器:IMU、电池
- 固件:PlatformIO + Arduino,C / C++ / Python 混合
- 像素资产:Python pet_pack_builder 生成动画 artifacts
技术栈
| 层 | 技术 |
|---|---|
| 桌面入口 | Node.js CLI(TypeScript) |
| 通信 | MQTT,snapshot 广播 |
| 设备 | M5StickS3 + PlatformIO |
| 像素资产 | 64×64 pet pack + Python builder |
这艘船代表什么
Buddy 是一盏很小的灯。它把复杂工具的运行状态压缩成一个人能自然感知的像素生命体:等待时不再焦虑,完成时有明确反馈,失败时第一时间察觉。
它代表的是”人类智慧之光”的一个很小但真实的切面:让技术不只强大,也更可感知,更靠近人。
下一步
- 更多 pet pack,让不同 agent 拥有自己的桌宠人格
- 断线重连与离线缓存优化,适合长时间桌面摆放
- 更细粒度的任务阶段:审批、构建、测试、部署
- 设备 / 密钥 / 宠物包管理控制面板
链接
- 官网:hibuddy.fun
- 开源固件:github.com/guolin/HiBuddy
更新记录
-
黑客松结束后把两个公开入口整理好推出去:HiBuddy 固件推上 GitHub(github.com/guolin/HiBuddy),hibuddy CLI 发布到 npm(npm install -g hibuddy)。固件 README 写清楚了 PlatformIO 环境搭建、platformio.local.ini 配置方式,以及安全注意事项(不要 commit 真实 API key 和 bearer token)。下一步要做的是 pet pack 社区生态——让更多人能定制自己的桌宠。
-
演示现场把 M5StickS3 摆在桌上,用 buddy codex 跑了一个真实任务。Thinking 状态下宠物蜷缩,有人问”它在干嘛”——答:”在想”。Waiting 状态宠物停下来对着大家,有人笑了。Done 状态宠物起舞,全场能看到。这比任何 PPT 动画都更直接。评委问的第一个问题不是”这怎么做的”,而是”在哪买”。
-
现场测试发现两个 bug。一:MQTT 断线重连后设备偶尔停在旧状态,不更新。根因是设备没有校验 updated_at,接受了比当前更旧的 snapshot。修复:设备端缓存上一条 snapshot 的 updated_at,收到更旧的消息直接丢弃。二:部分工具执行阶段(尤其是长 bash 命令)被误判成 Waiting。修复:Waiting 状态的判定逻辑单独抽出来,只在 requires_user 为 true 时触发,不再由工具执行状态覆盖。
-
今天把官网文案和安装路径统一了一遍。首页核心一句话定为:”Your AI agent's mood, on your desk.”——足够直白,不需要解释背景。安装命令收敛成三步:npm install -g hibuddy / buddy init --key xxx / buddy codex。减少用户第一次体验时需要理解的概念。buddy whoami 和 buddy status 这两条调试命令加到文档里,方便没有硬件的用户也能验证 CLI 是否在工作。
-
固件里的像素资产用 Python 脚本从源帧生成。今天把 pet_pack_builder 整理成可重复运行的工具:输入 64×64 的 PNG 帧序列,输出 C 头文件格式的 uint16 颜色数组,直接编译进固件。顺带搭了一个预览输出,方便在编译前就能看到动画效果。这个工具之后想开放出来,让社区能做自己的 pet pack。
-
设备端加了三个可切换界面。Pet 屏是默认界面,占全屏显示宠物动画。Overview 屏显示当前 session_states 列表、token 计数、requires_user 警示。Info 屏显示设备 ID、固件版本、Wi-Fi 信号、MQTT 连接状态。三屏通过侧边按钮切换。设计原则:Pet 屏是 ambient display,看一眼就够;Overview 和 Info 是需要时才切换的 detail 层,不打扰默认体验。
-
只显示状态还不够”活”。今天给设备端加了本地属性:mood 影响表情(嘴角弧度、眼睛形状),energy 影响动作幅度(步伐大小、呼吸深度),focus 影响停顿频率。关键设计决策:这三个属性不从云端下发,设备根据收到的 snapshot 自主缓慢演化。Thinking 状态持续越久,energy 越低;Done 触发后 mood 短暂拉满。这样动画有了记忆感,不会每次状态切换都归零。
-
今天补上两条入口:Codex 走 buddy codex(包装器模式),Claude / Enter 走 buddy install-claude-hooks(写入 hooks 文件)。两边事件模型不一样:Codex 走 stdout 拦截,Claude hooks 走文件写入触发。但 CLI 内部把它们归一成同一套状态机,最终都推到同一个 MQTT topic。现在 thinking(1) / busy(2) / waiting(3) / error(4) / done(5) / idle(0) 六个状态都能稳定到达设备端。
-
之前设备端 MQTT 参数需要手动写入 ini 文件,演示时非常容易出错。今天把流程改成 buddy init --key buddy_xxx:CLI 侧用 key 调控制平面 API 拿到 bootstrap 配置(包含 mqttBrokerUrl / mqttUsername / mqttToken / mqttClientId / mqttTopic / activePet),设备侧通过配对码拿同一份运行配置。这样现场换设备也能走同一套流程,不需要手动传参。
-
固件今天跑通了 Wi-Fi 配网(on-device portal)和第一版 Pet 屏。屏幕不大,动画不能贪多:先做呼吸、眨眼、轻微位移和 Waiting 状态的停顿。Busy 状态下宠物比 Idle 明显活跃,Waiting 状态停住不动——这两个对比放在桌面上差异已经足够大,不需要做得更复杂。PlatformIO 环境配置花了大半天,主要卡在 ESP32-S3 的 partition scheme 上。
-
消息格式在 snapshot 和增量事件流之间纠结了一天。最终选 snapshot 的原因很现实:小设备掉线、重连、漏消息都很常见,增量流在这种情况下会导致设备状态飘移。Snapshot 让设备随时能恢复到最新状态,不管中间漏掉了多少消息。v1 协议字段定为:version / updated_at / pet_state / session_states / requires_user / total_tokens / today_tokens。设备只消费自己需要的部分,其余字段忽略。
-
先把问题拆清楚:Buddy 不直接解析一整段混乱日志,而是让 CLI 把 Codex / Claude / Enter 的运行阶段归一成 snapshot。先接通了 idle、thinking、busy、done 四个基本状态,设备端可以稳定收到状态变化。这个版本还很粗,但方向对了:桌宠不需要知道所有细节,只需要把关键状态说清楚。
-
考虑过纯软件方案:系统托盘图标、桌面 widget、通知推送。但这些都在同一块屏幕上竞争注意力。选 M5StickS3 是因为它是一个真实的独立物体,有物理存在感。135×240 的小屏幕只够放一只像素宠物,反而是优点:信息密度低,状态判断在视觉外设皮层完成,不打断主显示器上的工作流。
-
一开始就想清楚 Buddy 不是什么:不是另一个监控面板,不是终端美化工具。它要解决一个非常具体的痛点——你让 Codex 跑一个任务,它在另一个标签页里卡在等待审批,你 10 分钟后才发现。Buddy 的核心不是”让信息更丰富”,而是”让关键节点不再被淹没”。把这个问题讲清楚之后,技术选型就很自然地收敛到了:硬件 + 像素宠物。