Skip to content

Repository files navigation

Agent Console

Control the Codex, Claude, Hermes and ZCode desktop apps from a Logitech MX Creative Console on macOS: pick a session on the keypad, see which sessions need you on the Home page, prepare model and effort with the dials, stop or compact a run, approve a request, dictate a message, or toggle Codex Voice Chat. A Utilities page opens your everyday apps and sites, and an optional Discord page exposes mute, deafen, leave-voice and a soundboard.

Everything runs locally. The Logi plugin talks to a small Node.js daemon over a private Unix socket; the daemon talks to the apps through their own local interfaces (IPC socket, local gateway, SQLite metadata, Accessibility). Nothing is sent over the network.

Status: 0.2.0, first public release. It is the author's daily-driver setup, extracted and anonymised. It has been verified on one Apple Silicon Mac (macOS 26, Logi Plugin Service 6.4). Treat other configurations as untested and read Compatibility before installing.

Contents

What it does

Home page Codex session page Utilities page
Home page with fictional sessions Codex session controls Utilities page

Demo renders produced by scripts/render-demo.mjs with fictional sessions.

  • Home page (keypad): four app keys plus up to five live session cards per page, sorted by urgency: questions, approvals and blocked runs first, then running sessions, then finished results you have not looked at yet. Pressing a card opens that exact session in its app.
  • Session lists: nine most recent sessions per page for the selected app. The big dial highlights a card, Apply opens it.
  • Session page (Codex, Hermes, ZCode): model and effort keys, context-usage indicator, Stop, Compact (two-step confirmation), Yes for a single identified approval, Answer for Codex multiple-choice questions, Dictate, and for Codex a Speed toggle, Voice Chat toggle and Submit/Cancel after dictation.
  • Dials: the small dial prepares the model, the big dial prepares the effort (or moves the selection on list pages). Green means confirmed in the app, orange means prepared, grey means unavailable. Apply commits prepared settings for the next request.
  • Utilities page: the second key on the dialpad. Opens WhatsApp, Reddit, X, YouTube, Gmail, Zoho Mail and Google Calendar by default; fully configurable.
  • Discord page (optional): voice controls and a soundboard for one server you configure.
  • Menu-bar companion ("Agent Console.app"): shows the same state in a window, can restart the local connection and opens the Accessibility settings pane.

Capabilities per app

Derived from the daemon wiring in daemon/server.mjs and the adapters. "Console" means reachable from the physical keypad/dialpad.

Capability Codex Claude (Desktop + Claude Code) Hermes ZCode
Discover recent sessions Yes (local state DB + live IPC) Yes (Desktop session metadata, sidebar, CLI registry) Yes (local gateway + state DB) Yes (task index DB + logs)
Open / select a session Yes (deep link) Yes (deep link, verified in the window) Yes (sidebar) Yes (sidebar)
Home notices (working / needs you / finished) Yes Yes (native sidebar state, hooks when installed) Yes Yes
Model / effort Yes Not on the console Yes Yes
Stop Yes Not on the console Yes Yes
Compact Yes Not on the console Yes Yes
Approve (Yes) Yes Hook decision path only (see below) Yes Yes (visible card)
Answer multiple-choice question Yes No No No
Dictation (hold Dictate) Native shortcut (Ctrl+Shift+D), Submit/Cancel after release Not on the console Yes Yes
Voice Chat toggle Yes (start / cancel connecting / end)

Claude: the console lists and opens Claude sessions and shows their activity on Home. Model, effort, Stop, Compact, dictation and approvals for Claude remain in the app. The daemon contains code for those actions, but it is intentionally not wired to the console because it has not been verified on real sessions. With the optional Claude Code hooks installed, permission requests from the Claude Code CLI appear on Home and can be answered there through the hook decision channel.

