Start here:
termdeck doctorIt prints the resolved host/port, data directory, file root, shell, and every external program TermDeck looked for — with the install command for anything missing.
TermDeck refuses to start without its hard dependencies rather than failing later in a confusing way. The
error names each missing program and how to install it. Most often it is dtach:
brew install dtach # macOS, Linuxbrew
sudo apt install dtach # Debian, UbuntuThe install directory isn't on your PATH.
| Installed with | Fix |
|---|---|
| uv | uv tool update-shell, then restart your shell |
| pipx | pipx ensurepath, then restart your shell |
| pip | Use python3 -m termdeck, or add the user script directory to PATH |
| Homebrew | brew doctor — Homebrew's bin should already be on PATH |
Something already holds port 8530 — most likely a TermDeck you forgot about.
lsof -nP -iTCP:8530 -sTCP:LISTEN # who has it
termdeck service status # is it the service?
termdeck --port 8531 # or just use another portHard-reload the browser (⌘⇧R / ⌃⇧R). If it persists, check the browser console for a failed asset load and open an issue with what it says.
The command couldn't be executed. The message carries the underlying error. Usual causes: the agent CLI isn't
installed or isn't on the login shell's PATH, or the working directory no longer exists.
Check what a login shell actually sees:
zsh -ilc 'which claude codex; echo $PATH'Sessions live in sessions.json inside the data directory. If you started TermDeck with a different
--data-dir (or a different TERMDECK_DATA_DIR in a service unit) it will look in the wrong place.
termdeck doctor # shows the data dir actually in use
ls ~/.termdeck/sessions.jsonUse ⟳ in the topbar to restart it. That kills the process group and respawns with resume, so an agent session is preserved.
The server preserves live terminals through a normal restart and saves a scrollback snapshot. If the computer restarted, opening the saved terminal restores that snapshot before starting a new process. For agent terminals, the resume command also restores the conversation; shell history remains the shell's own history.
An interactive agent session only gets an ID once the first message is sent — the CLI creates its session file lazily. If you open a terminal, type nothing, and restart, there is no session to resume, so the original command runs again.
Check what TermDeck recorded:
python3 -m json.tool ~/.termdeck/sessions.json | grep -A1 agent_session_idCodex holds its session file open, so attribution via lsof is exact. Claude doesn't, so picker-resumes and
/clear are attributed by watching ~/.claude/projects/<munged-cwd>/ for new files and crediting the
terminal most recently typed into. Two Claude terminals in the same directory, switching sessions at the
same moment, can rarely be mis-attributed.
Workaround: give concurrent Claude terminals different working directories, or set the session explicitly with the Resume existing session field when opening a terminal.
The resume flag is appended to the whole command string, so claude or codex has to be last:
| Command | Works? |
|---|---|
claude |
yes |
cd project && claude |
yes |
claude --model opus |
yes |
claude; echo done |
no — the flag lands after echo done |
Drafts are persisted on a 2-second debounce, so the last couple of seconds of typing before a hard kill can be lost. Enter and Ctrl-C intentionally clear the draft. Drafts are replayed a few seconds after the CLI boots — if the CLI is slow to start, the paste may land early; press ⟳ to restart the terminal.
ripgrep is missing or wasn't found. termdeck doctor will show rg as missing. Install it, or point
TermDeck at it directly:
export TERMDECK_RG_BIN=/custom/path/to/rgAlso check the glob filter box — a leftover filter like *.py silently narrows every search.
The file browser is confined to TERMDECK_FILE_ROOT (your home directory by default). Symlinks that resolve
outside the root are rejected too.
Files over 2 MB and files detected as binary are refused by design.
To the system trash: ~/.Trash on macOS, ~/.local/share/Trash/files on Linux. Never rm. If the trash is
on a different filesystem than the file, the move can fail — delete it from your file manager instead.
termdeck service status
termdeck service logsOn macOS the log is ~/.termdeck/termdeck.log; on Linux, journalctl --user -u termdeck. TermDeck trims
that file back to its last 2 MB whenever it passes 5 MB, so only the recent history is kept — copy
anything older out before it is dropped.
systemd user units end with the session unless lingering is enabled:
sudo loginctl enable-linger $USERThe unit file records an absolute path to the interpreter or console script that installed it. If that path moved, regenerate the unit:
termdeck service installlaunchd and systemd start services with a minimal PATH. TermDeck falls back to well-known directories, but
if yours is installed somewhere unusual, pin it and reinstall the service:
TERMDECK_DTACH_BIN=/custom/path/dtach termdeck service installThe variable is copied into the unit's environment block.
Open an issue at https://github.com/danialfarid/termdeck/issues with:
- The diagnostics bundle from the CPU/memory readout's Maintenance menu. It packages version, dependency, terminal-process, language-server, remote-state, and bounded log information while excluding terminal text, prompts, source files, project paths, titles, and credentials.
- For an intermittent browser-layout problem, start Record diagnostics for a bug report first, reproduce it, stop recording, then download the bundle so the latest geometry trace is included.
- What you did, what happened, what you expected