Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ right-click the menu bar icon → **Check for Updates…**, or turn on *Settings
Updates → check automatically at launch* (off by default). The app downloads
the signed update, verifies it, and relaunches. Update checks are the only
app-originated network call. The daemon also contacts a T3 Code environment
only after you explicitly enable that adapter and exchange a one-time pairing
only after you explicitly enable that integration and exchange a one-time pairing
link; Microbridge has no telemetry or cloud relay.

Homebrew installs are managed by brew instead: the app detects the brew
Expand All @@ -111,15 +111,15 @@ so the formula version and the on-disk app never drift apart.

### Cursor integration

Cursor support ships inside Microbridge. Open **Settings → Adapters** and click
Cursor support ships inside Microbridge. Open **Settings → Integrations** and click
**Enable Cursor**; Microbridge installs its bundled lifecycle integration into
Cursor's supported local-plugin directory after that explicit consent. Reload
Cursor once if it is already open. **Remove** disables the adapter and removes
only Microbridge's local integration. No Marketplace download is required.

### Factory integration

Factory support ships inside Microbridge. Open **Settings → Adapters** and
Factory support ships inside Microbridge. Open **Settings → Integrations** and
click **Enable Factory**. Microbridge copies its signed `microbridgectl` helper
to `~/.microbridge/integrations/factory/` and merges only its own entries into
Factory's supported `~/.factory/hooks.json`; existing hooks are preserved.
Expand All @@ -140,8 +140,18 @@ contract. Microbridge leaves approval, new-session, and reasoning-effort
controls disabled until CNVS exposes stable targets for them.

Synara and Conductor do not need an installer: their Codex/Claude sessions are
named by the built-in journal watchers. T3 Code controls require the one-time
pairing flow shown in **Settings → Adapters**.
named by the built-in journal watchers. ChatGPT, Claude Desktop, Codex CLI, and
Claude Code are distinguished automatically by those same watchers. T3 Code
controls require the one-time pairing flow shown in **Settings → Integrations**.

### OpenCode integration

OpenCode support ships inside Microbridge. Open **Settings → Integrations** and
click **Enable OpenCode**. Microbridge installs its dependency-free global plugin
at `~/.config/opencode/plugins/microbridge.mjs`. Restart OpenCode if it is already
running. The plugin publishes local lifecycle state and routes Interrupt to the
exact OpenCode session; it does not read or send prompts, transcripts, source
code, or tool arguments. **Remove** deletes only the Microbridge-owned file.

**Note:** Homebrew installs **prebuilt** release binaries (not a from-source
Tauri build). The formula checksums are refreshed by CI after each `v*` tag.
Expand All @@ -160,6 +170,7 @@ Tauri build). The formula checksums are refreshed by CI after each `v*` tag.
| `~/.cursor/plugins/local/microbridge` | Bundled Cursor lifecycle integration (only after consent) |
| `~/.factory/hooks.json` | Existing Factory hooks plus Microbridge-owned lifecycle entries (only after consent) |
| `~/.microbridge/integrations/factory/microbridgectl` | Signed Factory hook helper (only after consent) |
| `~/.config/opencode/plugins/microbridge.mjs` | Bundled OpenCode lifecycle and interrupt integration (only after consent) |
| `~/Library/LaunchAgents/ai.microbridge.ui.plist` | Login item (only if you enable launch at login) |

## Launch at login
Expand Down
11 changes: 8 additions & 3 deletions PRIVACY.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,21 @@ no unconfigured network traffic.
- No unconfigured network traffic; update checks and T3 access require opt-in
- No uploading of session text or source code

## Adapters
## Integrations

First-party adapters watch local session stores. The bundled Cursor integration
First-party integrations watch local session stores. The bundled Cursor integration
sends metadata-only lifecycle events over the local socket and never sends
prompt, response, transcript, or tool argument content. The T3 Code adapter
talks only to the exact environment the user pairs, using scoped orchestration
access.

The optional OpenCode plugin sends only the local session identifier, title,
state, and update time over Microbridge's mode-`0600` Unix socket. It does not
send prompts, responses, transcripts, source code, tool arguments, or files.
Interrupt is executed inside OpenCode against the exact local session ID.

The one-time T3 pairing token is exchanged immediately, never logged, and not
stored. Removing the adapter deletes its Keychain credential.
stored. Removing the integration deletes its Keychain credential.

## Hardware

Expand Down
29 changes: 17 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

**An open-source control plane for the Codex Micro — one macropad, every coding agent.**

Microbridge is a tiny local daemon that bridges AI coding agents — Codex CLI, Claude Code, CNVS, Cursor, T3 Code, Synara, Conductor, Factory, and anything else with an adapter — to the [Work Louder Codex Micro](https://worklouder.cc/). Per-key RGB mirrors live agent state; keys route only the actions each adapter explicitly advertises, so unsupported controls never report false success. No vendor desktop app is required for Microbridge itself.
Microbridge is a tiny local daemon that bridges AI coding agents — ChatGPT, Claude Desktop, Codex CLI, Claude Code, CNVS, Cursor, T3 Code, Synara, Conductor, Factory, OpenCode, and anything else with an integration — to the [Work Louder Codex Micro](https://worklouder.cc/). Per-key RGB mirrors live agent state; keys route only the actions each integration explicitly advertises, so unsupported controls never report false success. No vendor desktop app is required for Microbridge itself.

> **Status: early public alpha (`v0.3.x`).** Menu bar UI, local daemon, in-process Codex/Claude host attribution, native CNVS control, and signed macOS packages are shipping. Cursor and Factory lifecycle reception and paired T3 Code control are opt-in and capability-gated. **HID protocol (VID/PID, framing, `v.oai.thstatus`) is implemented from ChatGPT’s Work Louder kit**; hardware control stays off until enabled in Device settings (or `MICROBRIDGE_HID_CLAIM=1` is set for diagnostics) while physical validation is completed. See [docs/device-hid.md](docs/device-hid.md).
> **Status: early public alpha (`v0.3.x`).** Menu bar UI, local daemon, in-process ChatGPT/Codex and Claude Desktop/Claude Code attribution, native CNVS control, and signed macOS packages are shipping. Cursor, Factory, OpenCode, and paired T3 Code control are opt-in and capability-gated. **HID protocol (VID/PID, framing, `v.oai.thstatus`) is implemented from ChatGPT’s Work Louder kit**; hardware control stays off until enabled in Device settings (or `MICROBRIDGE_HID_CLAIM=1` is set for diagnostics) while physical validation is completed. See [docs/device-hid.md](docs/device-hid.md).

## Screenshots

Expand Down Expand Up @@ -34,19 +34,19 @@ Design spec: [docs/design/README.md](docs/design/README.md).

The Micro's best feature — bidirectional Agent Keys — currently works through exactly one vendor's desktop app. Most of us run agents in more than one place. Microbridge turns the deck into a shared, neutral surface:

- **Adapters publish state.** Each agent session reports `thinking`, `working`, `awaiting_approval`, … as transitions happen.
- **The focus policy decides.** Exactly one session owns the deck at a time; approval requests can preempt. Adapters never touch the device, so two apps can never fight over your keys.
- **Integrations publish state.** Each agent session reports `thinking`, `working`, `awaiting_approval`, … as transitions happen.
- **The focus policy decides.** Exactly one session owns the deck at a time; approval requests can preempt. Integrations never touch the device, so two apps can never fight over your keys.
- **The device layer renders.** State becomes LEDs; key presses become routed actions.

## Design principles

1. **Invisible footprint.** Local watchers are event-driven; device input, CNVS's local snapshot API, and an explicitly paired T3 connection use bounded polling and backoff. Idle CPU and RSS remain part of the [footprint budget](docs/architecture.md#footprint-budget).
2. **Local-first and explicit network access.** There is no telemetry or Microbridge cloud relay. The app checks for updates only when requested or enabled, CNVS traffic is restricted to its authenticated loopback endpoint, and the daemon contacts a T3 environment only after the user enables the adapter and supplies a one-time pairing link. Factory controls invoke the user-installed `droid` CLI only when a hardware action is requested.
3. **Rust core, any-language adapters.** The always-resident part is a single static Rust binary. First-party adapters compile into it (in-process, ~zero overhead). Community adapters are separate processes speaking [newline-delimited JSON](docs/protocol.md) — write one in whatever you like.
4. **The menu bar app is the product UI.** Configure keys, lighting, and adapters there. The daemon keeps the hardware alive underneath; `microbridgectl` is a support/debug escape hatch.
2. **Local-first and explicit network access.** There is no telemetry or Microbridge cloud relay. The app checks for updates only when requested or enabled, CNVS traffic is restricted to its authenticated loopback endpoint, and the daemon contacts a T3 environment only after the user enables the integration and supplies a one-time pairing link. Factory controls invoke the user-installed `droid` CLI only when a hardware action is requested.
3. **Rust core, any-language integrations.** The always-resident part is a single static Rust binary. First-party integrations compile into it (in-process, ~zero overhead). Optional integrations use official host hooks/APIs or speak [newline-delimited JSON](docs/protocol.md).
4. **The menu bar app is the product UI.** Configure keys, lighting, and integrations there. The daemon keeps the hardware alive underneath; `microbridgectl` is a support/debug escape hatch.

Cursor support is included in the Microbridge app and repository. Enable it
once in **Settings → Adapters**; Microbridge installs its bundled lifecycle
once in **Settings → Integrations**; Microbridge installs its bundled lifecycle
integration into Cursor's supported local-plugin directory. There is no
separate Marketplace download or second product to maintain.

Expand All @@ -57,6 +57,11 @@ active model advertises. Synara and Conductor sessions are attributed through
the built-in Codex/Claude watchers, so they need no pairing code or extra
background adapter.

OpenCode support is bundled too. Enabling it installs one dependency-free
global plugin through OpenCode's official plugin directory. Lifecycle events
stay in the OpenCode process, and Interrupt uses the documented session API;
there is no polling or additional helper process.

CNVS support is native and automatic: Microbridge reads CNVS's authenticated
loopback control API, represents each agent terminal by its exact canvas and
node identifiers, and routes focus or interrupt back to that target. No pairing
Expand All @@ -66,8 +71,8 @@ code, private database access, or CNVS modification is required.

```
┌───────────┐ ┌─────────────┐ ┌──────────────────┐
Codex CLI │ │ Claude Code │ │ community adapters
(in-proc) │ │ (in-proc) │ │ (any language)
ChatGPT / │ │ Claude app /│ │ optional integrations
Codex CLI │ │ Claude Code │ │ OpenCode, Cursor, …
└─────┬─────┘ └─────┬───────┘ └────────┬─────────┘
│ in-process │ NDJSON over unix socket
▼ ▼ ▼
Expand Down Expand Up @@ -144,7 +149,7 @@ Requires stable Rust (see `rust-toolchain.toml`) and, for Node adapters / UI, No

## Contributing

Adapter PRs are explicitly welcome — that is the point of the project. Start with [docs/adapters.md](docs/adapters.md) and [CONTRIBUTING.md](CONTRIBUTING.md).
Integration PRs are explicitly welcome — that is the point of the project. Start with [docs/adapters.md](docs/adapters.md) and [CONTRIBUTING.md](CONTRIBUTING.md).

## Relationship to Work Louder / OpenAI

Expand All @@ -156,7 +161,7 @@ Microbridge only exists because the Codex Micro is *open* — and that was a cho

OpenAI is a for-profit company, and it would have been easy to lock the Micro to a single first-party app: a closed protocol, an exclusive USB claim, no way for anyone else to light a key. They did the opposite — they ship the device kit in the open, keep the HID interface **non-exclusive** so third-party software can coexist with the official experience instead of fighting it, and keep giving users a choice (Codex CLI is open source; the models are reachable over documented APIs). None of that was required of them. **Thank you.**

Thanks too to **Work Louder** for designing a genuinely hackable macropad, and to **everyone who writes an adapter, files an issue, or plugs in a device and tells us what really happens** — adapters are the point of this project.
Thanks too to **Work Louder** for designing a genuinely hackable macropad, and to **everyone who writes an integration, files an issue, or plugs in a device and tells us what really happens** — integrations are the point of this project.

Full notes: [ACKNOWLEDGMENTS.md](ACKNOWLEDGMENTS.md).

Expand Down
13 changes: 8 additions & 5 deletions adapters/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# Adapter catalog
# Integration catalog

Adapter documentation lives here, one folder per runtime.
Integration documentation lives here, one folder per runtime. The local socket
protocol still calls an out-of-process connector an `adapter`; that is an
implementation term, not a separate product category.
Read [docs/adapters.md](../docs/adapters.md) for the contract and the review
checklist, and [docs/protocol.md](../docs/protocol.md) for the wire format.

## Built-in integrations

| Adapter | Status | Language |
| Integration | Status | Language |
|---|---|---|
| [`t3code`](t3code/) | daemon-owned paired HTTP | Rust |
| [`factory`](factory/) | bundled official hooks + JSON-RPC controls | Rust helper |
Expand All @@ -17,11 +19,12 @@ checklist, and [docs/protocol.md](../docs/protocol.md) for the wire format.
These integrations are daemon-owned or reuse watchers compiled into the daemon.
See [docs/architecture.md](../docs/architecture.md).

## Managed and out-of-process adapters
## Managed and out-of-process integrations

| Adapter | Status | Language |
| Integration | Status | Language |
|---|---|---|
| [`cursor`](cursor/) | bundled managed hooks | Node |
| [`opencode`](opencode/) | bundled global plugin + session interrupt | Node (no deps) |
| [`reference-echo`](reference-echo/) | community adapter example | Node (no deps) |

Out-of-process adapters may be written in any language and communicate over the
Expand Down
2 changes: 1 addition & 1 deletion adapters/cursor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ replacement sessions.

## Install and consent

1. Open **Microbridge Settings → Adapters**.
1. Open **Microbridge Settings → Integrations**.
2. Click **Enable Cursor**. Microbridge installs its bundled integration into
Cursor's supported local-plugin directory after this explicit consent.
3. Reload Cursor once if it is already open. **Remove** disables the adapter
Expand Down
2 changes: 1 addition & 1 deletion adapters/factory/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Factory integration

Enable Factory in **Microbridge Settings → Adapters**. The app transactionally
Enable Factory in **Microbridge Settings → Integrations**. The app transactionally
merges Microbridge-owned commands into Factory's official user hooks at
`~/.factory/hooks.json` and installs a signed helper at
`~/.microbridge/integrations/factory/microbridgectl`. Existing hooks are
Expand Down
24 changes: 24 additions & 0 deletions adapters/opencode/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# OpenCode integration

Enable OpenCode in **Microbridge Settings → Integrations**. Microbridge installs
one dependency-free global plugin at
`~/.config/opencode/plugins/microbridge.mjs`. OpenCode loads global plugins for
both its CLI and desktop surfaces.

The plugin uses OpenCode's documented plugin events and SDK client. It opens a
local Unix-socket connection to `microbridged`; there is no helper process,
polling loop, telemetry, or external network request.

## Supported behavior

- Lifecycle: session create/update/status/idle/error/delete, tool activity, and
permission-waiting state.
- Interrupt: OpenCode's documented `client.session.abort()` method for the exact
session owning the Agent Key.

OpenCode does not currently expose a stable exact-session focus operation or a
model-aware per-session reasoning-effort mutation through this plugin contract,
so Microbridge does not advertise those controls.

**Remove** deletes only the Microbridge-owned plugin. Restart OpenCode after
installing, repairing, or removing the integration if it was already running.
Loading
Loading