Requirements

  • macOS 14 or later on Apple Silicon (built and tested on macOS 26 / arm64; Intel builds are untested).
  • Logi Options+ with Logi Plugin Service 6.4 or later, and an MX Creative Console (keypad and dialpad). The plugin also declares Loupedeck CT-family devices, but only the MX Creative Console layout has been used.
  • Node.js 22+ (node on the PATH when you run the installer; the path is recorded).
  • The apps you want to control, installed and signed in: Codex desktop, Claude desktop (with the Claude Code tab), Hermes desktop, ZCode desktop. Any subset works; missing apps simply show no sessions.
  • To build from source: Xcode Command Line Tools (swiftc) and the .NET SDK 10.

Install

Two parts are needed: the Logi plugin (what Logi Plugin Service loads) and the local runtime (daemon, Accessibility helper, companion app, profiles). Both come from the same release.

A. From a release archive

  1. Download agent-console-<version>-macos-arm64.zip from the Releases page, verify it against SHA256SUMS, and unzip it.

  2. In Terminal:

    cd agent-console-<version>
    scripts/install.sh

    The installer copies the runtime to ~/Library/Application Support/AgentConsole/, installs ~/Applications/Agent Console.app, creates the plugin development link ~/Library/Application Support/Logi/LogiPluginService/Plugins/AgentConsolePlugin.link, and installs the keypad and dialpad profiles as the default profiles of the "System" application for each device (the previous selection is recorded in installation.json and restored on uninstall). Use --dry-run to print every action first.

  3. Restart Logi Plugin Service: quit and reopen Logi Options+, or run killall LogiPluginService. The plugin starts the daemon and the helper.

  4. Grant Accessibility to AgentConsoleAX when macOS asks (see Permissions).

AgentConsole_<version>.lplug4 is the same plugin packaged for Logi Options+ / the Logi Marketplace. You can install it by double-clicking instead of using the link, but the runtime step (scripts/install.sh --skip-plugin) is still required, because the plugin launches daemon/server.mjs and PluginPackage/bin/AgentConsoleAX from the support directory.

B. From source

git clone https://github.com/ozymandiashh/agent-console.git
cd agent-console
scripts/build.sh      # npm ci, dotnet build, swiftc, companion app
scripts/install.sh

Permissions

