cuxdeck

module
v0.1.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 14, 2026 License: GPL-3.0

README

Mission control for your overnight AI coding fleet — in your pocket.

Every Claude Code session on every machine you own — watched, steered, from any browser on Earth. No accounts. No app store. No servers of ours in the middle. You install it, and it just works.

Status Companion to cux


It's 3:47 AM. Your agent has been refactoring for six hours straight. It burned through one account's limit, hopped to the next seat without dropping the conversation, rode out an API outage with patient retries, and kept going.

You know all this because your phone buzzed once — and because, half-asleep, you opened a link and watched it happen:

╭──────────────────────────────────────╮
│  ⌁ cuxdeck                    ● live  │
│                                       │
│  ▸ mac-studio            2 sessions   │
│    ~/code/client-api                  │
│      seat ogz · running · 6h 12m      │
│      ▓▓▓▓▓▓▓░░░  2.6M tok             │
│    ~/code/side-project                │
│      waiting-reset · ogz in 02:40 ◔   │
│                                       │
│  ▸ linux-box             1 session    │
│    ~/ml/train-pipeline                │
│      seat work · running · 41m        │
│                                       │
│  ▸ gpu-rig               idle         │
│                                       │
│  SEATS (across fleet)                 │
│    ogz    5h ▓▓▓▓▓▓▓░░░  68%          │
│    ozcan  5h ▓▓░░░░░░░░  19%          │
│    work   7d ▓▓▓▓▓░░░░░  51%          │
│                                       │
│  [ switch seat ]   [ pause ]          │
╰──────────────────────────────────────╯

Then you put the phone down and went back to sleep. The fleet kept working.

This is cuxdeck.


Why this exists

cux already turns a pile of Claude accounts into one tireless pool — it swaps seats at the limit, waits out resets, and resumes through outages so your agent runs all night. But once you close the laptop lid, it all happens in the dark. Is it alive? Which seat is it on? Did everything stall at 4 AM waiting for a human who was asleep?

And the moment you run agents on more than one machine — a Mac at your desk, a Linux box in the closet, a GPU rig in the other room — there is no single place that shows you the whole picture. You SSH into three hosts to answer one question: how is my fleet doing?

Claude Code has a remote feature, but it's tied to the account you logged in with — and cux's whole job is to keep changing that account. The moment a swap happens, the session vanishes from your phone.

cuxdeck closes the gap. It is the one screen that answers "how is everything, everywhere?" — and lets you do something about it — from the device that's already in your hand.

What it feels like to use

  1. Install cuxdeck on each machine (see Install below — Homebrew, a signed-less .dmg, a prebuilt binary, or go build).
  2. Run it — it lives in the menu bar. cuxdeck install makes it start with the computer; from then on it prints a pairing QR and needs no configuration.
  3. Scan the QR. That machine is now on your phone — live sessions, seat usage, projects, and its terminals. Scan the next machine's QR and it joins the same fleet view.
  4. Share it. Invite a teammate with a tap — view-only, or full control.

No sign-ups. No tokens to copy by hand. No VPN client on the phone. No third party who can see your data. If a step can be removed, it will be.

Install

macOS — Homebrew (menu-bar app):

brew tap centrual/tap
brew install --cask cuxdeck

Recent Homebrew guards third-party taps, so the first install may ask you to trust it — run brew trust centrual/tap (or the command it prints) and re-run.

macOS — direct: grab cuxdeck-<version>-darwin-universal.dmg from the latest release, open it, and drag cuxdeck to Applications. It's ad-hoc signed, so the first launch is right-click → Open.

Linux / Windows: download the matching archive from the releases page and put the binary on your PATH.

From source (any platform with Go 1.23+):

go install github.com/centrual/cuxdeck/cmd/cuxdeck@latest

Every release ships a checksums.txt; verify with shasum -a 256 -c.

Requires cux

cuxdeck reads cux's on-disk session registry — no patching, no plugin. Everything works against a stock cux ≥ v0.2.11: sessions, seats, projects, the live conversation view, remote session launch.

The one feature that needs more is the live in-browser terminal (mirroring and driving a running session): it depends on cux advertising an attach socket, which lands with inulute/cux#31. Until that ships, the terminal button simply stays hidden — cuxdeck detects it per session (the attachable flag) and degrades cleanly. When #31 merges into a cux release, terminals light up on their own, no cuxdeck update needed.

