Core concepts
How Termdeck works
Two moving parts, one rule. The rule is that the machine that runs your code is the machine that holds your work, and everything else is a view onto it.
The picture
The master
The master is the service at termdeck.io. It serves the web app, holds your account and billing, keeps the list of your machines, and routes messages between your browser and the right agent.
What it does not do is as important. It stores no transcripts. It runs no coding CLI. It has no copy of your code. When you open a chat, the master does not read it out of a database, it asks the machine that owns it and streams the answer through.
The agent
The agent is a small Node program in ~/.termdeck/agent with two dependencies. On start it dials out to the master, authenticates with the machine token, and holds that socket open. While it is connected, the machine shows online.
The agent is deliberately not a general purpose remote shell. It answers a fixed list of typed requests and nothing else:
- Read, stat, list, and watch files, confined to the transcript directories of the installed engines.
- Browse and read files inside the project folder a chat was opened in, read only.
- Start one of the three known engines, write to its standard input, read its output, and stop it.
- Report machine facts: which CLIs are installed, whether they are signed in, current rate limits, agent log.
- Switch which saved Claude or ChatGPT account the machine uses for new turns.
There is no "run this command" capability. A request that is not on the list has no handler, whatever it says. That is the boundary the design is built around: even a fully compromised master could not read arbitrary files or run arbitrary programs on your machine.
Disk is the source of truth
Each engine already writes its own history to your machine. Claude writes JSON lines under ~/.claude/projects. Codex writes rollout files under its session directory. Grok keeps its own session files.
Termdeck renders from those files. That single decision produces most of the properties people notice:
| Because Termdeck reads the CLI's own files | You get |
|---|---|
| A chat started in a terminal writes the same file | It appears in the browser, in full, with no import step |
| A chat driven from the browser writes the same file | claude --resume and codex resume pick it up in a terminal |
| The file survives the process | Closing the tab, losing wifi, or a server restart cannot lose a transcript |
| Termdeck holds no copy | Uninstalling the agent leaves your history exactly where it was |
The live stream from a running CLI adds only what a file cannot carry: tokens arriving one at a time, a permission prompt waiting for an answer, and whether a run is currently alive.
What happens when you send a prompt
-
The browser sends the turn to the master
Over the same authenticated WebSocket the interface already uses, tagged with the machine and the session.
-
The master asks that machine's agent to start the engine
With the model, permission mode, and any per turn options you chose. The engine runs as you, in your project folder, under your subscription.
-
Output streams back through the same socket
Token deltas, tool calls, results, and errors. The browser renders them as they land.
-
A tool call that needs permission stops and asks
Your rules are checked on the machine first. If they do not cover it, the request becomes a card in the browser and, if you turned it on, a push notification. Nothing runs until you answer.
-
The engine writes the turn to disk
Which is what makes it permanent, resumable in a terminal, and readable from any other device you sign in on.
What survives a connection drop
The link and the work have separate lifetimes on purpose. When the socket to the master goes away, whether from wifi, a laptop lid, or a Termdeck deployment, the agent does not kill the running CLI. It parks it: the process keeps working and its output is buffered until the link comes back, at which point the browser is caught up and the run continues.
Parked runs are held for a few minutes. If nobody reconnects in that window the child is reaped, and the transcript on disk still holds everything it wrote. In practice a Termdeck release looks like a pause of a few seconds in a running Claude turn rather than a lost run.
Machines, not addresses
Every route in the interface is keyed on a machine name, never on an IP address or a session id alone. That is why a machine can move to new hardware, change networks, or sit behind three layers of NAT without anything in your saved links breaking. It is also why session ids never collide between accounts: nothing is ever addressed by a bare id.
There is no self hosted Termdeck server to run. The parts that must be local already are: the agent, the CLI, the credentials, the repository, and the transcript. Adding a local server would only move the web app, which is the one piece that holds nothing.