Dev Terminals
- Desktop, mobile and web
- All plans
What it does
A per-project terminal manager that lives next to your agents. Every command a project needs (dev server, backend, mobile bundler, Docker, worker, tests) is saved once, sorted in folders with a framework icon, and started in one click in a real terminal at the right working directory. A command is either a Process (a long-running service, included in "Start all") or a Snippet (a one-shot command run by hand). You can also open blank shells, split panes, detach the whole terminal strip to a floating window on a second screen, arm a bell that notifies you when a long command finishes, and start any saved command from your phone while the output streams back to it.
Where to find it
- Inside a project, the terminal bar at the bottom of the room carries four buttons: New terminal (empty shell at the project root), Commands (your saved commands), Servers and Databases. The bar stays visible even with zero tab open.
- The room dock: Commands & connections ("Commands · Servers · Databases · Secrets").
- Command palette (Cmd K / Ctrl K): a command result starts it or refocuses its tab (prefix
>). - Detach: the detach icon of the terminal strip opens it in its own window; Reattach terminals to the main window brings it back.
- Feature switch: Settings > Features > Dev Commands.
- The same bar also lists, after your local tabs, the terminals open in this project on your other online machines (same account), with the machine's name after the tab name; clicking one follows it under the banner "Remote terminal on <device>". Detail in Remote Fleet.
How to use it
- Open Commands and click New Command: name, command line, working directory (relative to the project root), folder, Type (Process or Snippet), Auto-execute on click (off = the line is typed but not run), category, and scope (this project only, or every project of your account).
- Or click the magic wand (Auto-detect project commands with AI): an agent reads package.json, Dockerfiles, Makefiles and similar files and fills the list with the persistent services it finds.
- Press Start on a command (or the global start button for every Process). The tab shows a dot: busy, idle, or nothing when the state is not known yet. Running commands are pinned at the top of the list.
- Bell: each pane label has a bell. Arm it and you get a desktop notification (and a push on your phone) when the command running there hands back to the prompt, with its name and duration.
- Restart: the label's restart button kills what runs in that pane and retypes the command (or, for a blank shell, the last line you typed, shown in the tooltip first).
- Stop: while a command is detected running in a pane, a Stop button (filled square) sits on its label between the bell and Restart. It interrupts the command exactly like pressing Ctrl+C; the terminal stays open at its prompt with its output. It is hidden when nothing runs. Available in the main window and in the detached one.
- Tidy up: the eraser opens Tidy up terminals with three actions: close the finished ones, close duplicates of the same command, close every terminal. The tab's context menu also offers Close this tab when the command ends.
- Right-click a pane for Copy (greyed when nothing is selected) and Paste at the top, then Clear buffer, Restart, Settings and Split right / Split down, or Remove from split. The menu opens on every right-click, selection included, in dev command terminals, agent terminals and remote terminals alike (since 2026-09-24; before, a right-click over a selection did nothing). Since 2026-10-01 a right-click over a selection also copies it at once, as in VS Code: the menu still opens and its first row shows Copied with a check, so there is no second click to copy. Only a selection made before the right-click is copied, so on macOS the word the right-click selects by itself never overwrites your clipboard. A right-click without a selection does not paste directly: use Paste in the menu. Tabs can be dragged between panes, in the main window and in the detached one.
Public commands are stored in .agentsroom/commands.json (commit it, the team gets the setup). Personal commands go to commands-personal.json, gitignored automatically. Use Duplicate command to start a copy from an existing one. Search covers name, command, folder, category and type, with a All / This project / Global filter.
Settings
terminalCommandAlerts(global, Settings > Notifications > Terminal command alerts): notify when a long command finishes. On by default. Project override in Project settings > Terminals ("Notify me when a long command finishes"); the bell on each tab overrides both (commandAlertOverrides, read-only, written by the bell).commandCloseOnFinish(project, read-only): the per-terminal "close this tab when the command ends" choices, written from the tab menu.openCommandsInSamePaneandopenCommandsSplitDirection(global, also as Open commands in the same pane in the Commands modal): new commands open as a split of the focused pane instead of a new tab.restoreDevCommands(global, Restore commands on launch in the Commands modal; a project can override it): re-launch the command terminals that were still running when the app closed. Commands that had already finished come back as idle tabs. Off by default.terminalStartupCommand,terminalFontFamily,terminalThemeOverride,terminalGpuAcceleration,terminalLinkTarget(global, Settings > Terminal): apply to every terminal, dev terminals included.
Agent tools (MCP)
commands_list/commands_get: the saved commands of both scopes, each withrunningand the ids of its live tabs, plus the open terminals that have no saved command behind them.commands_create: save a command (scope: "project" | "global"); refuses a line + directory already saved and returns the existing id.commands_run: start a command in a visible tab; refuses one that already has a live tab unlessallowDuplicateis set. The tab shows the agent's avatar ("Command launched by X").commands_output: the last lines a live tab printed, ANSI stripped (80 by default, 300 max).commandIdaccepts a saved command id, a tab id, a PTY id or the connection id of an SSH tab. When the same command has several live tabs,ptyIdpicks one; without it the most recently opened tab is read, and the answer lists every live tab id. AptyIdthat matches no live tab is refused, never silently replaced by another tab. Refused for a command whose line contains a{{secret:NAME}}reference. An SSH tab can be read but not typed into.commands_propose: ask you to run one shell line the agent's own sandbox refused. Nothing runs until you click Play on the card in that agent's panel; the tab it opens is a throwaway, never saved and never restored. See Command Proposal.
Providers
All providers, no difference for running commands. The magic-wand auto-detection launches a Claude agent to scan the project.
Mobile
Yes, and in both directions. The project screen lists the saved commands (project and global); starting one creates the terminal on the desktop and streams the output to the phone over the encrypted relay, with the same busy/idle dot and the launching agent's avatar on the tab. A throwaway terminal opened from the phone also appears as a tab on the computer, sharing the same process, the same scrollback and the same take-over, so a command started from the sofa can be picked up at the keyboard. Not on the phone: tidy-up menu, close-on-finish, split panes, detached window. The Fleet view of another machine also lists that machine's open terminals, one row per tab ("<device> · terminal"), and a tap follows it; see Remote Fleet.
Limits
- Free plan: 2 saved commands running at once; Plus: 3; Pro and Team: unlimited. Blank shells never count.
- The bell only knows "finished", not "succeeded": there is no exit code. Commands shorter than a minute stay silent unless the bell was armed while the command was already running. Nothing fires while you are looking at that terminal. What runs inside
ssh,tmuxordocker execis invisible to it;cmd &counts as finished immediately. - Close-on-finish closes on failure as well as success, which is why it is off by default and per terminal only.
- The detached window layout is not persisted across restarts.
- Windows: the finished-command detection polls the shell's descendants (no foreground process group), so it runs as long as a dev terminal is open and alerts are on.
- Remote tabs from other machines are a projection: no close, no drag, no split with a local tab, not shown in the detached window, gone when their machine goes offline. Stopping what runs there is done on that machine.
Common questions
- How does it know a command finished if the tab stays open? It watches the terminal's foreground process group: when it returns to the shell, the prompt is back. Nothing is written into your shell configuration.
- Why did an agent's command refuse to start? It was already running:
commands_runreturns the live tab instead of opening a second one. The agent can read it withcommands_output. - Where are the commands shared with the team?
.agentsroom/commands.jsonin the project. Personal ones are incommands-personal.json, gitignored. - Can a command exist in every project? Yes: choose the global scope when saving. Its working directory is still resolved against the current project.
- My auto-executed command lost its first character (
PORT=8811 npm run devran asORT=8811 npm run dev). Fixed after 1.173.0. The line used to be typed a fixed 300 ms after the shell opened, inside the window where a slow startup file could still swallow a keystroke, so it happened only now and then. It is now typed once the shell has printed its prompt and gone quiet (2 seconds at most), whatever the shell. - After restarting the app, my command tabs are back but nothing runs. Expected since 2026-09-24. Restoring the previous session reopens the tabs and their layout idle: press Start on the ones you need. To have the servers that were running re-launched on their own, turn on Restore commands on launch in the Commands modal; even then, a command that had finished (a test run, a one-shot script) comes back idle.
- How do I stop a dev server without closing its tab? Click Stop on the pane label (or press Ctrl+C in the terminal). Restart stops and re-runs it; closing the tab ends the shell.
- Text is clipped at the bottom of a terminal. Turn off GPU acceleration in Settings > Terminal, or resize the pane once.
- A tab in my terminal bar carries the name of my other computer. It is a terminal open there in the same project (since 1.182.0). Click it to read and type into it; it is not a local tab. See Remote Fleet.
- An agent read the wrong terminal after starting a second copy of a command. Fixed: a named tab is now found or refused, never swapped for an older tab of the same command, and without a tab id the most recently opened one is read.
- How do I copy and paste in a terminal with the mouse? Select the text and right-click: it is copied already (the menu shows Copied); right-click, Paste to type the clipboard into the terminal. Keyboard shortcuts are unchanged (Cmd+C / Ctrl+Shift+C to copy, Cmd+V / Ctrl+V to paste). An empty clipboard or one that holds only an image pastes nothing.
Related
- Process Guard: watches the child processes of agents, never dev terminals.
- Localhost Tunnel: expose a server started here on a public URL.
- SSH Connections: remote terminals share the same tab strip.
- Secret Manager:
{{secret:NAME}}in a command line is substituted at launch. - Command Palette: start a command from Cmd K.
- Command Proposal: an agent asking you to run a one-off line its sandbox refused.
- Remote Fleet: the terminals of your other machines shown in this bar.