用 Claude Code 跑长任务时,经常会遇到一个问题:把复杂任务丢进后台,转身去处理其他事情。几小时后回来,终端光标还在闪,看起来一切正常。但仔细一查,任务早在几十分钟前就卡在了一个确认环节,就这么静默地悬停在那里。
系统通知当然能解决这个问题,但前提是你在电脑前、且没有淹没在其他消息里。对于动辄跑几十分钟的后台任务,"后台静默卡死"是一个很容易被忽略的盲区。
一、灵光乍现
于是我做了一个实体状态 Mini 副屏,把 AI 牛马卷起来:用 3D 打印外壳 + HDMI 小屏 + 本地状态服务 ,通过红绿灯,把 Claude Code 的运行状态实时映射到桌面上。无法上传视频,演示效果可以关注微信视频号:涛哥玩3D 。
🔴 红灯 ------ AI 正在全速运行,CPU/Token 消耗中;
🟡 黄灯 ------ AI 等待用户确认,任务卡在半路,这是最容易被遗漏的状态;
🟢 绿灯 ------ AI 处于空闲,任务已完成或尚未开始。

整个方案成本可控、复现门槛不高,下面按硬件组装 → 软件状态机实现 → 前端展示的顺序展开。
二、硬件准备
1、Mini 显示器外壳
外壳不需要自己建模,直接用开源方案。拓竹 MakerWorld 上搜索 "Mocintosh 摸鱼小副屏",作者提供了两款尺寸:
| 尺寸 | 分辨率 | 打印时长 | 耗材重量 |
|---|---|---|---|
| 2.8-inch(推荐) | 640×480 | 约 4.4h | 161g |
| 3.54-inch | 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、组装外壳

四、软件架构:三层状态机
硬件只是躯壳,核心在于软件架构。整体分为三层:
js
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...
js
用户发消息
│
├─ 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 主题 绿灯由服务端倒计时决定:前端无任何计时逻辑
项目结构如下
js
MyBetterDisplay/
├── start.sh # ⭐ 一键启动(首次运行这个就够了)
├── stop.sh # 停止监控服务
├── install.sh # 安装 BetterDisplay 应用
├── index.html # 监控主页(主题切换器)
├── claude-status/
│ ├── monitor.js # HTTP 监控服务(port 4242)
│ ├── set-state.sh # Hook 脚本(由 Claude Code 调用)
│ └── install-hooks.sh # 向 settings.json 注入 hooks
└── themes/ # 19 个动画主题(每个独立 HTML 文件)
快速开始
bash
# 脚本自动完成:检查依赖 → 注入 hooks → 启动服务 → 打开浏览器。
bash start.sh
# 停止服务
bash stop.sh
五、主题扩展
为了让 Mini 显示器不那么枯燥,除了标准红绿灯以外,我还扩展了很多模式。反正都是 AI 来干活,随便扩展扩展。

六、总结
3D 打印外壳 + HDMI 副屏 + 本地状态机,实现下来并不复杂。从 DIY 外壳,到组装硬件显示器,再到适配软件程序,整条链路完整,软硬件创意的结合,值得动手一试。