fix: detect and control Codex Micro over HID (v0.3.9)#92
Conversation
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 15 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (9)
📝 WalkthroughWalkthroughMicrobridge 0.3.9 adds USB/Bluetooth HID transport detection, macOS Input Monitoring permission requests, periodic physical-device refresh, transport-aware hardware UI states, and updated installation, release, and troubleshooting documentation. ChangesHID transport and hardware control
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant MicrobridgeUI
participant Tauri
participant macOS
participant Microbridged
User->>MicrobridgeUI: Enable hardware control or choose Claim
MicrobridgeUI->>Tauri: Request Input Monitoring access
Tauri->>macOS: Check or request IOHID listen permission
macOS-->>Tauri: Return permission status
MicrobridgeUI->>Microbridged: Apply hardware-control configuration
Microbridged->>Microbridged: Refresh HID presence and claim device
Microbridged-->>MicrobridgeUI: Publish transport and connection state
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Comment |
There was a problem hiding this comment.
Pull request overview
This PR updates Microbridge’s Codex Micro hardware pipeline to detect devices via the macOS HID registry (instead of USB-only system_profiler), adds transport-aware naming for USB-C/Bluetooth, and tightens “Connected” semantics to require a successful HID write. It also prepares the v0.3.9 release across Rust/Tauri/JS packages and improves install/uninstall behavior for the signed macOS app.
Changes:
- Add HID-registry-based presence probing with transport suffixes (
-usb,-bluetooth) and refresh device presence every 2 seconds without repeatedly retrying a stable failed claim. - Request macOS Input Monitoring permission from the signed UI app on Claim/Retry paths, and only mark “Connected” after a successful HID write.
- Release prep: bump versions to
0.3.9, update docs, and harden release app staging/cleanup during install/uninstall.
Reviewed changes
Copilot reviewed 29 out of 32 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/uninstall.sh | Kill/wait for running UI before deleting the app bundle. |
| scripts/install-from-release.sh | Track staging dir for cleanup; wait for UI exit before replacement. |
| INSTALL.md | Uninstall steps updated; hardware control docs mention USB-C/Bluetooth. |
| docs/releases/v0.3.9.md | New release notes for v0.3.9 hardware changes. |
| docs/hardware-bringup.md | Update bring-up runbook for HID-registry detection + transport. |
| docs/governance.md | Clarify upgrade flow includes microbridge-app install. |
| docs/device-hid.md | Update HID presence/transport documentation and retry semantics. |
| docs/design/README.md | Refine “Retry” copy to include permission-driven failures. |
| docs/architecture.md | Update idle CPU budget explanation with HID presence refresh. |
| crates/microbridged/src/state.rs | Add presence refresh API; render LEDs early; broadcast DeviceChanged after write-induced descriptor changes. |
| crates/microbridged/src/main.rs | Schedule presence refresh on a 2-second cadence in the main loop. |
| crates/mb-device/src/probe.rs | Prefer HID registry probe (hidapi) with transport reporting; keep USB fallback. |
| crates/mb-device/src/lib.rs | Transport-aware device names; “Connected” only after successful write; rename “usb_present” to “device_present”. |
| crates/mb-device/src/claim.rs | Track transport on claimed device using hidapi bus type. |
| Cargo.toml | Workspace version bump to 0.3.9. |
| Cargo.lock | Lockfile updates for 0.3.9 workspace crates. |
| apps/microbridge-ui/src/surfaces/surfaces.test.tsx | Add UI test coverage for Bluetooth-detected copy. |
| apps/microbridge-ui/src/surfaces/Settings.tsx | Use transport-aware physical-device detection/labels in settings text. |
| apps/microbridge-ui/src/surfaces/Popover.tsx | Treat physical device presence beyond USB-only; update copy to mention Bluetooth. |
| apps/microbridge-ui/src/surfaces/Disconnected.tsx | Improve disconnected guidance depending on current view. |
| apps/microbridge-ui/src/lib/hardwareControl.ts | Add physical-device detection + transport labeling; invoke Input Monitoring request via Tauri. |
| apps/microbridge-ui/src/lib/hardwareControl.test.ts | Add tests for transport labeling / physical device detection. |
| apps/microbridge-ui/src/components/DeviceEcho.tsx | Display transport-aware “detected” status for physical devices. |
| apps/microbridge-ui/src/App.tsx | Request Input Monitoring permission before enabling hardware control. |
| apps/microbridge-ui/src-tauri/tauri.conf.json | Version bump to 0.3.9. |
| apps/microbridge-ui/src-tauri/src/lib.rs | Implement request_input_monitoring_access command and use physical-device detection for menu actions. |
| apps/microbridge-ui/src-tauri/Cargo.toml | Version bump to 0.3.9. |
| apps/microbridge-ui/src-tauri/Cargo.lock | Lockfile updates for 0.3.9. |
| apps/microbridge-ui/package.json | Version bump to 0.3.9. |
| apps/microbridge-ui/package-lock.json | Version bump to 0.3.9. |
| adapters/sdk/package.json | Version bump to 0.3.9. |
| adapters/claude/hooks/microbridge-permission.mjs | Adapter metadata version bump to 0.3.9. |
Files not reviewed (1)
- apps/microbridge-ui/package-lock.json: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
crates/mb-device/src/claim.rs (1)
29-52: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winMake HID selection deterministic when both transports are exposed.
crates/mb-device/src/claim.rsandcrates/mb-device/src/probe.rs: both paths take the first matching HID entry, so a device exposed over USB and Bluetooth can flip the reported suffix and claimed interface across refreshes. Add an explicit transport tie-break instead of depending on HidApi iteration order.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/mb-device/src/claim.rs` around lines 29 - 52, The HID candidate selection in claim.rs and probe.rs currently depends on HidApi iteration order, causing inconsistent results when USB and Bluetooth entries both match. Update the selection logic in both paths to apply an explicit, shared transport tie-break before choosing the first candidate, while preserving preferred-PID ordering and ensuring the same transport is selected consistently in crates/mb-device/src/claim.rs lines 29-52 and crates/mb-device/src/probe.rs lines 74-96.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/microbridged/src/main.rs`:
- Around line 89-102: The polling task currently holds the input_bus mutex while
refresh_device_presence performs potentially blocking HID enumeration.
Restructure the loop so poll_device_inputs and expire_leased_sessions retain
their locked path, but release the guard before probing; run
refresh_device_presence outside the mutex, then re-acquire input_bus only to
apply the resulting device-presence changes using the existing state APIs.
In `@docs/device-hid.md`:
- Around line 18-22: Update the device-presence documentation to state that
MockDevice is used only when no supported physical device is detected, while a
detected-but-unclaimed Micro remains represented as a HidDevice. Clarify that
this preserves the codex-micro-<transport> descriptor and Detected UI status,
distinct from Connected.
In `@docs/hardware-bringup.md`:
- Around line 21-27: Update the HID inspection command in the hardware bring-up
documentation to display the full matching IOHIDDevice record rather than
relying on the limited rg -A8 context. Preserve the existing matching criteria
and ensure VendorID, ProductID, and Transport are visible when validating the
pass condition.
In `@docs/releases/v0.3.9.md`:
- Around line 20-22: Update the release-note sentence describing the validated
physical Codex Micro claim/release path to explicitly state that it occurred
over USB-C, while preserving the remaining behavior and validation details.
In `@scripts/install-from-release.sh`:
- Around line 92-99: Treat an unconfirmed microbridge-ui shutdown as an error
before destructive operations: in scripts/install-from-release.sh lines 92-99,
recheck the process after the wait and abort or explicitly force termination
before replacing DEST; apply the same post-loop recheck and
abort-or-force-terminate behavior in scripts/uninstall.sh lines 43-49 before
deleting the app.
---
Outside diff comments:
In `@crates/mb-device/src/claim.rs`:
- Around line 29-52: The HID candidate selection in claim.rs and probe.rs
currently depends on HidApi iteration order, causing inconsistent results when
USB and Bluetooth entries both match. Update the selection logic in both paths
to apply an explicit, shared transport tie-break before choosing the first
candidate, while preserving preferred-PID ordering and ensuring the same
transport is selected consistently in crates/mb-device/src/claim.rs lines 29-52
and crates/mb-device/src/probe.rs lines 74-96.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: a7fca421-d90d-4227-95f3-c2363e61e4ae
⛔ Files ignored due to path filters (3)
Cargo.lockis excluded by!**/*.lockapps/microbridge-ui/package-lock.jsonis excluded by!**/package-lock.jsonapps/microbridge-ui/src-tauri/Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (29)
Cargo.tomlINSTALL.mdadapters/claude/hooks/microbridge-permission.mjsadapters/sdk/package.jsonapps/microbridge-ui/package.jsonapps/microbridge-ui/src-tauri/Cargo.tomlapps/microbridge-ui/src-tauri/src/lib.rsapps/microbridge-ui/src-tauri/tauri.conf.jsonapps/microbridge-ui/src/App.tsxapps/microbridge-ui/src/components/DeviceEcho.tsxapps/microbridge-ui/src/lib/hardwareControl.test.tsapps/microbridge-ui/src/lib/hardwareControl.tsapps/microbridge-ui/src/surfaces/Disconnected.tsxapps/microbridge-ui/src/surfaces/Popover.tsxapps/microbridge-ui/src/surfaces/Settings.tsxapps/microbridge-ui/src/surfaces/surfaces.test.tsxcrates/mb-device/src/claim.rscrates/mb-device/src/lib.rscrates/mb-device/src/probe.rscrates/microbridged/src/main.rscrates/microbridged/src/state.rsdocs/architecture.mddocs/design/README.mddocs/device-hid.mddocs/governance.mddocs/hardware-bringup.mddocs/releases/v0.3.9.mdscripts/install-from-release.shscripts/uninstall.sh
|
Addressed the outside-diff HID selection finding in 0645c4f: probe and claim now share one deterministic key that preserves preferred-PID priority, then prefers USB over Bluetooth over unknown when both transports are exposed. Added ordering tests, including preferred Bluetooth PID versus a different USB PID. |
What
Fixes the production Codex Micro detection/claim path and prepares v0.3.9:
system_profilerprobeBluetooth control is conditional on the paired device exposing the vendor HID interface, matching the physical transport contract.
Why
A physical Codex Micro was visible in macOS IOHID with VID
0x303A, PID0x8360, and usage page0xFF00, but Microbridge fell back tomockbecausesystem_profilermissed it. The previous claim path could also report Connected after opening a handle even when macOS rejected writes.Validation
cargo test --workspace --all-targets— 85 passedcargo clippy --workspace --all-targets -- -D warningscargo test --manifest-path apps/microbridge-ui/src-tauri/Cargo.toml— 11 passedcargo clippy --manifest-path apps/microbridge-ui/src-tauri/Cargo.toml --all-targets -- -D warningspnpm --dir apps/microbridge-ui test— 35 passedpnpm --dir apps/microbridge-ui buildbash -n scripts/install-from-release.sh scripts/uninstall.shcodex-micro-usb; native right-click Claim changed the live snapshot to Connected; menu refreshed to Release; Release returned it to Detectedai.microbridge.ui, Team ID3NQG568C4Q, hardened runtime, nested daemon/CLI signatures validNative QA boundary
USB-C claim/release is proven on the physical device. The paired Bluetooth device was still reported by macOS under
device_not_connectedduring the run, so Bluetooth code/tests are green but final physical BLE claim proof remains pending an unplug/wake/connect cycle.Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Chores