Collie drives one multiplexer per install: Herdr, tmux or zellij. Herdr is the default. This page covers pointing Collie at any of the three, what each backend can answer, and the beacons Collie uses to detect an agent in a pane.
Name the backend in COLLIE_MUX, point it at an endpoint, restart, and install the beacon hooks.
Experimental in 1.0. tmux and zellij were tested on tmux 3.6b and zellij 0.44.2, on a single host. Herdr is the default and the primary supported backend. Testers wanted: open an issue on AltanS/collie titled
tmux: …orzellij: …, with your multiplexer, version, OS, and what you saw.
Name the multiplexer on the command line:
COLLIE_MUX=herdr collie start
COLLIE_MUX=tmux collie start
COLLIE_MUX=zellij collie startSet the endpoint when the default target is not the one you want:
# in your .env: ~/.config/collie/.env, or Herdr's plugin config dir on a Herdr
# install. See Configure for the full precedence.
COLLIE_MUX=tmux
COLLIE_MUX_ENDPOINT_TMUX=/run/user/1000/collie-tmux.sock
COLLIE_MUX_ENDPOINT_ZELLIJ=collie-zellij
# only if the binary sits somewhere unusual
# COLLIE_TMUX_BIN=/usr/bin/tmux
# COLLIE_ZELLIJ_BIN=/home/you/.local/bin/zellij| variable | value | what it means |
|---|---|---|
COLLIE_MUX |
herdr, tmux or zellij |
which backend this install drives |
COLLIE_MUX_ENDPOINT_TMUX |
/run/user/1000/collie-tmux.sock |
a socket PATH (tmux -S), because it has a / |
COLLIE_MUX_ENDPOINT_TMUX |
work |
a socket NAME (tmux -L work), no / |
COLLIE_MUX_ENDPOINT_TMUX |
empty | tmux's own default server |
COLLIE_MUX_ENDPOINT_ZELLIJ |
collie-zellij |
a session NAME, not a path |
COLLIE_MUX_ENDPOINT_ZELLIJ |
empty | the single running session |
COLLIE_TMUX_BIN |
/usr/bin/tmux |
only if tmux sits somewhere unusual |
COLLIE_ZELLIJ_BIN |
/home/you/.local/bin/zellij |
only if zellij sits somewhere unusual |
Herdr has no endpoint variable here: its socket is HERDR_SOCKET_PATH, not a
COLLIE_MUX_ENDPOINT_ name.
That socket is the local one and no other. A machine saved in Herdr is not a crew member, and only a Collie crew brings another machine's sessions to the phone. What each list is, and why one is not the other, is in Herdr machines and the crew.
Then restart, install the beacon hooks, and start an agent where the phone can see it:
collie restart # after every .env edit
collie hooks install claude # once per host, tmux and zellij only
# open a window or a tab for the agent
tmux -S /run/user/1000/collie-tmux.sock new-window -n claude
zellij --session collie-zellij action new-tab --name claude
claude # in that window or tabCOLLIE_MUX on the command line sets the choice for that run and for every later run. start
writes the name to .env, so running collie start later drives the same multiplexer.
With COLLIE_MUX unset, start probes for Herdr, tmux, and zellij, prompts for a backend, and
writes the answer to .env. For the full configuration reference, see
MUX_CONTRACT.md → Pointing a collie at a multiplexer.
collie hooks install claude installs Collie's beacon hooks, which
tmux and zellij require. They expose panes as generic shells, so without hooks every pane appears as
bash.
The command updates ~/.claude/settings.json and leaves project configs untouched
(details below). Running Claude instances do not
reload their configuration, so restart them.
Note. Herdr is not required in this mode. With
COLLIE_MUX=tmuxorCOLLIE_MUX=zellij, the bridge loads only the selected adapter and ignores Herdr's socket. Multi-session discovery across Herdr config roots is disabled (bridge/index.ts). You do not need Herdr installed or running, and.envlives in~/.config/collie/instead of the plugin configuration directory.
COLLIE_TMUX_BIN is usually left unset. Collie checks a list of standard paths and does not read
PATH, which background services and Herdr actions do not share with login shells.
Note. Keep socket paths short. Unix domain sockets longer than roughly 100 characters fail to connect, and tmux returns
error connecting to … (File name too long). Use/run/user/<uid>/or/tmprather than a deep directory path.
On tmux versions before 3.7 with window-size set to manual, creating a window crashes the
server. Collie blocks window creation in this state and tells you to run
tmux set -g window-size latest; Requirements lists the tested
versions.
With automatic-rename on, tmux renames a window after whatever program is running in it; Collie
shows the last folder of that window's active pane instead, since a screenful of tabs named bash
says nothing — a window you named yourself keeps that name.
If your distribution lacks zellij packages, download a binary from
zellij's GitHub releases and place it in your
PATH.
Leaving the endpoint empty defaults to the single running session. If zero or multiple sessions exist, Collie halts with an error instead of selecting one. If a named session exits, Collie reports it by name instead of switching to an active one.
Zellij requires XDG_RUNTIME_DIR to locate sessions. If Collie reports all sessions as exited,
verify that the systemd service includes this environment variable
(contract).
Zellij sessions persist independently of their initial terminal. Create a session with
zellij -s collie-zellij and detach using Ctrl o d. On headless hosts,
zellij attach --create-background collie-zellij starts a detached session directly (verified on
zellij 0.44.2).
Note. Collie manages active sessions, but it does not create or restart them.
collie doctor # the `mux` check names the multiplexer, its endpoint,
# and whether it answered
# `[bridge] mux: tmux · socket /run/user/1000/collie-tmux.sock`, printed at
# startup; a multiplexer it cannot reach is one warning line more
collie logs
# the herd, as the phone is given it
curl -s http://127.0.0.1:8787/api/snapshot | head -c 400This curl call works without auth headers. Read requests bypass device validation even when
COLLIE_DEVICE_HEADER is enabled (Configure). Only write actions require
the configured header.
Check the phone UI: the dashboard should display your tmux windows or zellij tabs, and the
Claude pane should identify as an agent instead of bash. If panes still display as standard
shells, verify the beacon hook installation below.
$ collie hooks install claude
$ collie hooks status
would install: /home/you/collie/bin/collie beacon emit (this checkout)
/home/you/.claude/settings.json: installed (v1)Because tmux and zellij expose panes as generic shells, agents must announce themselves. This requires installing Collie's beacon hooks into Claude Code's configuration.
The output references the bin/collie path from this repository. Package installs use the installed
binary path (~/.local/bin/collie or ~/.local/share/collie/current/bin/collie) rather than
versioned directories, ensuring links remain valid across updates.
Behavior details for Claude configuration changes:
- Modifies the global
~/.claude/settings.jsonand any activeCLAUDE_CONFIG_DIR. Project-level.claude/settings.jsonfiles are untouched. - Injects five hooks tagged
# collie-beacon v1with 10-second timeouts. Existing hooks are preserved.hooks uninstall clauderemoves only Collie entries. - Running Claude processes do not reload configuration. Restart agents to apply changes.
- Linux only. The agent liveness check depends on
/proc. Other operating systems do not emit beacons. - Beacons are multiplexer-specific. They record pane and session identifiers for the active
backend. Switching
COLLIE_MUXinvalidates existing beacons. Old beacons remain on disk until cleared, visible undercollie doctor'sbeaconscount. - If using
COLLIE_STATE_DIR, export it in the agent's shell environment.collie beacon emitreads this variable directly; otherwise, beacons write to the default state directory where the bridge will not find them.
collie doctor includes a beacon-hooks-claude diagnostic check that points out missing hooks or
broken paths to moved checkouts. For runtime details, see
Agent beacons.
The table below summarizes key differences. Refer to MUX_CONTRACT.md for the
exact specification.
| Herdr | tmux | zellij | |
|---|---|---|---|
| a space is | a workspace | a session | the session — exactly one, so the phone drops the space strip |
| a tab is | a tab | a window | a tab |
| a pane is | a pane | a pane | a terminal pane |
| who says a pane holds an agent | Herdr does, itself | a beacon, or nothing | a beacon, or nothing |
| how soon an unannounced change is seen | pushed | pushed | counted on a schedule, 12 s ceiling |
| "Show in terminal" | yes | yes | no — zellij accepts the request and moves nothing |
| open / rename / close a tab | yes | yes (opening is refused on the tmux crash case above) | yes |
| open a space | yes | yes | no — a session it made would be invisible to it |
| pane history | from Herdr's own pane record | from the beacon's session key | from the beacon's session key |
Without active beacons, tmux and zellij present panes as raw shells, and pane history is marked unavailable rather than returning empty content.
- "synced Ns ago": This indicator appears in the dashboard header to show data age. It is displayed only when the backend relies on scheduled polling, such as zellij (up to 12s polling interval). Herdr and tmux push state changes immediately, so the freshness badge is omitted.
- "Show in terminal": This pane action focuses the selected pane in your active host terminal. It is disabled on zellij because zellij's focus command accepts the instruction without changing view state.
Note. The mobile interface never changes host terminal focus automatically. Only the explicit "Show in terminal" action updates the display. Navigating the dashboard or opening panes does not affect the active host cursor (ADR 0031).
claude --resume # reconnects the conversation, not the windowCollie does not store multiplexer state. Restarting a tmux server destroys its windows, leaving the dashboard empty. Standard tmux plugins restore the window layouts and working directories: tpm for plugin management, tmux-resurrect for saving session trees, and tmux-continuum for automated snapshots.
Note. Running agent processes are not preserved. Restart Claude Code manually after recovery.
zellij -s collie-zellij # start the session
zellij attach --create-background collie-zellij # headless: start it detached
claude --resume # reconnects the agentZellij does not provide an equivalent to tmux-resurrect. Sessions persisted after terminal
detachment show as (EXITED - attach to resurrect), and attaching triggers re-execution of session
commands, so a reboot means starting the session fresh with one of the commands above and launching
agents inside it, reconnecting each with claude --resume or claude --continue.
Note. Because attaching produces side effects, Collie does not attach to or resurrect sessions. Exited sessions appear as unreachable, and the UI displays a disconnection banner instead of an empty session list.
A beacon is how an agent identifies itself to Collie, on tmux and zellij, where a pane otherwise appears as a generic shell.
$ collie hooks install claude
$ collie hooks status
would install: /home/you/collie/bin/collie beacon emit (this checkout)
/home/you/.claude/settings.json: installed (v1)A hook in Claude Code settings runs collie beacon emit, which writes a file containing the harness
name, the session, and the target pane. Herdr tracks this natively. Setup details are in
Pointing Collie at a multiplexer; this section
explains the mechanism.
The path above references bin/collie from the local checkout. A binary install points to
~/.local/bin/collie, or to ~/.local/share/collie/current/bin/collie when that name is not
linked, as described above. The status command
performs no writes.
Running hooks uninstall claude removes only entries added by Collie. It modifies your global
Claude configuration, not project-level files. This is Linux-only: the liveness check inspects
/proc, and Collie writes no beacons on other operating systems.
Claude becomes visible immediately on startup. Because the hook triggers on SessionStart, an open
pane waiting for input displays as an idle agent instead of a shell.
Visibility ends when the process exits. Collie verifies the emitting PID on each check, so once the agent terminates, the pane immediately reports as a standard shell instead of lingering in an unknown state.
Collie does not delete the beacon file to do this: the file remains on disk, collie doctor reports
it under beacons as expired, and the next hook invocation overwrites it.
This allows the dashboard to label panes by agent name rather than bash. It lets "needs you"
sort panes by blocked status, and provides the state required for alerts. Pane history also relies
on the beacon to supply the session key used by the journal.
Note. Beacons provide no control channel. A beacon only determines what Collie displays and queries. It cannot send text, inject keystrokes, rename panes, close sessions, or bypass access controls. The threat model and omitted fields are documented in ADR 0024.