Skip to Content

Desktop App

TL;DR

The Cmdop desktop client is a Wails (Go + React) application built around a seven-tab workspace, a global hotkey launcher, a system tray, and an embedded inspector for media and per-machine chat. It is the recommended way to operate Cmdop day-to-day; the CLI covers headless and scripted use, and the web cabinet covers workspace, billing, and observability admin.

The desktop app is the primary surface for Cmdop. It runs on macOS, Windows, and Linux and shares the same Go core that powers the CLI, so behaviour is identical across surfaces.

Why Desktop is the primary surface

Desktop is the canonical user-facing surface for Cmdop. It exposes the full agent workflow — chat, machines, work tracking, audit, networking, files, and settings — in a single window, while the CLI remains the headless or scripted equivalent and the web cabinet stays focused on workspace, billing, and observability admin. Because Desktop and CLI share the same Go core (internal/desktop/services/* calls into the same agent, chat, and connection packages used by the CLI binary), there is no behavioural drift — only two front ends over one engine.

Desktop, CLI, and the web cabinet are three views over the same workspace. Switching between them does not change which machines are reachable, which sessions are open, or which permissions are active.

The seven main tabs

The sidebar rail exposes seven primary tabs. Chat is the default landing tab; the rest are reachable with Cmd/Ctrl+17 or by clicking the rail. Each tab is a peer surface — none is “inside” another — and most have an associated lists panel for filtering or browsing items in that tab.

Full-pane conversation with the local agent.
Workspace roster and per-machine inspector chat.
Kanban issue tracker for in-flight agent work.
Live event feed across chat, tools, and permissions.
RPC stats, outage history, and disconnect audit.
Local and remote file trees, side-by-side.
Nine sub-tabs of preferences.

Layout modes

The desktop has two top-level layout modes that respond to window size. Workspace mode shows a 64 px sidebar rail, an optional 250 px lists panel, the main content area, and an optional 300 px inspector — with four inner variants (lists+main+inspector, lists+main, main+inspector, main-only). Compact mode collapses the rail and lists panel into a header-only layout for narrow windows. The mode is chosen automatically based on width and persisted per-window via useLayoutPrefs().

Layout mode is chosen automatically based on window width and persisted per-window. You can force compact mode in Settings → Appearance, and the four inner workspace variants are described in detail on the Layout modes page.

Global hotkey, tray, launcher, and FAB

Outside the main window the desktop exposes four surfaces. The global hotkey (Option+Space on macOS, Alt+Space on Windows and Linux) toggles the chat window from anywhere on the OS. The system tray shows connection state and exposes Connect, Disconnect, and “Stay disconnected across restart”. The launcher is a Spotlight-like overlay for quick prompts, with @machine targeting. The FAB (floating action button) is a persistent shortcut that stays on screen when the main window is hidden and streams launcher results back without restoring the full window.

Inspector panel

The inspector is an embedded right-column panel (or a floating overlay in compact mode) that previews documents — audio, video, images, PDFs — with EXIF and audio metadata. It is driven by the docinfo service for metadata extraction and a /_localfile/ HTTP mux for Range-request media streaming, which is what makes scrubbing in long media files smooth. See Inspector for supported file types and remote-file behaviour.

Connection lifecycle

The desktop authenticates via OAuth on first run, then auto-connects on launch when cfg.DesktopUI.AutoConnect is true. Connect and Disconnect are surfaced from the tray, the status pill at the top of the window, and Settings → Connection. Disconnect is an L2 operation — it closes the gRPC ClientConn so no bytes leave the process, but the OAuth token stays in the keychain. See System tray and Connection tab for the full semantics.

Where to go next

Start here — the default landing surface.
Per-machine inspector chat with direct-pipe routing.
Theme, providers, permission modes, updates.
Every keybinding, grouped by context.
Last updated on