Files
tty7/docs/cli/overview.mdx
T
l0ng-ai 00e1aa8218 docs: correct claims that no longer match the code
Audited every page under docs/ against the source. Fixes for what the
code actually does:

- agents: the status vocabulary is idle/working/waiting/done, not
  running/waiting/idle; hook rows grow a separate Uninstall button; the
  Settings table labels read "Copilot CLI" and "Grok Build"; Copy Session
  ID lives in the tab's context menu, not the pane's
- cli: `pane ls --all` reports the owning workspace id, not "tty7-cli";
  document bare `tty7 [PATH]` as the GUI launcher it is instead of listing
  it as unimplemented; note `active_tab` and the `diagnostics` array; wait
  also defaults to $TTY7_PANE
- git: the branch dropdown is a plain list with no search box and no
  stash-and-switch, and checkout is not a palette command; quote the diff
  overlay's own overflow notice rather than the sidebar's
- window: the unread marker tracks a finished agent turn, not any output;
  rows cannot be dragged across groups; the sidebar and `tty7 tab ls`
  resolve labels differently; drop Toggle Commit History and Checkout to
  from the palette's Git group; ~/.ssh/config aliases are not palette
  entries
- terminal: Ctrl+R dedups by command text and shows no directory; Esc does
  not dismiss a ghost suggestion; document Cmd+Enter
- remote: GSSAPI is an ordinary Auth choice, not a managed-connection-only
  mechanism
- fonts: Maple Mono NF CN leads the chain on Windows and Linux only; list
  the real per-platform defaults
- settings paths: the three Links settings and per-pane history were filed
  under the wrong sections
2026-08-11 14:35:54 +08:00

148 lines
4.8 KiB
Plaintext

---
title: "The tty7 command"
description: "Driving the workbench from a script, a Makefile, or another agent."
---
`tty7` is a thin, non-interactive client of the tty7 server. Every verb runs and
exits; `--json` makes the output machine-readable. **The GUI does not have to be
running** — the server is what owns the panes.
It ships inside every installer and is put on PATH at launch, so it works from
any terminal on the machine. [Installation →](/getting-started/installation#the-tty7-command)
## Start with `doctor`
```bash
tty7 doctor
```
One table that answers everything you need before doing anything else: whether a
server is reachable, whether its wire dialect matches this binary, and whether
`TTY7_CONFIG_DIR` / `TTY7_WS` / `TTY7_PANE` are set — that is, whether you are
running *inside* a tty7 pane.
Being inside a pane matters because the address-taking verbs (`split`, `send`,
`capture`, `procs`, `wait`, `pane close`) default to `$TTY7_PANE`, and
`run --keep` files its pane into `$TTY7_WS`. Outside one you must name a target,
and the error says so rather than guessing.
## Addresses
| Shape | Means | Stable? |
|---|---|---|
| `%42` | A pane | **Yes** — a pane keeps its id for its whole life |
| `@7` | A tab, numbered across the whole machine in tree order | **No** — it shifts whenever any workspace or tab appears or disappears |
| `api` · `76698a44` · a full UUID | A workspace, by name, unique id prefix, or id | Yes |
Re-resolve `@N` immediately before using it. Pane and workspace ids are safe to
remember.
## Two ways to run something
### Blocking, with a real exit code
```bash
tty7 run -- cargo test # streams to stdout, exits with cargo's code
tty7 run --cwd /path -- make
tty7 run --keep -- cargo build # leaves the pane behind as a new tab
```
The closest thing to running the command yourself — the difference is that it
gets a real PTY (so colour, progress bars, and TUIs behave), and that you can
watch it happen in the window.
<Note>
Everything after `--` belongs to the child: `tty7 run -- cargo test --keep`
passes `--keep` to cargo, not to tty7.
</Note>
### Non-blocking: a pane you talk to over time
This is the one worth reaching for. Get a pane, give it work, come back.
```bash
PANE=$(tty7 split --v) # or --h; prints "%83"
tty7 send "$PANE" 'npm run dev' --enter
# ... later
tty7 capture "$PANE" --plain
tty7 pane close "$PANE"
```
If you are not inside a tty7 pane there is nothing to split, so make your own
place to work:
```bash
tty7 new --json /path/to/repo # {"id": "...", "pane": 83}
```
## Reading a pane
```bash
tty7 capture %83 --plain
```
`capture` returns what the server stored. Without `--plain` that is the raw
bytes, escapes and all. With `--plain` those bytes are replayed through a real
terminal grid and you get the text that produced — which is not the same as
stripping escapes yourself:
- A line the shell wrapped at the pane width comes back as **one** line
- A progress bar that rewrote itself with `\r` reads as its **final** value
- Cursor addressing puts text **where the program put it**, so a TUI's screen
lands where it was drawn
Use `--plain` whenever a human would want to read the output.
<Warning>
A screen is a rectangle. Whatever scrolled off the top is gone, and an exit
code was never on it. When you want the *answer* rather than the *view*, have
the shell write it somewhere clean:
```bash
tty7 send "$PANE" 'cargo test > /tmp/t.log 2>&1; echo $? > /tmp/t.rc' --enter
```
</Warning>
## Knowing when something finished
```bash
tty7 procs %83
```
The process tree inside the pane, indented by depth, with `*` on the foreground
process — plus the ports those processes are listening on. **When the only entry
left is the depth-0 shell, the command is done.** That is far more reliable than
grepping the screen for a sentinel that can wrap or echo twice.
For agents specifically, use [`tty7 wait`](/agents/orchestration) instead of
polling.
## Looking around
```bash
tty7 ls # every workspace: tabs, panes, who's attached
tty7 ws tree api # one workspace as a tree
tty7 pane ls --all # every pane, including orphans no workspace holds
tty7 agents # every coding agent and its status
tty7 status # server pid, uptime, pane count, build, socket
tty7 machine ls # this machine plus any linked remotes
tty7 events # stream server events until interrupted
```
`--json` on any of them, `-q` to suppress success output (errors still print).
## Remote machines
```bash
tty7 -m devbox ls
tty7 -m devbox run -- cargo test
```
`-m` routes over a link the local server already holds. It will not dial a fresh
connection — connect from the GUI first.
[Remote workspaces →](/remote/workspaces)
<Card title="Full command reference" icon="book" href="/cli/reference">
Every verb, flag, and JSON shape.
</Card>