Surfaces & I/O
Surface lifecycle and I/O — splitting panes, focusing them, sending keystrokes, reading the visible buffer.
list-surfaces
Section titled “list-surfaces”ht list-surfaces# surface:1 ws:0 ~/code/foo bun run dev# surface:2 ws:0 ~/code/bar zsh# surface:3 ws:1 ~/code/docs astro devnew-split
Section titled “new-split”ht new-split right # left | right | up | downht new-split right --cwd ~/code/fooht new-split down --shell /bin/zshCreates a new terminal surface as a split of the focused (or --surface-targeted) pane. Optional flags:
--cwd <path>— initial working directory.--shell <path>— override the shell binary for this surface only.--ratio 0.6— split ratio.
rename-surface
Section titled “rename-surface”ht rename-surface "build watcher"ht rename-surface --surface surface:3 "api server"Sets the pane’s display title. Without --surface it renames the pane you are
in (HT_SURFACE), falling back to the focused pane. A renamed pane ignores
OSC 0/2 title escapes from then on, so the name you set sticks.
list-panes
Section titled “list-panes”ht list-panesThe pane tree of the active workspace (split directions and ratios), as
opposed to list-surfaces which is a flat list.
list-panels
Section titled “list-panels”ht list-panelsht list-panels --surface surface:2Canvas panels currently open in a surface.
list-browsers
Section titled “list-browsers”ht list-browsersEvery browser pane with its id and current URL.
editor
Section titled “editor”ht edit src/index.ts # open in an editor splitht editor open src/index.ts [--split]ht editor split src/index.ts [--direction right|down] [--create]ht editor listht editor save|reload|close [editor:N]CodeMirror editor panes. --create
makes a missing file, --cwd resolves a relative path.
ht agent create # pi agent pane in a new workspaceht agent create-split [right|down]ht agent listht agent countht agent close --agent <id>The pi coding-agent pane. For Claude Code panes see
ht claude pane.
run-script
Section titled “run-script”ht run-script --command "bun run dev" --cwd ~/code/appRuns a command the way the sidebar’s script buttons do — in a real pane you can
watch. --workspace targets a workspace, --script-key sets the key used to
track running state on the workspace card.
close-surface
Section titled “close-surface”ht close-surfaceht close-surface --surface surface:3Closes the targeted surface (defaults to focused). Shell receives SIGHUP.
focus-surface
Section titled “focus-surface”ht focus-surface --surface surface:3wait-ready
Section titled “wait-ready”ht wait-ready # wait on the focused surfaceht wait-ready --surface surface:7 # explicit targetht wait-ready --surface surface:7 --timeout-ms 5000Block until the targeted surface’s metadata is observable (the 1 Hz poller has produced its first snapshot), then print the snapshot. Returns null on timeout. Default timeout is 2000 ms; capped at 30 000 ms.
Use it to synchronize automation that races the post-spawn metadata poll — e.g. spawning a pane and immediately calling ht open. Naive scripts don’t need this anymore: ht open and ht kill now wait up to 2 s internally before erroring out. Reach for wait-ready only when you want to pin the exact moment yourself.
ht send "echo hello\n"ht send --surface surface:3 "ls\n"Sends raw text to the surface’s PTY. The string is unescaped before being written, so the following sequences are interpreted:
| Escape | Sent as | Use for |
|---|---|---|
\n | \r (CR) | Submit a command — terminals expect carriage return, not line feed. |
\r | \r (CR) | Same as \n; explicit form for scripts that already produce CR. |
\t | \t (HT) | Tab — autocomplete, field navigation. |
\x1b | \x1b (ESC) | Escape — leave insert mode in vim, dismiss menus. |
\\ | \ | Literal backslash. |
Anything else passes through verbatim. Quote the argument with double quotes (or your shell’s preferred form) so the backslashes survive shell parsing intact.
send-key
Section titled “send-key”ht send-key enterht send-key tabht send-key arrow-upht send-key ctrl+cSymbolic keys for things that are awkward to escape. Supports modifiers (shift+, ctrl+, alt+, cmd+) and named keys (enter, tab, escape, arrow-up/down/left/right, home, end, page-up/down, f1 … f12).
read-screen
Section titled “read-screen”ht read-screen --lines 20ht read-screen --scrollback true # include scrollback bufferht read-screen --jsonReads the current visible terminal buffer. Useful for agents tailing log output or for screenshots-as-text. With --scrollback true, includes everything in scrollback (up to scrollbackLines setting).
screenshot
Section titled “screenshot”ht screenshot # the focused paneht screenshot --surface surface:3 # a specific paneht screenshot workspace # all panes of the active workspaceht screenshot workspace ws:2 # all panes of a specific workspaceht screenshot window # the whole app windowht screenshot workspace --output ~/Desktop/ws.pngCaptures a PNG, then crops to one of three targets:
- (default) the focused pane — or
--surface <id>/$HT_SURFACE. workspace— the bounding box of every visible pane in a workspace (excludes titlebar + sidebar). Targets the active workspace, or a specific one via a trailing id /--workspace <id>. Only the active workspace’s panes are visible to the capture; a background workspace falls back to the whole-window grab.window(or--full-window) — the whole app window, uncropped (titlebar + sidebar). Useful for bug reports.
Output path is optional (--output / -o); omitted, a timestamped PNG lands in the system tmpdir. The resulting path is printed. macOS only (uses screencapture). Captures the rendered xterm.js canvas plus any overlay panels.
tmux compat
Section titled “tmux compat”ht capture-pane --lines 50 # alias for read-screen