Claude Code硬件副屏DIY:3D打印外壳+状态机实现AI任务可视化
在 Claude Code 中执行后台长任务时,一个常见的痛点是将复杂作业提交到终端后便离开处理其他工作,几小时后回来发现光标仍在闪烁,表面一切正常,然而任务早在数十分钟前就卡在了某个确认环节——就这样无声地悬停,白白消耗了时间与算力。
系统通知理论上可以提醒,但前提是你恰好守在电脑前且未被其他消息刷屏。对于动辄运行几十分钟的后台进程,“后台静默卡死”确实是一个极易被忽视的盲区。
一、破局思路:实体状态指示灯
我制作了一个实体状态 Mini 副屏——采用 3D 打印外壳、HDMI 小屏及本地状态服务,通过红绿灯将 Claude Code 的运行状态实时映射到桌面上。
红灯 —— AI 全速运行,CPU/Token 处于高占用;
黄灯 —— AI 等待用户确认,任务卡在半路,这是最容易被忽略的状态;
绿灯 —— AI 空闲,任务已完成或尚未启动。
整套方案成本可控,复现门槛低。以下按硬件组装、软件状态机实现、前端展示的顺序展开讲解。
二、硬件选型与准备
1、Mini 显示器外壳
外壳无需自己从头建模,直接复用开源方案即可。在拓竹 MakerWorld 搜索 "Mocintosh 摸鱼小副屏",作者提供了两款尺寸:
| 尺寸规格 | 分辨率 | 打印耗时 | 耗材重量 |
|---|---|---|---|
| 2.8 英寸(推荐) | 640×480 | 约 4.4h | 161g |
| 3.54 英寸 | 960×640 | 约 4.8h | 179g |
个人倾向 2.8 英寸款,打印时间更短,且 640×480 分辨率对静态状态展示完全够用。
2、HDMI 显示屏
屏幕在某宝搜索 "HDMI 显示屏方案 2.8 寸麦金塔模型屏",需注意两点:
- 必须选择 HDMI 直驱方案,避免 SPI/I2C 驱动屏(需额外转接板,可能不兼容外壳);
- 注意屏幕排线方向——部分 FPC 排线从左侧出,部分从右侧出,需与外壳走线槽匹配。
避坑提示:macOS 对 640×480 这类非标准小屏支持一般,首次连接可能默认输出 1080p 导致黑屏。建议在系统设置中按住 Option 键点击“缩放”强制选择 640×480,或在 Windows 下先调好分辨率再切换。
三、组装与部署
1、安装驱动板
按图示安装即可,注意不要压到屏幕排线,用螺丝固定驱动板。
2、组装外壳
四、软件架构:三层状态机驱动
硬件只是载体,核心在软件架构。整体分为三层:
Claude Code (Hook) → monitor.js (状态机) → 浏览器前端 (副屏展示)
1、状态灯逻辑
三种状态直接对应红绿灯:
红灯 / running:AI 正执行工具或生成回复,算力满载;
黄灯 / awaiting:本轮输出结束,但不确定是任务完成还是下一轮思考的间隙;
绿灯 / idle:确认任务真正结束,进入空闲。
黄灯到绿灯的切换采用 3 秒倒计时缓冲。Claude Code 的 Agent 模式是“思考→工具→思考”循环,两轮之间会有短暂间隙。若直接切绿灯,指示灯会频繁闪烁。加入 3 秒阈值后,只有真正空闲才切为绿灯。
2、技术架构拆解
来看具体的实现层次:
- 第一层:在 Claude Code 中发送消息、Claude 执行工具、Claude 回答完毕——这三个时机自动触发脚本,将当前状态通过网络推送给本地服务。
- 第二层:本地服务(monitor.js)类似交通灯控制器,只负责管理三种颜色。收到“开始工作”信号 → 立即亮红灯,同时取消任何待处理的倒计时;收到“本轮结束”信号 → 亮黄灯,并启动一个 3 秒倒计时。3 秒内无新“开始工作”信号 → 切绿灯(任务结束);3 秒内出现新信号 → 取消倒计时,重回红灯继续作业。
- 第三层:浏览器页面每 250ms 轮询服务端“当前颜色”,拿到结果后同步给动画主题播放对应效果。
一句话总结:红灯干活,黄灯等待,绿灯可交互。
3、操作与使用
代码已开源至 GitHub:github.com/chenfengyan…
用户发送消息
│
├─ UserPromptSubmit hook → set-state.sh busy → 红灯
│
├─ PreToolUse hook → set-state.sh busy → 红灯(持续)
│ │
│ └─ 若工具为 AskUserQuestion / AskFollowupQuestion
│ → set-state.sh waiting (persistent) → 黄灯(持续,不倒计时)
│ └─ 等待用户回复后 → UserPromptSubmit 再次触发 → 回归红灯
│
├─ Stop hook → set-state.sh waiting → 黄灯(3 秒倒计时)
│ │
│ └─ 若 Claude 继续工作(多 turn)→ PreToolUse 再次触发 → 回归红灯
│
└─ Stop hook 触发后 3 秒内无新事件
↓
monitor.js 判定为 idle → 绿灯
- Hooks 通过 curl POST 推送到 monitor.js(不再依赖文件);
- monitor.js 在内存维护状态:收到 busy 立即取消倒计时;收到 waiting 根据 persistent 字段决定行为——普通 Stop 启动 3 秒倒计时,AskUserQuestion 则持续黄灯直到用户回复;
- 前端每 250ms 轮询 /api/status,严格跟随服务端状态,通过 postMessage 同步给 iframe 主题;
- 绿灯由服务端倒计时决定:前端无任何计时逻辑。
项目结构如下:
MyBetterDisplay/
├── start.sh # ⭐ 一键启动(首次运行执行此脚本即可)
├── stop.sh # 停止监控服务
├── install.sh # 安装 BetterDisplay 应用
├── index.html # 监控主页(主题切换器)
├── claude-status/
│ ├── monitor.js # HTTP 监控服务(端口 4242)
│ ├── set-state.sh # Hook 脚本(由 Claude Code 调用)
│ └── install-hooks.sh # 向 settings.json 注入 hooks
└── themes/ # 19 个动画主题(每个独立 HTML 文件)
快速开始:
# 脚本自动完成:检查依赖 → 注入 hooks → 启动服务 → 打开浏览器。
bash start.sh
# 停止服务
bash stop.sh
五、主题扩展与个性化
为避免 Mini 显示器过于单调,除标准红绿灯外,我额外扩展了多种显示模式。反正全由 AI 生成代码,扩展起来毫无负担。
六、结语
3D 打印外壳 + HDMI 副屏 + 本地状态机,整个实现并不复杂。从 DIY 外壳到硬件组装,再到软件适配,链路完整,软硬件结合的创意值得一试。