Permission Who needs it Why
Accessibility AgentConsoleAX (launched by Logi Plugin Service) and optionally Agent Console.app Reads window titles, sidebars and controls of Claude, Hermes, ZCode and Discord, presses their buttons and menu items, types /compact into ZCode. Codex is driven through its IPC socket and deep links, not Accessibility.
Microphone The target app, not Agent Console Dictation and Voice Chat are started by pressing the app's own native controls; the console never records audio.
Full Disk Access Not required The daemon reads only the apps' own state files under your home directory.
Network None No listening TCP port and no outbound connections (the Hermes adapter connects to the Hermes app's own 127.0.0.1 gateway).

macOS grants Accessibility to the helper only when it is launched by Logi Plugin Service. If you start AgentConsoleAX from a shell for testing, it will report trusted:false even after you enabled it. Let the plugin restart it (killall AgentConsoleAX is enough; the plugin relaunches it within seconds).

Using the console

Keypad (nine LCD keys, left/right arrows) and dialpad (four keys, two dials).

Dialpad keys: Home (top left), Utilities (top right), Fast (bottom left, Codex speed), Apply (bottom right).

  • Home: the four app keys, then session cards. Right arrow pages through cards. Pressing an app key opens its session list (and for Codex, Hermes and ZCode brings the app forward; Claude is listed passively and only comes forward when you open a session).
  • Left arrow: back (session → list → apps). Right arrow: next page.
  • Big dial: move the highlight on Home and lists; prepare effort on a session page; choose an answer on a question page. Eight units per step with a short debounce, so slow deliberate turns register as single steps.
  • Small dial: prepare the model.
  • Apply: open the highlighted card, commit prepared model/effort, or confirm Compact.
  • Session page rows: model / effort / context (Codex: Speed) on top, Stop / Compact / Yes or Answer in the middle, and the bottom row for Voice / Speed / Dictate (Codex) or Dictate (Hermes, ZCode). After a Codex dictation the bottom row becomes Submit / Cancel / Dictate until you decide.
  • Stop asks the app to interrupt the selected session. Compact shows CONFIRM in orange; press again (or Apply) within 10 seconds to run it.
  • Dictate (Hermes, ZCode): hold until RECORDING, speak, release. The text stays in the app's composer for review; nothing is sent. Codex uses its native hold shortcut, with Submit and Cancel afterwards.
  • Voice (Codex): starts Voice Chat in the selected task; pressing again cancels a pending connection or ends the call. The state is read from the app before each press.
  • Key colours: purple pulsing = working, green tick = finished (unseen), yellow ? = needs you, orange = approval, red ! = blocked or error.

Utilities

The Utilities page shows up to eight launchers (nine keys, the first is reserved for Discord when configured). Defaults:

Key Opens
WhatsApp The WhatsApp app (net.whatsapp.WhatsApp)
Reddit https://www.reddit.com/
X https://x.com/
YouTube https://www.youtube.com/
Gmail https://mail.google.com/
Zoho Mail https://mail.zoho.com/zm/ (use mail.zoho.eu, .in, … for your region)
Google Calendar https://calendar.google.com/calendar/

URLs open in the default browser through /usr/bin/open; no shell is involved and repeated presses within a second are ignored.

To change the page, create ~/Library/Application Support/AgentConsole/utilities.json with an array of entries and restart the daemon (killall node is too broad; use the companion app's Restart connection or kill $(cat ~/Library/Application\ Support/AgentConsole/daemon.pid); the plugin relaunches it):

[
  {"id": "notes", "name": "Notes", "color": "#ffcc00", "bundle": "com.apple.Notes"},
  {"id": "docs", "name": "Team docs", "color": "#4285f4", "url": "https://docs.example.com/"},
  {"id": "zohomail", "name": "Zoho Mail", "color": "#f4bc35", "url": "https://mail.zoho.eu/zm/"}
]

Rules: id is lowercase letters, digits and dashes; exactly one of bundle (a macOS bundle identifier) or url (http/https); color is optional; at most eight entries. Invalid files stop the daemon with a clear error in daemon.log.

Discord (optional)

Discord controls are disabled unless ~/Library/Application Support/AgentConsole/discord-catalog.json exists. Copy assets/discord/catalog.example.json and fill in your server id and the sounds of its soundboard (Discord → server → soundboard; ids are visible in the app's developer mode). With a catalog, the first Utilities key opens a Discord page with Mute, Deafen, Exit voice and Soundboard; the soundboard plays sounds only in a voice channel of that server, after re-reading the channel before each press.

Icons

Key images are rendered by the daemon. The repository bundles original monogram icons (assets/*.png, generated by scripts/generate-icons.mjs) rather than third-party logos. To use your own artwork, place PNG files named after the tile in ~/Library/Application Support/AgentConsole/icons/ (for example icons/codex.png, icons/gmail.png, icons/<utility id>.png, icons/discord.png) and restart the daemon. Images are trimmed and fitted into 150×150 pixels.

Codex shortcuts, Claude Code hooks and status line (optional)

These installers change files in your home directory and are therefore separate from install.sh. Each backs up what it changes.

  • node scripts/install-codex-bindings.mjs adds two app-scoped shortcuts to ~/.codex/keybindings.json (composer.submit → Ctrl+Alt+Shift+U, composer.clear → Ctrl+Alt+Shift+Backspace) used by Submit/Cancel after dictation. The previous file is copied to ~/Library/Application Support/AgentConsole/backups/composer-<timestamp>/. Restart Codex afterwards. Undo by restoring the backup.
  • node scripts/install-claude-hooks.mjs --dry-run | --install | --uninstall registers hooks/agent-console-claude-hook.mjs in ~/.claude/settings.json so Claude Code CLI sessions report state and permission requests to the daemon over the private socket, authenticated with a random secret stored in claude-hooks.secret (mode 0600). Unrelated hooks are preserved; --uninstall removes only the entries it added.
  • node scripts/install-claude-statusline.mjs --dry-run | --install | --uninstall chains a small wrapper in front of your existing Claude Code status line so model and context usage reach the daemon; your own status line keeps working.

Data, storage and network

What the daemon reads (all read-only, all local, metadata only):

App Sources
Codex ~/.codex/ipc/ipc.sock (the app's multi-client IPC), ~/.codex/state_5.sqlite (recent threads, via sqlite3 -readonly), ~/.codex/models_cache.json
Claude ~/Library/Application Support/Claude/claude-code-sessions/**/*.json (Desktop session metadata), ~/.claude/sessions/*.json (CLI registry) and transcript file names/metadata under ~/.claude/projects/, the Claude window sidebar through Accessibility
Hermes The Hermes app's local gateway on 127.0.0.1 (port discovered per launch, session token read from its own page), ~/.hermes/state.db
ZCode ~/.zcode/v2/tasks-index.sqlite, ~/.zcode/cli/db/db.sqlite, ~/.zcode/cli/log/zcode-*.jsonl, ~/.zcode/v2/config.json, the ZCode window through Accessibility
Discord The Discord window through Accessibility (voice state, soundboard panel)

What it stores, in ~/Library/Application Support/AgentConsole/ (directory mode 0700, files 0600):

  • control.sock, gui.sock, daemon.pid: private sockets and pid.
  • activity-ledger.json: per-session status and result identifiers so that a result you already opened is not announced again. No titles, no message text.
  • session-actions.jsonl, dictation-events.jsonl, last-input.json: short operational logs (action, status, timestamps, daemon-generated messages).
  • composer-review.json: Codex session ids with a dictated draft pending Submit/Cancel.
  • claude-hooks.secret: the random bearer secret for the optional Claude Code hooks.
  • daemon.log, plugin-status.log: process output.
  • Your configuration: utilities.json, discord-catalog.json, icons/.

Session previews shown on Home (a short extract of a final answer or question) are held in memory only and truncated to about 200 characters. Full prompts, answers and tool output are never read into files.

Network: the daemon binds only a Unix socket. The only TCP connection it ever opens is to the Hermes app's own gateway on 127.0.0.1. There is no telemetry, no update check and no external request of any kind.

Compatibility

Observed working with the versions below on one Mac. Every adapter depends on internal interfaces (IPC protocol, SQLite schema, Accessibility labels) that the vendors can change without notice; a new app version can break discovery or a specific action until the adapter is updated. Accessibility labels are matched in English and Romanian.

Component Version observed
macOS 26.6 (Apple Silicon)
Logi Plugin Service / Logi Options+ 6.4.1 / 2.7
Codex desktop (bundled in the ChatGPT app) Codex framework 152.x, IPC protocol v3
Claude desktop / Claude Code 1.52 / 2.1.26x
Hermes desktop 0.17.2
ZCode 3.11.2
Discord 0.0.410
Node.js 22
.NET SDK (build only) 10.0

Limitations

  • Claude actions other than open and Home notices are not on the console (see the capability table).
  • Codex Submit and Cancel rely on the optional keybindings installer; without it those keys report the missing shortcut.
  • Hermes and ZCode dictation depend on the apps' own dictation controls and on macOS Dictation being enabled for them.
  • Free-text questions, secret prompts and MCP forms are answered in the app; the question page implements only Codex multiple-choice questions.
  • The Discord soundboard catalog is static; changes on the server are not synced.
  • Only one MX Creative Console (keypad + dialpad) layout is provided. The profiles are installed for the "System" application (they apply regardless of the foreground app).
  • Hooks, keybindings and the status-line wrapper are per-user changes and must be uninstalled with the matching --uninstall step or the backups.
  • Not validated on a freshly installed Mac; the installer has been exercised against a temporary home directory and the built artifacts match the author's installed runtime byte for byte for the helper and the daemon.

Troubleshooting

  • Keys stay dark or show "Starting…": the daemon is not running. Check ~/Library/Application Support/AgentConsole/daemon.log and plugin-status.log; make sure runtime.json points to an existing Node 22+ binary (scripts/install.sh rewrites it).
  • "Enable Agent Console in macOS Accessibility": add AgentConsoleAX in System Settings → Privacy & Security → Accessibility. If it is already listed, remove it, then killall AgentConsoleAX and let the plugin relaunch it. The companion app's Enable Accessibility… menu item opens the pane.
  • A session list is empty: the app is not running or not signed in, or its state files moved. The key shows the adapter's reason.
  • Codex Submit/Cancel show a missing shortcut: run node scripts/install-codex-bindings.mjs and restart Codex.
  • Profiles did not switch: connect each device once in Logi Options+ so its "System" profile folder exists, then rerun scripts/install.sh --skip-plugin, or import AgentConsole-Keypad_<v>.lp5 and AgentConsole-Dialpad_<v>.lp5 from the release and select them in Logi Options+.
  • Blank key images: sharp failed to load (run npm ci in the runtime directory or reinstall from the archive, which includes node_modules).

Uninstall

scripts/uninstall.sh           # keeps your configuration and metadata in the support directory
scripts/uninstall.sh --purge   # also deletes ~/Library/Application Support/AgentConsole

The uninstaller stops the daemon and helper, removes the plugin link, restores the previously selected profiles, removes the companion app and the runtime code, and runs the Claude hook/status-line uninstallers if they were used. It never touches the data of Codex, Claude, Hermes, ZCode or Discord; the only external file it can change is ~/.claude/settings.json (restoring your original hooks and status line). Restore ~/.codex/keybindings.json from the backup folder if you no longer want the two composer shortcuts. Finally remove AgentConsoleAX from the Accessibility list if you wish.

Building from source

scripts/build.sh     # PluginPackage/bin/*.dll, native/AgentConsoleAX, dist/Agent Console.app
npm test             # 597 Node tests (they compile nothing and touch no real session)
dotnet run --project tests/native/NativeActionTests.csproj -c Release
dotnet run --project tests/gui-hold/GuiHoldTests.csproj -c Release
scripts/package.sh   # dist/AgentConsole_<v>.lplug4, *.lp5 profiles, runtime zip, SHA256SUMS

PluginApi.dll is taken from the installed Logi Plugin Service (LOGI_PLUGIN_API_PATH overrides the path) and is never copied into the package. logiplugintool (dotnet tool install --global LogiPluginTool) is used for packing and verification when available; otherwise the package is zipped directly. The Swift binaries are ad-hoc signed; the build is deterministic and the helper reproduces byte for byte with the same toolchain.

Repository layout

Plugin/            C# plugin for Logi Plugin Service (buttons, dials, hardware input, daemon bridge)
PluginPackage/     Package metadata (LoupedeckPackage.yaml, icon); bin/ is produced by the build
profiles/          Keypad (Loupedeck70) and dialpad (Loupedeck71) profiles
daemon/            Node.js daemon: controller, adapters, rendering, hooks control plane
native/            AXBridge.swift (Accessibility helper), AgentConsole.swift (companion app), console.html
hooks/             Claude Code hook script
scripts/           build, package, install, uninstall, optional installers, icon generator
assets/            Original monogram icons and the Discord catalog example
tests/             Node tests with synthetic fixtures; two small C# check programs
docs/              Architecture and privacy notes

License

MIT, see LICENSE. Third-party components and trademarks are listed in THIRD_PARTY_NOTICES.md.

About

Control the Codex, Claude, Hermes and ZCode desktop apps from a Logitech MX Creative Console (macOS). Local daemon + Logi plugin + Utilities page.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages