Devices Page
Your other machines and the work that lives on them — pull a workspace or a whole project to this device, open one on its device without copying it, and sweep settled worktrees.
The Devices page shows the machines your account knows about and the workspaces that live on them, and moves work between them. Your local workspaces stay in the sidebar; this page is for everything that lives elsewhere. (To use another machine's Codemux from a browser instead, see Web Remote Access.)
Opening the Page
- Sidebar footer — click the Devices icon. It appears once there is something to show: a device you've added in Settings → Devices, or work synced from another device of your account. Its dot is amber when something needs a decision (a failed push or pull, a branch that diverged across devices, a device that answers but needs setup) and green when at least one device is online.
- Command palette —
Ctrl+K→ Devices. - Close —
Escape, or the sidebar's Back button. Like the other utility pages, Devices opens beside the sidebar, and the workspace underneath stays loaded.
Layout
The page is one column:
- This device — a one-line summary with your local workspace count ("managed in the sidebar"). When settled worktrees can be cleaned up, it carries a Sweep N settled chip with their approximate disk size — see Sweeping settled worktrees.
- A card per device — every device registered in Settings → Devices, in the order they appear there. The header shows the device name, a status (
online,updating…,needs attention,checking…, orunreachable · last seen …), and a meta line with its SSH target, workspace and project counts, and disk usage. A device that needs attention shows what is wrong in place of the meta line. Reachable devices start expanded; the rest fold to their header until clicked. - Another device — workspaces your account knows about whose device isn't configured on this machine, so nothing disappears silently. You can pull them here, but not open them in place.
- Add device — opens Settings → Devices.
When a device is running a Remote Control server, its card shows a Remote Control serving badge and a Connect button that opens the hosted web client.
With no devices yet, the page reads "No devices yet" and suggests adding one — your home desktop, an always-on box, or a cloud server.
Project Grouping
Inside a device card, workspaces are grouped by project: a folder icon, the project name, and a count. The first project starts open; the rest are one-line headers until clicked. An open project header carries a Pull project button — see Pull an entire project at once.
Grouping uses a stable project identity, not the folder path: the same repository cloned at different paths on different devices or hosts still groups together, while two unrelated repositories that happen to share a folder name do not. Each row also carries a repo root or worktree badge so the project's root checkout is distinguishable from its branch worktrees at a glance.
Repo Root Protection
Codemux treats a git repository as one connected unit — the root checkout and all of its branch worktrees share the same history. The root checkout (your project on its default branch) is protected:
- It carries a
repo rootbadge, and in the sidebar its menu offers Archive or Close instead of Delete Worktree…. You can't accidentally delete the whole repository the way you'd remove a throwaway worktree. - Pulling a repo root to another device brings the repository over once and lands it cleanly, so the root and its worktrees stay on one shared history rather than drifting into an independent copy.
If you pulled a project to a device before this behavior existed, its root may instead be a disconnected standalone copy — a full copy of the repo that will drift from the real history over time. Its sidebar right-click menu has a Reconcile copy… item that detaches the card without touching the files on disk (it refuses if the copy has uncommitted changes or unpushed commits, so nothing is ever lost), after which you can Pull project to land a clean, connected repo root. Reconciling never deletes your work — it just removes the disconnected card so the project reads cleanly again.
Row Actions
Each workspace row shows its title, kind badge, branch, and two buttons:
- Open on <device> — only on a device configured on this machine. Drives the workspace in place on that device without copying it down. See Open a workspace on its device below.
- Pull here — brings the workspace to this machine. See Sibling-device adoption below.
While a pull runs, the buttons are replaced by a Pulling spinner with an elapsed-seconds counter.
Pushing goes the other way and starts from the sidebar: right-click a local workspace and choose Move to device… (see Safety guardrails).
Sweeping Settled Worktrees
The Sweep N settled chip on the This device row removes the worktrees of settled local workspaces to free disk space. The confirm dialog shows the count and approximate size, and explains that branches are kept and that worktrees with uncommitted or unpushed work are skipped — a sweep is never the thing that loses work. Repo roots, attach-in-place, and device-backed workspaces are never candidates.
Sibling-Device Adoption
When the Devices page shows you a workspace on another device of yours, its Pull here button brings it to your current machine. Codemux picks the right adoption strategy automatically:
- Host-backed adoption — if both devices have the same SSH host configured, Codemux rsyncs the worktree from that host. The adopted workspace replaces the original on the host (single source of truth).
- Clone-from-git fallback — if the workspace has a git remote but no shared host, Codemux runs
git clone --no-checkoutinto~/.codemux/projects/<basename>, adds a worktree on the right branch, and registers a fresh local workspace. Both devices end up with independent worktrees sharing the same git remote — push and pull from both ends to stay in sync. - Same-branch guard — if you click Pull here on a row but you already have a local workspace on the same branch of the same project, the dialog refuses to create a parallel copy. Instead it shows the existing workspace with an
Open the existing workspacebutton so a pull can't silently clobber work you're already doing. The match is on the workspace's stable project identity plus the git branch (falling back to project folder name when no identity is known), so it's reliable even when the same repo lives at different paths on the two devices. - Neither — if the workspace has no host and no remote, the dialog tells you to push from the other device first.
Uncommitted work on the origin device is preserved by the host-backed path; the clone fallback warns you before it runs if there's anything that could be lost.
Pull an Entire Project at Once
When a sibling device has a whole project — the repo root plus several branch worktrees — you don't have to adopt each card one at a time. The project header carries a single Pull project button that brings the entire repository over in one action:
- The repo root lands first, as a protected root, so the repository exists locally on one shared history.
- Each branch worktree is then recreated as a real linked worktree under that root — they share the root's history instead of becoming independent copies.
If one worktree fails to materialize (a branch that no longer exists, say) the rest still come over, and Codemux tells you which ones it skipped. This is the recommended way to move a multi-worktree project to a new machine.
Open a Workspace on Its Host
Pulling brings a host workspace's files down to your machine. Sometimes you don't want a copy — you just want to drive the workspace where it already lives. The Open on <device> button does exactly that: it opens a terminal (and agent) running on the host, in the workspace's real directory there, and streams the output live to your desktop. Nothing is copied to this device — no files land under ~/.codemux/.
This is the third way to work with a remote workspace, alongside Push (send a local workspace up to a host) and Pull (bring a host or sibling workspace down to this device):
| Mode | Where the files live | Where commands run |
|---|---|---|
| Push | Copied up to the host | On the host |
| Pull | Copied down to this device | On this device |
| Open on <device> | Stay on the host (no copy) | On the host |
Using it
Open on <device> appears on a workspace row when that device is registered in Settings → Devices on this machine (Codemux needs an SSH path to reach it). Click it and a workspace card appears in the sidebar with a single ready terminal already attached to the device — start typing and you're running commands in the workspace's directory on the remote machine.
The in-place workspace's sidebar card shows the device's name, and its only teardown action is Close workspace — which leaves it running on the device. It can't be deleted, pushed, or pulled, because there's nothing local to act on. While it is open here, its row is hidden from the Devices page so you aren't offered to open it twice.
Survives closing the app
The host process keeps running when you close Codemux or shut your laptop's lid — the agent on the host doesn't stop just because your SSH connection dropped. Reopen the app (or open the same workspace from another device that has the host configured) and Codemux re-tunnels and re-attaches to the still-running session. Each device attaches independently over its own connection.
What's available today
The terminal and agent are the supported surface for an in-place workspace. Local-only panels — the file tree, the Changes panel, and ports — are empty, because the files live on the host, not on this device. If you need those, use Pull here instead so the workspace has a local copy.
A workspace on a device that isn't configured on this machine (the Another device card) doesn't offer Open on <device> — there's no SSH route to attach with — so use Pull here for those.
Your Conversation Follows the Workspace
Pushing or pulling a workspace doesn't just move the files — if you have an active agent conversation in it, that comes along too. When you push a workspace whose terminal is running a Claude Code or OpenCode session, Codemux carries the conversation to the host so the agent resumes there with its full context instead of starting cold. Pull it back and the conversation continues on your laptop. This holds across repeated push/pull cycles — messages are never lost or duplicated.
A few things worth knowing:
- The matching agent CLI must be installed on the host (
claudeoropencode, reachable from a login shell). If it isn't, the agent still launches — just without the carried-over history. - It's best-effort. If the conversation can't be synced for any reason, the push or pull still succeeds and the agent still starts; you only lose the continuity, never the workspace.
- OpenCode sync only moves this workspace's session. OpenCode keeps all of its conversations in a single local database, so Codemux transfers just the one session tied to this workspace — the host's other OpenCode conversations are never touched.
- The same daemon that keeps agents running after you close the app powers this: a pushed workspace's agent runs on the host and survives your SSH connection dropping.
Auto-publish from codemux-remote Hosts
The Devices page also lists workspaces that an agent (or anything else) created directly on a host — without you ever pushing one there from a dev device. The model is intentionally asymmetric:
- Dev devices (laptops, desktops running the Codemux app) keep their manual push/pull. Nothing leaves the device unless you say so.
codemux-remotehosts auto-publish their workspace registry. They're always-on, SSH-reachable, and exist to be used as hosts — broadcasting what's on them is the unsurprising default.
How it works in practice: each dev device polls every configured host over SSH every ~60 seconds, runs codemux-remote workspace list on the host (which reads the daemon's local registry — no running daemon required), and republishes any new workspaces it finds to the cloud registry. Other devices see them on the next pull tick, so a workspace an agent creates on pandora overnight via the MCP workspace_create tool shows up on every dev device's Devices page within ~90 seconds.
Two consequences worth knowing:
- A device you've configured shows up immediately. You don't have to push a workspace to it first — its card renders the moment the device is added in Settings → Devices (reading "Nothing on <device> yet" until something lands there), so you can see at a glance which devices are wired up.
- Host-discovered rows carry a
project_remotewhen the host project has a git remote. Codemux records the project's canonical remote on the host, so pull-to-this-device for these rows works via either path — host-backed (rsync from the shared host) or the clone-from-git fallback. A host project with no resolvable remote is adoptable only via the host-backed path.
Cross-Device Divergence
When the same workspace exists on multiple devices via clone-adoption and their git HEADs have moved separately, the rows show an amber diverged chip; hover it to see where else the branch has different commits. Push from one side and pull on the other to bring them back together. Divergence also turns the sidebar's Devices dot amber. The chip clears automatically once both ends agree on the same commit.
Safety Guardrails
Every push and every adoption has two safety nets:
- Confirm before push — Move to device… → <device> in a sidebar card's right-click menu opens a confirmation dialog with the workspace title, the destination, and a short explanation of what's about to happen. A "Don't ask again for
<host>" checkbox skips the dialog for that destination on this device (persisted in local storage). - 10-second Undo — every successful push, and every pull that came from a device, surfaces a toast with an
Undobutton that fires the reverse action. (A clone-from-git adoption has no Undo: the two copies are independent.) Double-click-guarded so the reverse only runs once. If the reverse action itself fails, you get a follow-up error toast.
Elapsed-Time Indicator
When a push or pull takes longer than ~2 seconds, a compact 12s pill renders next to the spinner — both on the Devices page row and in the sidebar row. Lets you tell at a glance whether the operation is still working or actually stalled. The counter ticks once per second until the operation completes.
What Syncs Across Devices
The cross-device registry that powers sibling-device rows syncs a deliberately small set of fields through the Codemux API (Bearer-token authenticated, scoped per user):
Synced: title, host the workspace lives on, project path, git remote URL, branch, HEAD SHA (for divergence detection), project identity + name + type (main / worktree, so grouping and badges line up across devices), and create / update / delete timestamps.
Not synced (per-device runtime state): working directory, worktree path, pane statuses, terminal sessions, surface tree, git ahead/behind/changed-file counts (read from each device's local git tree), notification counts, mute state.
A workspace mutation propagates to other devices within ~30 seconds via a background pull/push loop. Last-write-wins; there is no conflict UI — if two devices edit the same workspace simultaneously, the later push overwrites.
See Also
- Workspaces — creating and managing individual workspaces.
- Settings → Devices — adding a device so you can push workspaces to it or run threads there.
- Web Remote Access — use another machine's Codemux from a browser instead of moving work.
- Automations — scheduled agent runs that also use the host routing layer.