微光黑客松 已完成

Buddy 桌面灵宠

把 Codex / Claude / Enter 的运行状态变成桌上的 64×64 像素小宠物

by 郭霖 Hardware Hacker · AI & NLP · Utility Tool

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 拥有自己的桌宠人格
  • 断线重连与离线缓存优化,适合长时间桌面摆放
  • 更细粒度的任务阶段:审批、构建、测试、部署
  • 设备 / 密钥 / 宠物包管理控制面板

链接

更新记录

  1. 黑客松后:开源固件和 npm 包正式上线

    黑客松结束后把两个公开入口整理好推出去: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 社区生态——让更多人能定制自己的桌宠。

  2. 黑客松演示:桌上那只宠物比 PPT 更能说话

    演示现场把 M5StickS3 摆在桌上,用 buddy codex 跑了一个真实任务。Thinking 状态下宠物蜷缩,有人问”它在干嘛”——答:”在想”。Waiting 状态宠物停下来对着大家,有人笑了。Done 状态宠物起舞,全场能看到。这比任何 PPT 动画都更直接。评委问的第一个问题不是”这怎么做的”,而是”在哪买”。

  3. 修复重连后状态滞留和 Waiting 误判问题

    现场测试发现两个 bug。一:MQTT 断线重连后设备偶尔停在旧状态,不更新。根因是设备没有校验 updated_at,接受了比当前更旧的 snapshot。修复:设备端缓存上一条 snapshot 的 updated_at,收到更旧的消息直接丢弃。二:部分工具执行阶段(尤其是长 bash 命令)被误判成 Waiting。修复:Waiting 状态的判定逻辑单独抽出来,只在 requires_user 为 true 时触发,不再由工具执行状态覆盖。

  4. 官网文案和 npm 安装路径打磨

    今天把官网文案和安装路径统一了一遍。首页核心一句话定为:”Your AI agent's mood, on your desk.”——足够直白,不需要解释背景。安装命令收敛成三步:npm install -g hibuddy / buddy init --key xxx / buddy codex。减少用户第一次体验时需要理解的概念。buddy whoami 和 buddy status 这两条调试命令加到文档里,方便没有硬件的用户也能验证 CLI 是否在工作。

  5. pet_pack_builder:Python 工具生成像素动画资产

    固件里的像素资产用 Python 脚本从源帧生成。今天把 pet_pack_builder 整理成可重复运行的工具:输入 64×64 的 PNG 帧序列,输出 C 头文件格式的 uint16 颜色数组,直接编译进固件。顺带搭了一个预览输出,方便在编译前就能看到动画效果。这个工具之后想开放出来,让社区能做自己的 pet pack。

  6. 三屏设计:Pet / Overview / Info

    设备端加了三个可切换界面。Pet 屏是默认界面,占全屏显示宠物动画。Overview 屏显示当前 session_states 列表、token 计数、requires_user 警示。Info 屏显示设备 ID、固件版本、Wi-Fi 信号、MQTT 连接状态。三屏通过侧边按钮切换。设计原则:Pet 屏是 ambient display,看一眼就够;Overview 和 Info 是需要时才切换的 detail 层,不打扰默认体验。

  7. 宠物加上 mood、energy、focus 本地属性

    只显示状态还不够”活”。今天给设备端加了本地属性:mood 影响表情(嘴角弧度、眼睛形状),energy 影响动作幅度(步伐大小、呼吸深度),focus 影响停顿频率。关键设计决策:这三个属性不从云端下发,设备根据收到的 snapshot 自主缓慢演化。Thinking 状态持续越久,energy 越低;Done 触发后 mood 短暂拉满。这样动画有了记忆感,不会每次状态切换都归零。

  8. Codex 代理和 Claude hooks 两条路径打通

    今天补上两条入口: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) 六个状态都能稳定到达设备端。

  9. 配对流程从手工写参数改成 buddy init

    之前设备端 MQTT 参数需要手动写入 ini 文件,演示时非常容易出错。今天把流程改成 buddy init --key buddy_xxx:CLI 侧用 key 调控制平面 API 拿到 bootstrap 配置(包含 mqttBrokerUrl / mqttUsername / mqttToken / mqttClientId / mqttTopic / activePet),设备侧通过配对码拿同一份运行配置。这样现场换设备也能走同一套流程,不需要手动传参。

  10. M5StickS3 固件首次点亮,Wi-Fi 配网跑通

    固件今天跑通了 Wi-Fi 配网(on-device portal)和第一版 Pet 屏。屏幕不大,动画不能贪多:先做呼吸、眨眼、轻微位移和 Waiting 状态的停顿。Busy 状态下宠物比 Idle 明显活跃,Waiting 状态停住不动——这两个对比放在桌面上差异已经足够大,不需要做得更复杂。PlatformIO 环境配置花了大半天,主要卡在 ESP32-S3 的 partition scheme 上。

  11. 确定 MQTT snapshot 协议而不是事件流

    消息格式在 snapshot 和增量事件流之间纠结了一天。最终选 snapshot 的原因很现实:小设备掉线、重连、漏消息都很常见,增量流在这种情况下会导致设备状态飘移。Snapshot 让设备随时能恢复到最新状态,不管中间漏掉了多少消息。v1 协议字段定为:version / updated_at / pet_state / session_states / requires_user / total_tokens / today_tokens。设备只消费自己需要的部分,其余字段忽略。

  12. 把 agent 状态从终端里捞出来

    先把问题拆清楚:Buddy 不直接解析一整段混乱日志,而是让 CLI 把 Codex / Claude / Enter 的运行阶段归一成 snapshot。先接通了 idle、thinking、busy、done 四个基本状态,设备端可以稳定收到状态变化。这个版本还很粗,但方向对了:桌宠不需要知道所有细节,只需要把关键状态说清楚。

  13. 为什么选 M5StickS3 和像素宠物

    考虑过纯软件方案:系统托盘图标、桌面 widget、通知推送。但这些都在同一块屏幕上竞争注意力。选 M5StickS3 是因为它是一个真实的独立物体,有物理存在感。135×240 的小屏幕只够放一只像素宠物,反而是优点:信息密度低,状态判断在视觉外设皮层完成,不打断主显示器上的工作流。

  14. 问题定义:审批提示埋在 200 行工具输出里

    一开始就想清楚 Buddy 不是什么:不是另一个监控面板,不是终端美化工具。它要解决一个非常具体的痛点——你让 Codex 跑一个任务,它在另一个标签页里卡在等待审批,你 10 分钟后才发现。Buddy 的核心不是”让信息更丰富”,而是”让关键节点不再被淹没”。把这个问题讲清楚之后,技术选型就很自然地收敛到了:硬件 + 像素宠物。