How it works

                         your phone (one panel, your whole fleet)
                          │            │            │
              ┌───────────┘            │            └───────────┐
              ▼                        ▼                        ▼
     trycloudflare.com        trycloudflare.com        trycloudflare.com
       (tunnel, TLS)            (tunnel, TLS)            (tunnel, TLS)
              ▼                        ▼                        ▼
      cuxdeck @ mac            cuxdeck @ linux          cuxdeck @ gpu-rig
      127.0.0.1                127.0.0.1                127.0.0.1
       reads ~/.cux             reads ~/.cux             reads ~/.cux
       runs `cux`               runs `cux`               runs `cux`
  • Server — one small Go binary bound to 127.0.0.1. It reads cux's on-disk state (accounts, usage cache, project pools, the per-session heartbeat registry) and shells out to the cux CLI for every action, so all the rules stay in cux. It never opens a listening port to the world.
  • Remote access, accountless — cuxdeck downloads and supervises cloudflared (over TLS from Cloudflare's official GitHub releases, self-checked by running it, kept under ~/.cuxdeck/bin) and opens a Quick Tunnel: a random https://….trycloudflare.com address, no Cloudflare account required. If the tunnel drops, cuxdeck rebuilds it and pushes your phone the new address.
  • The fleet is assembled in your browser, not on a server — each machine is one independent deck with its own tunnel and its own device token. Your phone holds the list and merges them into one view. There is no central cuxdeck service to sign up for, trust, or take down — add a machine by scanning its QR, remove it by forgetting it.
  • Pairing & auth — the QR encodes the deck's current URL plus a long random per-device token. The URL is never the secret: every request is authenticated, failed attempts back off, and any device can be revoked from the panel. A short manual code covers cameraless setups.
  • Notifications (Web Push, no third parties) — subscriptions live with your browser's push service, not with our URL, so even when a tunnel address rotates the old service worker still receives the "panel moved — tap to open" push and the chain never breaks. Planned events: tunnel address changed · all seats exhausted (with the reset countdown) · wait-for-reset resumed · API-outage retry started / recovered · run finished (duration + tokens) · a seat needs re-login. Per-event toggles per machine.
  • Telegram (optional, first-class) — a guided flow if you want alerts in a channel that outlives any phone: open BotFather with one tap, paste the token, send /start; cuxdeck catches the chat id and sends a test message. Same events. Never required.

Principles we won't compromise

  • Zero-step by default. Anything that asks for an account, a token, or a config file has to earn its place — or it's cut. Device pairing is the one mandatory step, because security isn't optional.
  • We run no servers. Your data flows through a tunnel your machine spawns, straight to your phone. We never see it, relay it, or store it. There is nothing to trust here but the code in this repo.
  • cux owns the rules. cuxdeck is a window and a remote control. Every change goes through the cux CLI; every reading comes from cux's on-disk files. No logic forks, no drift.
  • A browser is the only client. Phone, tablet, someone else's laptop — if it renders HTML, it's a cuxdeck client. Add it to your home screen and it looks and launches like a native app, with none of the app-store friction.

Roadmap

Phase Scope Status
v1 daemon + mobile panel (sessions · seats · projects, view & manage) · QR device pairing · accountless tunnel supervisor · start-at-login ✅ shipped
v2 multi-machine fleet view (one phone, many decks) · read-only live conversation view · full remote terminal · start a session remotely · Web Push events · Telegram connect wizard ✅ shipped
v3 per-seat utilization trend charts · shared team decks (invite with view / control) · menu-bar tray icon · .dmg / Homebrew packaging + cross-platform releases ✅ shipped
next usage cost (once a price signal exists) · a stable named tunnel option · notarized macOS build planned

Status: usable. The experience above is real today — install from Homebrew, pair a phone, watch and drive your fleet from anywhere. Watch the repo — it's moving fast.

Requirements

  • cux ≥ 0.2.12 (session heartbeat registry)
  • macOS or Linux today · Windows on the roadmap
  • A browser on the device you want to watch from. That's the whole list.

Development

The panel is React + TypeScript, bundled by esbuild used as a Go library — the entire toolchain is Go, and React is vendored under web/vendor, so there is no node/npm anywhere in the loop:

go run ./tools/buildweb   # web/src/*.tsx → internal/server/web/app.js
go build ./cmd/cuxdeck    # single binary, panel embedded

The generated bundle is committed, so a plain go build always works without the generate step.

License

GPL-3.0-only — the same license as cux. Use it, change it, ship it; changes you distribute stay open too. See LICENSE.

Built alongside cux. Not affiliated with Anthropic.

Directories

Path Synopsis
cmd
cuxdeck command
cuxdeck — mission control for your cux fleet.
cuxdeck — mission control for your cux fleet.
internal
auth
Package auth implements cuxdeck's device pairing and request authentication.
Package auth implements cuxdeck's device pairing and request authentication.
chat
Package chat turns Claude Code's session transcript (the JSONL under ~/.claude/projects) into a clean, phone-friendly stream of chat events.
Package chat turns Claude Code's session transcript (the JSONL under ~/.claude/projects) into a clean, phone-friendly stream of chat events.
cuxcli
Package cuxcli is cuxdeck's only write path into cux: a thin, allowlisted bridge to the `cux` command-line tool.
Package cuxcli is cuxdeck's only write path into cux: a thin, allowlisted bridge to the `cux` command-line tool.
cuxdata
Package cuxdata reads cux's on-disk state.
Package cuxdata reads cux's on-disk state.
i18n
Package i18n translates the short, fixed notification strings cuxdeck pushes to phones (Web Push and Telegram) into the language the user picked in the panel.
Package i18n translates the short, fixed notification strings cuxdeck pushes to phones (Web Push and Telegram) into the language the user picked in the panel.
notify
Package notify is the shared vocabulary for outbound alerts: a small event and the interface every channel (Web Push, Telegram, …) implements.
Package notify is the shared vocabulary for outbound alerts: a small event and the interface every channel (Web Push, Telegram, …) implements.
push
Package push delivers Web Push notifications straight from this machine to the browsers paired with it — no third party in the middle.
Package push delivers Web Push notifications straight from this machine to the browsers paired with it — no third party in the middle.
selfupdate
Package selfupdate checks GitHub for a newer cuxdeck release and, when asked, upgrades in place.
Package selfupdate checks GitHub for a newer cuxdeck release and, when asked, upgrades in place.
server
Package server is cuxdeck's HTTP surface: the embedded mobile panel, the deck snapshot API, and the allowlisted action endpoint.
Package server is cuxdeck's HTTP surface: the embedded mobile panel, the deck snapshot API, and the allowlisted action endpoint.
spawn
Package spawn launches a fresh cux session from the panel.
Package spawn launches a fresh cux session from the panel.
telegram
Package telegram delivers the same alerts as Web Push to a Telegram chat — useful for a channel that outlives any one phone.
Package telegram delivers the same alerts as Web Push to a Telegram chat — useful for a channel that outlives any one phone.
tray
Package tray puts cuxdeck in the menu bar: the mascot icon, and a menu to open the panel, copy a pairing link, toggle start-at-login, and quit.
Package tray puts cuxdeck in the menu bar: the mascot icon, and a menu to open the panel, copy a pairing link, toggle start-at-login, and quit.
tunnel
Package tunnel gives cuxdeck its accountless public address.
Package tunnel gives cuxdeck its accountless public address.
usagelog
Package usagelog records each seat's utilization over time so the panel can show a trend, not just the current number.
Package usagelog records each seat's utilization over time so the panel can show a trend, not just the current number.
watch
Package watch turns changes in cux's state into push notifications.
Package watch turns changes in cux's state into push notifications.
tools
buildicon command
Command buildicon rasterizes the brand mascot (assets/onion.svg) to the PNG the menu-bar tray uses.
Command buildicon rasterizes the brand mascot (assets/onion.svg) to the PNG the menu-bar tray uses.
buildweb command
Command buildweb bundles the React panel with esbuild — which is a Go library, so the whole frontend toolchain is `go run`: no node, no npm, no lockfiles.
Command buildweb bundles the React panel with esbuild — which is a Go library, so the whole frontend toolchain is `go run`: no node, no npm, no lockfiles.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL