Skip to content
Development
Skill

/tty7

Drive the tty7 terminal workbench from the shell with the `tty7` binary — list workspaces/tabs/panes, split a pane, send keystrokes into one, capture what is on a pane's screen, run a command in a real PTY and pass its exit code through, see which coding agents are running and

From plugin
tty7
6241 skill
Install
$ npx -y skills add l0ng-ai/tty7 --skill tty7 --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/tty7

Context preview

The summary Claude sees to decide when to auto-load this skill.

Drive the tty7 terminal workbench from the shell with the `tty7` binary — list workspaces/tabs/panes, split a pane, send keystrokes into one, capture what is on a pane's screen, run a command in a real PTY and pass its exit code through, see which coding agents are running and

SKILL.md

tty7.SKILL.md
name: tty7
description: >-
  Drive the tty7 terminal workbench from the shell with the `tty7` binary — list workspaces/tabs/panes, split a pane, send keystrokes into one, capture what is on a pane's screen, run a command in a real PTY and pass its exit code through, see which coding agents are running and which ports a pane is listening on. Use this whenever tty7, panes, workspaces, or `%42`/`@7`/"the other pane"/"the other agent" come up; whenever you need to start something long-running or interactive (dev server, REPL, ssh session, `tail -f`, a TUI) that should not sit blocking your Bash tool; whenever a program needs a real terminal to behave the way the user sees it; and whenever you need to look at or report on what is running in some *other* terminal on this machine. Cheap to check: if `$TTY7_PANE` is set you are already inside tty7 and every command here works with no setup.

Driving tty7 from the command line

`tty7` is a thin, non-interactive client of the tty7 server. Every verb returns and exits; `--json` makes the output machine-readable. The GUI never has to be running — the server is what owns the panes.

First: where are you?

tty7 doctor

One table, and it answers everything you need before doing anything else: whether a server is reachable, whether the dialect matches, and whether `TTY7_CONFIG_DIR` / `TTY7_WS` / `TTY7_PANE` are set — i.e. whether you are running *inside* a tty7 pane.

Being inside a pane matters for two reasons: the address-taking verbs (`split`, `send`, `capture`, `procs`) default to `$TTY7_PANE`, and `run --keep` files its pane into `$TTY7_WS`. Outside a tty7 shell you must name a target explicitly, and the error will say so rather than guessing.

If `tty7 doctor` says the server is unreachable, stop and tell the user — do not run `tty7 server start` on your own initiative. Starting a server they didn't ask for changes what their GUI attaches to.

When to use this instead of the Bash tool

The Bash tool is right for anything that starts, does its job, and exits. Reach for tty7 when one of these is true:

  • **It shouldn't block you.** A dev server, a watcher, `tail -f`, a long test

run you want to check on later. Put it in a pane, come back and read it.

  • **It's interactive or stateful.** A REPL, `ssh`, a database shell, anything

where you send one thing, read the answer, then send the next. A pane keeps the session alive between your turns; a Bash call cannot.

  • **It needs a real TTY.** Programs that detect a pipe and change behaviour —

colour, progress bars, TUIs, `top`, anything using raw mode. `tty7 run` gives a genuine PTY at 120×30.

  • **The user should be able to watch it.** Anything in a pane shows up in their

tty7 window, live. That is often the whole point.

  • **You're being asked about something you didn't start.** "What's running in

that pane?", "why is port 3000 taken?", "what are my agents doing?" — you can answer those from here without touching anything.

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 a workspace or tab appears or disappears | | `api` / `76698a44` / a full UUID | a workspace, by name, by unique id prefix, or by id | yes |

Re-resolve `@N` right before you use it; never cache one across a step that creates or removes a tab. Pane ids and workspace ids are safe to remember.

Omitting the address inside a tty7 shell means "this pane" / "this workspace". An explicit address always wins over the environment.

Running a command: two shapes

Blocking, with a real exit code

tty7 run -- cargo test          # streams to your stdout, exits with cargo's code
tty7 run --cwd /path -- make
tty7 run --keep -- cargo build  # leaves the pane as a new tab afterwards

The command's output streams to your stdout as it happens, and `tty7` exits with the command's own exit code. This is the closest thing to a Bash call — the difference is the PTY and the fact that the user can see it.

Two things to know. `--keep` needs a workspace, so it only works inside a tty7 shell or with `--ws <workspace>`. And with `--json`, the streamed output comes first and the JSON object last — the combined stream is *not* parseable as JSON, so read the last line.

Non-blocking: a pane you talk to over time

This is the one that makes tty7 worth reaching for. Get a pane, send it work, come back later.

PANE=$(tty7 split --v)                  # or --h; splits $TTY7_PANE, prints "%83"
tty7 send "$PANE" 'npm run dev' --enter

`split` prints the new pane's address on stdout, which is what you capture into a variable. Without an axis it is a usage error — `--v` stacks the new pane below, `--h` puts it to the right.

Splitting `$TTY7_PANE` changes the user's visible layout, which is usually the point: they can watch the dev server you started. Say that you did it, and close the pane when you're done with it.

If you are *not* inside a tty7 pane there is nothing to split, so make your own place to work first. `tty7 new --json /path/to/repo` hands you both ids at once — don't go digging through `ws tree` for the pane:

read -r WS PANE < <(tty7 new --json /path/to/repo \
  | python3 -c 'import json,sys; d=json.load(sys.stdin); print(d["id"], "%%%d" % d["pane"])')

`send` types text into the pane exactly as a keyboard would; `--enter` appends the carriage return. It does not wait and it does not tell you what happened — reading is a separate step.

Reading a pane

If you want the screen, use `--plain`

tty7 capture %83 --plain

`capture` hands back what the daemon stored — the pane's bytes, escapes and all — and `--plain` replays them through a terminal grid and prints the resulting text instead. Not a stripper: colour and cursor escapes are gone, but also a line the shell wrapped at column 249 com

Read more
Ships withtty7

A terminal workbench in pure Rust: shells, persistent sessions, SSH, coding agents. GPU-rendered on Zed's gpui, VT core from Alacritty.

Get the whole plugin
Stats
625
Stars
44
Forks
Active
Maintenance
Rust
Language
Apache-2.0
License
1h ago
Last commit
1mo ago
Created

Repo: l0ng-ai/tty7