OpenLogi

Architecture

How OpenLogi's desktop, agent, overlay, CLI, shared crates, and hardware boundaries fit together.

OpenLogi separates one authoritative background agent from two GPUI clients. The agent owns HID++ inventory and channels, input capture, binding resolution, device writes, and action execution. The settings app mirrors agent snapshots and sends commands; the Actions Ring overlay only renders and reports user interactions. The CLI is independent and opens hardware directly.

Components

  • OpenLogi agent (openlogi-agent) — the background process: HID++ device I/O, input hooks and capture sessions, per-app watching, pairing, action dispatch, the menu-bar / tray item, and supervision of the overlay helper.
  • OpenLogi desktop (openlogi-desktop) — the GPUI settings app. Its local state is a presentation and editing mirror; HID++ reads and writes go through the agent. Webcam preview and UVC controls remain direct desktop operations.
  • Actions Ring overlay (openlogi-overlay) — a warm, separately supervised GPUI process. It receives presentation-only ring snapshots and returns hover, activation, and cancellation events; the agent retains and executes actions.
  • OpenLogi CLI (openlogi) — headless inventory, asset sync, light and camera control, and HID++ diagnostics. It deliberately bypasses agent IPC.
  • assets.openlogi.org — a static host serving per-device renders and clickable-hotspot metadata, keyed by each device's modelId; a versioned Cloudflare Pages origin and jsDelivr npm shards are raced as mirrors.

Component relationships

Processes and local state

openlogi-ipc is a shared contract and transport library, not another process. The desktop and overlay connect to the same endpoint, while the CLI deliberately bypasses it.

Runtime and I/O boundaries

The agent is authoritative for HID++ and native input capture. The desktop only opens UVC cameras directly; both the desktop and CLI can populate the verified asset cache.

Crates

CrateRole
openlogi-coreLeaf-level types, TOML config, paths, device models, and the button / action catalog
openlogi-hidpp-derivePrivate proc macros that generate HID++ feature boilerplate
openlogi-hidppWorkspace hard fork of the HID++ protocol crate (lib name hidpp): channels, features, receivers
openlogi-hidDevice discovery, HID++ reads / writes, control capture, raw-HID lights
openlogi-hookOS input hook: macOS CGEventTap, Linux evdev/uinput, Windows WH_MOUSE_LL
openlogi-injectOS event synthesis: CGEvent, uinput / MPRIS, SendInput
openlogi-cameraUVC webcam discovery, capture, and image controls
openlogi-permissionsPermission status and remediation for Accessibility, input, camera, uinput, and hidraw
openlogi-assetsDevice-render registry schema and cached mirror fetches
openlogi-ipcThe tarpc service contract and bincode transport over Unix sockets or Windows named pipes
openlogi-agent-coreHeadless orchestration, capture planning, hardware operations, action dispatch, and Actions Ring sessions
openlogi-uiShared GPUI presentation assets, ring geometry, colors, and locales
openlogi-cli / openlogiCLI implementation library and its thin binary wrapper
openlogi-agentThe real agent and openlogi-agent-mock binary targets
openlogi-desktopGPUI settings application and agent IPC client
openlogi-overlaySeparate GPUI Actions Ring renderer and agent IPC client
xtaskCI, packaging, bundling, and release tooling

How a button press becomes an action

  1. The control is captured: either by the OS hook (middle / back / forward) or diverted over HID++ 0x1b04 (gesture button, haptic panel, mode-shift, keyboard F-row) by a per-device capture session the agent rebuilds whenever bindings change.
  2. The agent resolves the binding: the frontmost app's overlay first, then the device's global map.
  3. The agent dispatches it: host actions go through openlogi-inject; device actions use an agent-owned openlogi-hid channel.
  4. ShowActionsRing is different: the agent snapshots a presentation for the overlay, accepts hover / activate / cancel RPCs, validates the session and slot, then executes the selected action itself.

Configuration is a plain TOML file; there is no cloud or account. The desktop loads and atomically writes the file, then requests reload_config. The agent independently loads it at startup and validates it again on reload before replacing live state. Values that live in volatile device RAM (DPI, SmartShift, Fn-lock, wheel resolution) are re-applied after reconnects and system wake.

Developing without hardware

openlogi-agent-mock serves the real IPC contract from a scripted in-memory inventory without opening HID devices or installing input hooks, so the desktop and overlay can be developed with no Logitech device attached. See DEVELOPMENT.md.

On this page