Skip to content
Dormon's Hideaway
Go back

给 Claude Code 做桌面状态灯

来源:X @eternityspring

给 Claude Code 配一块桌面状态灯,将”它在想、它在干活、它干完了”这三种状态从终端日志移到桌面上,用红黄绿灯直接显示 [0]。整条链路是:Claude Code 的 Hook 触发 hook-client.mjs,把状态发给本机 TCP 端口;常驻的 serial-bridge.mjs 收到后,通过 USB 串口驱动 Arduino UNO 点亮三色灯模块 [0,1]。代码开源在 agent-light 仓库,主要文件包括 serial-bridge.mjs、hook-client.mjs、lib/commands.mjs(把状态名转成灯光命令)和 claude-settings-snippet.json(Hooks 配置片段)[0,1]

硬件与协议:Arduino 只负责”听懂命令”

硬件需要 Arduino UNO(或兼容板)、引脚为 GND/R/Y/G 的三色灯模块、杜邦线和 USB 数据线 [0]。UNO 的主控是 ATmega328p,提供 14 个数字引脚;板上的 ATmega16U2 或 CH340G 芯片负责在电脑上虚拟出一个 USB 串口 [2]。接线三对:D5→绿灯、D6→黄灯、D7→红灯,GND→灯模块的 GND [0]

Arduino 端程序只监听串口命令并控制灯 [0]。命令是纯文本,波特率 9600,例如 G:on(绿灯常亮)、Y:blink:250(黄灯每 250ms 闪一次)、R:onY:off [0]。仓库里定义了 idle、thinking、running 等命名状态,由 lib/commands.mjs 转换成灯光命令 [0,1]。因为是文本协议,用 Arduino IDE 的串口监视器发几条命令,就能验证硬件是否正常 [0]

兼容板需要注意:山寨/兼容板多用 CH340 芯片,需要手动安装驱动,否则电脑识别不出串口;原装板用 ATmega16U2 微控制器刷 USB 转串口固件,不需要 [4,6]

为什么不能”每次 Hook 开一次串口”:DTR 复位是设计不是故障

最先想到的方案是:Claude Code 每次触发 Hook,就打开串口发一条命令 [0]。但 UNO 打开串口时板子会自动重启 [0]。这是刻意设计:UNO 的串口芯片 DTR 引脚经过一个 100nF 电容接到 ATmega328p 的复位引脚,计算机发出 DTR 低电平时,复位端得到一个足够长的脉冲,芯片就复位了 [2]。这个电路的设计初衷是免手动复位烧录——Arduino IDE 点击上传时先触发复位,让芯片进入 bootloader,再写入程序 [2]

多数串口软件(串口调试助手、自写程序)在打开端口时会自动控制 RTS 与 DTR 信号 [3],因此”打开串口”往往等于”复位一次”;实测中第一次打开串口就会复位,除非用 stty -hupcl 之类手段保持 DTR 状态 [8]。烧录工具 avrdude 也正是靠翻转 RTS 电平把板子带进 bootloader 的 [7]

所以每个 Hook 都重新开一次串口,Arduino 会被反复复位,灯光不稳定甚至延迟 [0]。桥接结构是这套复位电路决定的架构要求。

桥接:把”发状态”和”占串口”拆成两件事

