eliBenven/freemicro
GitHub: eliBenven/freemicro
让 OpenAI Codex Micro 宏键盘脱离 ChatGPT 桌面应用、直接接入 Claude Code 生命周期的驱动工具,通过 LED 灯效和按键映射实现对多个并行 AI 编程项目的物理状态感知与快速切换。
Stars: 1 | Forks: 0
# ⌨️💡 FreeMicro
### 你的 **Codex Micro** 会显示你的哪些 **Claude Code** 项目需要你,按下按键即可跳转过去。
六个 Agent Key,对应六个代码仓库,每个按键各司其职。当项目的 agent 正在思考时按键会显示蓝色,当需要你介入时显示琥珀色,完成时显示绿色。按下亮起的按键,其对应的终端就会置于最前。
[](LICENSE)
[](https://www.python.org/)
[](pyproject.toml)
[](CONTRIBUTING.md)
[](docs/PROTOCOL.md)
[](docs/PROTOCOL.md)
[](#honest-status)
```
○ idle ◍ working… ◐ needs you ● done ✖ error
#FFFFFF #304FFE #FF6D00 #00FF4C #FF0033
```
## 日常使用效果
三个项目同时开启,只需一个控制板。这是 slot resolver(槽位解析器)产生的真实运行记录,而非简单示意图:
| 时刻 | AG00 | AG01 | AG02 |
|---|---|---|---|
| 开始处理 `api` | `api` 蓝色 | 暗色 | 暗色 |
| 打开 `web` 并开始任务 | `api` 蓝色 | `web` 蓝色 | 暗色 |
| 打开 `docs` | `api` 蓝色 | `web` 蓝色 | `docs` 蓝色 |
| `api` 请求权限 | **`api` 琥珀色** | `web` 蓝色 | `docs` 蓝色 |
| 你按下 AG00 | *api 的终端标签页置于最前* | | |
| `web` 完成 | `api` 琥珀色 | **`web` 绿色** | `docs` 蓝色 |
| 3 分钟后,未读的绿色淡化 | `api` 琥珀色 | `web` 白色 | `docs` 蓝色 |
| 你关闭了 `docs` 的终端 | `api` 琥珀色 | `web` 白色 | 暗色 |
**按键位置永远不会变动。** `api` 是你最先接触的项目,所以它在一整天里都会占据 `AG00` 的位置,不管围绕它的活动顺序如何变动。这块控制板会逐渐形成你的肌肉记忆,不亮的按键意味着“此处无项目”,而不是“变暗了”,因此亮起的按键数量就是正在运行的项目数量,无需阅读任何文字即可一目了然。
按键绑定的是**项目目录**,而不是 session id。目录可以经受住 `/clear`、崩溃的标签页、系统重启和合上屏幕;而 session UUID 做不到这一点。毕竟,一块需要你反复重新配置的控制板,还不如没有控制板。
**完整设计说明(包括槽位稳定性规则和确切的颜色定义):[`docs/AGENT-KEYS.md`](docs/AGENT-KEYS.md)。**
## 开发初衷
OpenAI 的 **Codex Micro** 拥有六个华丽的顶部 **Agent Keys**,它们会根据你 agent 的实时状态发出光芒。但有一个痛点:**这种灯光效果是由 ChatGPT 桌面应用推送的,而且仅限 Codex 使用。** 如果你在终端中使用 Claude Code,这些按键就会黯淡无光。更糟糕的是,这块控制板的按键根本不会发出普通的扫描码,所以如果没有那个应用,它们甚至连打字都不行。对于其他任何 agent 来说,它开箱即是一个昂贵的镇纸。
FreeMicro 重新接管了这块控制板。它直接使用设备原生的供应商协议进行通信,因此能够**读取每一次按键**并**控制每一个 LED**,并直接接入 Claude Code 真实的生命周期 hooks,全程无需任何供应商应用介入。
该协议已详细记录在 **[`docs/PROTOCOL.md`](docs/PROTOCOL.md)** 中,据我们所知,这是目前互联网上对该协议的首份公开文档。
## 快速开始
只需两条命令。第二条命令在进行任何更改前都会先询问你,并明确告诉你该怎么操作。
```
pipx install git+https://github.com/eliBenven/freemicro # not on PyPI yet
freemicro start
```
`freemicro start` 会按顺序引导完成整个设置过程:它会检查所有 macOS 权限,并主动为你打开对应的“系统设置”面板;接着寻找你的控制板(支持 USB 或 Bluetooth);如果你电脑上的 ChatGPT 应用正在争抢同一个 LED 的控制权,它会向你发出警告;然后写入你的配置,并询问是否驱动 LED(默认选择为**否**);接着提供安装 Claude Code hooks 的选项,并通过触发一个模拟的 session 来**验证它们是否正常工作**;之后提供安装后台守护进程的选项;最后通过让控制板遍历亮起每一种状态色来结束流程,让你直观看到效果。当你发现配置出现偏差时,随时都可以安全地重新运行它。此外,每个提示都有默认选项,因此在脚本中使用 `freemicro start --yes` 也是完全可行的。
然后在第一天,有两件事值得了解:
```
freemicro config --web # the visual editor: click a key on a picture of your pad
freemicro menubar # a status item that tells you when FreeMicro has stopped working
freemicro lights --enable # let FreeMicro drive the LEDs (off until you say so)
```
**请使用 `pipx`。** 它会将 FreeMicro 放入其专属的 virtualenv 中,并将可执行文件置于你的 `PATH` 路径下,这正是 Claude Code hooks 和后台守护进程所必需的;而且它会安装在 `~/.local` 目录下,而不是 macOS 禁止后台进程读取的某些位置。使用 `pip install --user` 也可以。如果你还没有安装 `pipx`,请运行:`brew install pipx && pipx ensurepath`。
更倾向于通过 clone 安装(用于贡献代码或阅读源码)?
``` git clone https://github.com/eliBenven/freemicro cd freemicro python3 -m venv .venv ./.venv/bin/python -m pip install --upgrade pip # editable installs need pip >= 21.3 ./.venv/bin/python -m pip install -e . export PATH="$PWD/.venv/bin:$PATH" # add to ~/.zshrc to make it stick freemicro --version ```lifecycle hooks] -->|stdin JSON| B[State Engine
one state per project] B -->|idle / working / waiting / done / error| C[micro-leds] C -->|v.oai.thstatus| P[Codex Micro
vendor HID 0xFF00] P -->|key + joystick events| K[Input Bridge] K -->|your keymap| T[Frontmost app] ``` 控制板本身就**是**显示屏。FreeMicro 没有第二块显示 surface,没有备用灯光,也没有屏幕上的 chip 组件:如果控制板未连接,`freemicro run` 只会将每次状态变化打印到你的终端,仅此而已。这是有意删减的功能,并非遗漏。详情请参阅 [`SPEC.md`](SPEC.md) §5.3。 ## 真实状态 **已在实体零售版设备上验证**(VID `0x303A` / PID `0x8360`,固件版本 v0.4.1,2026-07-23): * ✅ **读取所有输入。** 包含六个 Agent Keys、七个动作按键、旋钮(按压*及*旋转)以及摇杆,均通过控制板的 `0xFF00` 供应商 HID 通道完成。 * ✅ **驱动 LED。** 通过 `v.oai.thstatus` 单独控制六个 Agent Keys,并通过 `v.oai.rgbcfg` 控制底光和背光。已通过肉眼确认。 * ✅ **双重传输模式。** 输入、灯光和 RPC 均已在未连接线缆的情况下,通过 **USB 和 Bluetooth** 完成验证。 * ✅ **在硬件上跑通完整的“hook → 状态 → 灯光”循环。** 真实的 Claude Code hook JSON 输入至 stdin → 进入状态存储 → 传递给 `freemicro run` → 控制 Agent Keys 按顺序展示全部五种状态颜色(全程通过 Bluetooth 进行)。`freemicro selftest` 可以按需重新执行上述所有环节,唯一的例外是它不会直接点亮你的控制板 LED(而是断言校验确切的协议消息)。 **尚未实现/待定项:** 悬而未决的协议问题(`v.oai.rgbcfg` 与 `lights.preview` 的对比、`magic` 字段、编码器 `act` 值)已在它们应在的位置被详细记录,见 [`docs/PROTOCOL.md`](docs/PROTOCOL.md)。 FreeMicro 是基于**我们自有硬件上观察到的设备行为**进行的独立重新实现,并进行了互操作性相关的文档化记录。本文档/项目中未复制或引入任何供应商源代码。 ## FreeMicro 横向对比 | | **FreeMicro** | OpenMicro | VibeSignal | codex-micro.com | |---|---|---|---|---| | 驱动 **真实 Codex Micro 的** LED | ✅ 已验证 | ❌ 仅限游戏手柄 | ❌ | ✅(克隆板) | | 读取 **真实 Codex Micro 的** 按键 | ✅ 已验证 | ❌ | ❌ | ✅(克隆板) | | **一个按键对应一个项目**,并显示该项目自身状态灯 | ✅ | ❌ | ❌ | ❌ | | 按下亮起的按键跳转至对应终端 | ✅ | ❌ | ❌ | ❌ | | 支持 **Claude Code** | ✅ | ✅ | ✅ | ✅ | | **开源** | ✅ MIT | ✅ MIT | ✅ | ❌ 付费 | | 完全支持用户重定义按键及 LED 映射 | ✅ 可视化编辑器 + 单一 JSON 文件 | 部分 | ❌ | 部分 | | 支持 Bluetooth 连接 | ✅ 已验证 | - | - | ? | | 在你明确要求前不对控制板进行任何操作 | ✅ 手动选择开启 LED | ❌ | n/a | ❌ | | 公开通信协议文档 | ✅ [`docs/PROTOCOL.md`](docs/PROTOCOL.md) | ❌ | ❌ | ❌ | ## 故障排除 **请先运行 `freemicro doctor`。** 它能检测出程序层面可检查的一切问题,包含一次真实的往返写入测试。如果是*灯光*出现问题,`freemicro selftest` 能提供更具体的诊断:它会通过真实的 hook 命令模拟推送整个 session,并告诉你哪一个环节断开了。 | 症状 | 修复方法 | |---|---| | **Claude 运行时 LED 毫无变化** | 运行 `freemicro selftest`。十有八九是因为 hooks 根本没安装,或者指向了一个已经移动过的 virtualenv。运行 `freemicro install` 即可修复这两点。 | | `hooks registered on every lifecycle event: FAIL` | 运行 `freemicro install`,然后**重启 Claude Code**:它仅在启动时才会读取 `settings.json`。 | | 已安装 hooks,依然没有反应 | 有程序在监听吗?在终端里运行 `freemicro run`,或者运行 `freemicro daemon install` 让其常驻后台。`freemicro status` 会显示状态引擎是否确实接收到了你的 session。 | | 守护进程无法启动 | 运行 `freemicro daemon logs`。如果出现 `PermissionError … pyvenv.cfg`,说明二进制文件位于 `~/Desktop`/`~/Documents`/`~/Downloads` 目录下,而 macOS 不允许后台 agent 读取这些路径:请使用 `pipx` 重新安装。如果控制板无法打开,说明守护进程需要获得属于自己的 Input Monitoring 权限(见上文)。 | | `Codex Micro not found` | 插入 USB 线或通过 Bluetooth 配对,两者皆可。`freemicro detect` 应当列出 `303a:8360`。 | | `could not open it` | 缺少 Input Monitoring 权限,授权后请**重启终端**。 | | 按键日志显示 `FAILED` | 缺少 Accessibility 权限,授权后请重启终端。 | | `… already has the pad` | 有其他程序正在占用设备,通常是守护进程。`freemicro daemon status` 会指出其名称;可以加上 `--take-pad` 强行接管,但这两者会发生冲突。 | | 按键输入到了错误的窗口 | 击键指令会发送给**最前方**的应用。请将焦点切回你的 Claude Code 终端。 | | LED 未发生变化 | 你是否运行了 `freemicro lights --enable`?如果 ChatGPT 应用处于打开状态,它会驱动相同的 LED;运行 `freemicro lights --coexist` 可避免两者发生冲突。 | | 旋钮毫无反应 | 请绑定 `ENC_CW` / `ENC_CC`,而不仅仅是 `ENC_CLK`。`--dry-run` 可以显示接收到的旋转动作。 | | 所有操作都显示“成功”却毫无动静 | 在此设备上,写入的返回码毫无意义。`freemicro doctor` 会执行唯一真实有效的测试:一次 `device.status` 往返验证。 | | 修改配置后毫无作用 | 运行 `freemicro config`,它会打印出最终实际生效的是哪个文件。 | | `command not found: freemicro` | 你跳过了安装步骤,或者 `.venv/bin` 未添加到 PATH 中。使用 `pipx install` 可以彻底避免此问题。你永远不需要设置 `PYTHONPATH`。 | | `freemicro watch` / `--no-screen` 提示已被移除 | 这是正常的。它们曾驱动的渲染器已被移除;`freemicro run` 会接管其任务,并将每一次状态变化打印在这里。 | | 本来一切正常,然后突然停止 | 某些设备会出现 USB 间歇性断连。重新插拔一下线缆;`freemicro run` 会报告控制板不存在,并在其重新连接前保持正常运行状态。 | ## 卸载 只需一条命令,它在进行任何更改前会先展示要删除的列表。 ``` freemicro uninstall --dry-run # exactly what would go, and nothing happens freemicro uninstall # the same list, then asks ``` 它将按顺序执行以下操作:停止守护进程及其他任何占用控制板的进程,并确认它们已停止;在相关的控制代码仍安装着时,**将控制板的 LED 恢复为熄灭状态**;移除 LaunchAgent;从 `~/.claude/settings.json` 中删除 FreeMicro 的 hook 条目,但保留你的所有其他 hooks 不受影响;最后删除 `~/.freemicro` 目录——这包含键位映射及其备份、引擎设置、保存的布局、session 状态、槽位分配、锁文件、守护进程日志以及原始 hook 日志。 | Flag 标志 | 功能 | |---|---| | `--dry-run` | 打印完整列表后终止操作,不做更改。 | | `--yes` | 跳过确认步骤,专为脚本设计。如果在无终端环境下且未提供此 flag,它会直接拒绝执行而不是乱猜。 | | `--keep-config` | 保留 `keymap.json`、`keymap.json.bak`、`config.json` 以及 `layouts/`,这样在你重新安装时就能完全延续之前的配置。其余所有内容仍将被删除。 | 它会按名称报告每一个步骤。如果某一项内容无法被移除——例如文件正在使用中或存在权限问题——它会明确指出是哪一项,同时坚持清理剩余内容,并以非零状态码退出。它绝不会打印不实的总结信息;无论你是运行两次,还是在一台根本没有安装过任何相关内容的机器上运行它,它都会成功执行并告诉你没有任何需要移除的内容。 **有两件事它做不到,并且会通过精确的路径提示告诉你:** * **macOS 权限授予。** Input Monitoring 和 Accessibility 属于 TCC 条目,你的机器上没有任何程序能代你撤销它们。请前往“系统设置” → “隐私与安全性” → 找到这两项,手动关闭 FreeMicro 的开关。 * **安装包本身。** `freemicro uninstall` 移除的是 FreeMicro 的*状态数据*,而不是 FreeMicro 本身。请使用你当初安装它时的对应方式来完成最后的清理: pipx uninstall freemicro 如果使用了 pipx(推荐) pip uninstall freemicro # 如果使用了 pip rm -rf