Advanced
Non-default tmux Server
By default every tmux call resolves ambiently: $TMUX when ccmux runs inside tmux, tmux’s default socket otherwise. That breaks when your agents live on a named server (tmux -L work) but the daemon was auto-started from a plain login shell, which lands it on the default socket. It scans a server with no panes on it, finds nothing, and the board sits empty.
Name the server explicitly, by config or environment:
ccmux config set tmuxSocket work # a label -> tmux -L workccmux config set tmuxSocket /tmp/my.sock # a path -> tmux -S /tmp/my.sockccmux daemon restart
export CCMUX_TMUX_SOCKET=work # same thing, per shell (wins over the config key)There is also a convenience flag for an explicitly started daemon:
ccmux daemon start -b --label workccmux daemon start -b --socket /tmp/my.sockccmux daemon status # prints the socket the running daemon tracksA leading / means a socket path, anything else a label. Environment and config are the primary interface because the daemon is usually auto-started for you (it inherits your environment, so both reach it); the flag only applies to a ccmux daemon start you run yourself.
After an upgrade you do not need to restart the daemon by hand: the next ccmux command notices the running daemon is on an older build and replaces it, as long as it has no running invocations or queued handoffs (a busy daemon is kept, with a one-line warning). A daemon started from a different checkout on the same version is left alone; switch with ccmux daemon restart. ccmux daemon status shows both builds.
Inside tmux, the client half of ccmux ignores the setting and uses the server you are attached to; the daemon always honors it, which is the point of the setting.
When the configured server cannot be reached, the picker, the sidebar, and ccmux show say so and name the socket (tmux server unreachable at /private/tmp/tmux-501/work) instead of reporting an empty session list.
Remote / SSH
ccmux tracks the sessions on the machine where it runs, so for a remote devbox, run everything there: install ccmux, tmux, and your agents on the remote host, run ccmux setup, and attach over SSH. Detection, hooks, the picker, and the sidebar all work at full fidelity because nothing crosses the SSH boundary; your terminal is just the window into it.
The one piece that doesn’t follow automatically is desktop notifications: the remote daemon has no desktop to deliver to. The osc notification backend covers this by writing a notification escape sequence into the session’s tmux pane, so it rides the terminal stream, SSH included, and renders as a banner in the emulator you’re sitting in front of. Opt-in only (never picked by auto) and informational only: no buttons, reply, sound, or retraction, and paneless background sessions are skipped. Kitty clients get OSC 99, everything else OSC 9 (title: body); supported by Ghostty, iTerm2, and WezTerm (OSC 9) and Kitty (OSC 99), silently ignored by Apple Terminal and Alacritty.
# on the remote hostccmux config set notifications.enabled trueccmux config set notifications.backend osctmux set -g allow-passthrough all # add to tmux.conf to persistccmux notify # test: a banner should appear locallyUse all rather than on: at on, tmux only forwards passthrough sequences from visible panes, and the agent that needs your attention is usually in a window you’re not looking at.
Nested tmux (a local tmux, SSH, then a remote tmux where ccmux runs) is detected automatically: the escape is wrapped twice so it survives both layers. Both tmux instances need allow-passthrough all (with on, the outer tmux drops the sequence whenever the SSH pane sits in a background local window), and ccmux can only verify the one it runs under, so set it on the local side too. A Kitty terminal behind an outer tmux receives the plain OSC 9 form, since Kitty can’t be detected through that outer tmux; the banner still appears, just without per-session grouping.