稳定方案是将串口交给一个常驻进程独占:serial-bridge.mjs 一直占用 Arduino 串口,Hook 只需把状态发给本地 TCP 端口 [0]。桥接启动时会自动探测 Arduino 串口,也可以手动指定(如 /dev/cu.usbmodem832101[1],并且只需 Node.js 环境、没有第三方依赖 [1]

独占串口有条件:启动桥接前必须先关掉 Arduino IDE 的串口监视器 [1]——串口同一时间通常只能被一个程序占用,监视器不关,桥接就抢不到端口 [0,46,49]。常驻方案也有不足:电脑休眠后 Arduino 会断开,唤醒时可能在另一个端口重新出现 [48];端口一旦”锁死”,常见恢复手段是拔掉 USB 线重插 [43,46]。桥接程序是否有自动重连逻辑未见说明 [0],长时间挂机后灯可能停在旧状态,需要在桥接端自行补上重连处理。

Claude Code 端:Hook 事件与配置层级

Claude Code 的 Hooks 是事件驱动的脚本,在生命周期固定点被调用 [13]。官方支持的事件远不止这里用到的四个:除 UserPromptSubmit、PreToolUse、PostToolUse、Stop 外,还有 SubagentStop、Notification、SessionStart、PermissionRequest 等,总共约 30 个 [12,14]。触发时机分别是:PreToolUse 在工具执行前、PostToolUse 在工具完成后、Stop 在主代理结束时 [12,15]。每次触发,Hook 会收到 JSON 输入,包含 session_id、hook_event_name、tool_name、tool_input 等字段 [14,16]——也就是说脚本能拿到 prompt 和工具入参的原文,日志里不要落盘敏感内容 [14]

状态映射是:UserPromptSubmit→thinking(黄灯闪)、PreToolUse→running(红灯闪)、PostToolUse→回到 thinking、Stop→idle(绿灯常亮)[0,1]。这套映射放进项目级 .claude/settings.json,就只对当前项目生效 [0];因为配置按层级合并——用户级 ~/.claude/settings.json 对所有项目生效,项目级只对当前项目,企业托管级(managed)优先级最高,数组字段在层级间拼接而非互相覆盖 [32,33]。反过来,如果想全局生效,把片段挪到用户级即可 [1,32]

多会话:从”最后一条命令”到状态聚合

当前实现是”最后一次状态生效”:多个会话配置了同一套 Hook 时,它们都向同一个桥接发状态,灯显示最后收到的那个 [0]。更严谨的聚合版本可以做成:只要任一会话 running 就红灯,否则只要任一会话 thinking 就黄灯,全部 idle 才绿灯;这需要 Hook 客户端把每个会话的状态单独记下来 [0]。Hook 的 JSON 输入本身就带 session_id,按会话区分状态是可行的 [14]

想区分”等待授权""需要输入”这类更细的状态,官方还有 Notification、PermissionRequest 等事件可用 [12,14,15]——其他状态灯项目正是这么扩展的,把权限请求、计划审批映射成独立的”需要输入”灯效 [54]

常见问题

这套链路把不可见的软件状态变成桌面实体反馈:Claude 思考时黄灯闪、执行工具时红灯闪、停下时绿灯亮 [0]。顺着 Hook 链路,终点还可以换成其他硬件——ESP32 灯环走 BLE 无线、支持 BLE 的台灯、或者用语音播报状态 [60,54,62]。一块 UNO 和三色灯即可将 AI 编程时看不见的思考与执行变成桌上看得见的灯 [0]

参考来源

  1. 素材原文(见文首来源链接)
  2. GitHub - eternityspring/agent-light: Claude Code status light system · GitHub
  3. Arduino Uno主板介绍 - emakefun文档中心
  4. CH340打开串口一瞬间DTR和RTS变化
  5. 我的Arduino Uno从来都识别不出来,就好像我买了个假的或者坏掉的 …
  6. USB 转串口芯片CH340
  7. Arduino Uno R3 CH340 驱动安装3 步法:从设备管理器到稳定烧录
  8. Change Arduino auto-reset via DTR/RTS/CTS to allow direct reset connection · Issue #1262 · avrdudes/avrdude · GitHub
  9. Configure serial port to leave DTR on to avoid resetting …
  10. Soft reset using DTR on Uno - Programming
  11. auto reset an Arduino using ftdi - DTR signal stays low and …
  12. DTR Off blocks USB serial receive - Teensy Forum - PJRC
  13. claude-code-hooks/.claude/hooks/HOOKS-README.md at main · shanraisshan/claude-code-hooks · GitHub
  14. Claude Code Hooks in 2026: A Production Playbook (PreToolUse, PostToolUse, Stop, SubagentStop) - Totalum Blog
  15. Claude Code Hooks (2026): Block Claude Reading .env + 30 Hook Events, JSON Input, Exit Codes
  16. Claude Code Hooks
  17. Claude Code Hooks - Verdent Guides
  18. Claude Code Hooks Complete Guide - Deterministic …
  19. Claude Code Hooks (2026): Block Claude Reading .env + 30 …
  20. Claude Code Hooks (2026): Setup Guide with Working Examples
  21. Claude Code Hooks Examples: 12 Copy-Paste Automation …
  22. Claude Code Hooks: Complete Guide to All 30 Lifecycle Events
  23. AI-Coding-Guide-Zh/docs/claude-code/11-企业实战完整指南.md at main · KimYx0207/AI-Coding-Guide-Zh · GitHub
  24. 3万字硬核拆解 Claude Code:从入门到工程化落地 - charyGao - 博客园
  25. Claude Code 最佳实践指南
  26. 别再手动重复配置了!Claude Code .claude 目录一劳永逸,团队协作效率翻倍-腾讯云开发者社区-腾讯云
  27. 一文搞懂Claude Code 四大隐藏机制:让AI 记住项目、守住纪律
  28. 7.5 自主编码实践与案例 | Claude 技术指南 | Claude Guide
  29. claude-code-best-practice/best-practice/claude-settings.md …
  30. Settings - Claude Code
  31. Claude Code Features and Settings Reference 2026
  32. Configure Claude Code to Power Your Agent Team
  33. Claude Code settings - Claude Code Docs
  34. Where Is Claude Code settings.json? 5 Config Files, 1 Priority …
  35. 给Claude Code 做一个桌面状态灯:Arduino 三色灯接入实战
  36. Blackmagic 3G-SDI Shield for Arduino
  37. Arduino自定义通信协议解析
  38. Issues with serial data buffering · Issue #12 · Twilight-Logic …
  39. Parsing AT Commands via Serial Returns Results out of …
  40. [solved] Commands over Serial not working “unknown …
  41. Problem with Arduino Serial Communication
  42. [SOLVED] Arduino resetting when disconnected (via Serial …
  43. 可以,用Arduino Uno當USB-to-Serial橋接看ESP32-CAM的 …
  44. USB Serial Port Locking Up - General Guidance
  45. Arduino Uno still boots and runs but no serial …
  46. Arduino 崩溃或挂起的7 种方式及如何防止原创
  47. serial monitor won’r release port · Issue #1570 · Sloeber/arduino-eclipse- …
  48. Serial port problems for Arduino Micro [Solved] - General Guidance
  49. Resuming Serial Connection after sleep on Arduino M0
  50. Having to disconnect and reconnect Arduino every time I connect to it in …
  51. Serial Monitor “disconnects” during deep sleep - PlatformIO Community
  52. “while (!Serial);” USB Disconnect Issue - Teensy Forum - PJRC
  53. GitHub - eternityspring/agent-light: Claude Code status light system · GitHub
  54. Claude Code 完整指南(四):Hooks(自动化事件触发)
  55. Someone turned an LED light into a live Claude Code status indicator, and so can you
  56. Desktop Notifications for Claude Code: Never Miss a Completed Task | The road
  57. Build a Hardware Companion for Claude Code Using Anthropic’s BLE API
  58. Automate actions with hooks - Claude Code Docs
  59. Voice Notifications for Claude Code - Roman Imankulov
  60. hacker-news-summarizer/output/hacker_news_summary_2025-07-01.md at main · yuxiaopeng/hacker-news-summarizer · GitHub
  61. 10 分钟教会你制作专属「Claude Code 状态灯」
  62. 给Claude Code 做一个桌面状态灯:Arduino 三色灯接入实战
  63. Claude Code 三色硬件状态灯太麻烦?教你用星际/魔兽语音或RGB 键盘 …
  64. 我给Claude Code 装了个“红绿灯”,再也不怕忘记确认状态了

Share this post:

Previous Post
热核代码审查:一份提示词
Next Post
Pi Agent 五大模块与极简循环