hty send
Deliver input to a running session’s PTY, exactly as if a user had typed it. You can send plain text, symbolic key names, raw bytes, or a sequenced combination of all three.
The <session> argument accepts a session name, a full UUID, or a unique UUID prefix. If only one session is running, you can omit it.
Reference
hty send [SESSION] --text "..." | --raw-text "..." | --key NAME | --seq "..." | --bytes-hex HEX
| --click ROW COL | --scroll up|down
Send input to a session. Exactly one of --text, --raw-text, --key,
--seq, --bytes-hex, --click, --scroll is required.
Flags:
--text STRING UTF-8 text with C-style escapes (\n \t \r \\ \e).
--raw-text STRING UTF-8 bytes sent verbatim. No escape processing —
`\n` stays as literal backslash-n. Use this when
you want to type source code or other content that
contains backslashes you don't want interpreted.
Prefer over --text when shell quoting gets hairy.
--key NAME Named key with optional modifiers.
Supports ctrl-, alt-/meta-, shift- prefixes,
function keys (f1-f12), and combinations like
ctrl-alt-f or shift-up. Run `hty keys` for details.
--seq STRING Send a sequence of keys, text, and delays in one call.
Quoted strings are text, durations (e.g. 200ms, 1s)
are pauses, and bare words are key names.
Example: --seq '"hello" 200ms enter 500ms "world"'
--bytes-hex HEX Raw bytes encoded as hex.
Mouse input (issue #24). Rows and columns are 1-indexed, matching
snapshot conventions. The target app must have enabled mouse mode
(the usual `CSI ?1000/1002/1003 h` sequences); otherwise the
command fails with "target app has not enabled mouse input". Check
`hty snapshot --json`'s `mouse.enabled` to verify.
--click ROW COL Click at ROW/COL. Defaults to left button;
combine with --button to change.
--scroll up|down Scroll at the cursor (or --at ROW COL); emits
--amount N events (default 1).
--button B Button for --click: left (default),
right, middle.
--at ROW COL Row/col for --scroll. Defaults to 1 1.
--amount N Repeat count for --scroll. Default 1.
Delay flags (optional, combine with any mode above):
--delay-before DUR Sleep before sending (e.g. 200ms, 1s).
--delay-after DUR Sleep after sending.
--delay-char DUR Send text character-by-character with a delay
between each. Only works with --text, --raw-text,
or --seq.
Wait + snapshot flags (fuse send + wait + snapshot into one round-trip):
--snapshot Include the post-action snapshot in the response.
Combines with --json and --ansi like `hty snapshot`.
--wait-duration DUR Sleep DUR after sending, then snapshot. Requires
--snapshot (otherwise use --delay-after).
--wait-until-idle [MS]
Block until the screen has been quiet for MS
milliseconds (default 100). The idle window is
measured from the moment this op begins on the
server, so a session that was already quiet
before the send won't trip the check immediately.
--wait-until-text STR Block until STR appears in the rendered buffer.
--wait-until-regex RE Block until RE (POSIX extended) matches.
--wait-until-exit Block until the child process exits.
--timeout DUR Cap on any --wait-until-* (default 30s; 0 = none).
--json With --snapshot, emit `{ok, matched, elapsed_ms,
snapshot, ...}` instead of the plain buffer.
--ansi With --snapshot, print the styled ANSI rendering
instead of the plain buffer.
Examples
# Type into an insert-mode editor
hty send my-session --text "ihello world"
# Confirm a yes/no prompt
hty send my-session --text "y\n"
# Press Escape
hty send my-session --key esc
# Send Ctrl-C
hty send my-session --key ctrl-c
# Type text, then press enter after 200ms
hty send my-session --seq '"hello" 200ms enter'
# Send raw bytes (the up-arrow escape sequence)
hty send my-session --bytes-hex "1b5b41"--text vs. --raw-text
--text processes C-style escapes — \n becomes a newline, \t a tab, \e the Escape byte, \\ a literal backslash. That’s what you usually want for typing commands, pressing Enter, etc.
--raw-text sends the UTF-8 bytes verbatim with no escape processing. Use it when you want to type content that contains backslashes you don’t want interpreted — for example, pasting source code, regex patterns, or shell snippets into an editor:
# With --text, the \n would be turned into a real newline
hty send my-session --raw-text "const re = /\\n/;"Prefer --raw-text whenever shell quoting of backslashes gets painful.
Mouse input
For TUIs that opt into mouse tracking (btop, lazygit, k9s, tmux, many fzf layouts), hty send can deliver click and scroll events. Rows and columns are 1-indexed, matching hty snapshot.
# Left-click at row 5, column 12
hty send my-session --click 5 12
# Right-click
hty send my-session --click 5 12 --button right
# Scroll down three times at the default position
hty send my-session --scroll down --amount 3
# Scroll up at a specific cell
hty send my-session --scroll up --at 10 40hty sniffs the CSI ?1000/1002/1003 h/l (event set) and ?1006 h/l (SGR extended) toggles out of the PTY output stream to track per-session mouse state. send --click uses SGR encoding when the app has enabled ?1006, and legacy X10 otherwise. If an X10-only app receives coordinates past column/row 223 (past the 1-byte X10 range), the send fails with a clear error rather than silently truncating or upgrading the encoding to something the app can’t parse.
If the target app has not enabled any mouse-event mode, the command fails with target app has not enabled mouse input. Check hty snapshot --json’s snapshot.mouse.enabled field to verify before sending.
Fused send + wait + snapshot
For agent workflows, the common pattern is “type something, wait for the program to settle, then read the screen.” Instead of three round-trips (send, wait, snapshot), you can fuse them into one by combining --snapshot with a --wait-* flag:
# Type a command, wait for the screen to go idle for 200ms, read it back
hty send my-session --text "git status\n" \
--snapshot --wait-until-idle 200 --json
# Press Enter and wait for a specific string to appear
hty send my-session --key enter \
--snapshot --wait-until-text "press any key" --timeout 5000
# Submit and wait for a regex match, returning styled ANSI
hty send my-session --text "help\n" \
--snapshot --wait-until-regex "^(ERROR|OK):" --ansiThe response format follows hty snapshot — plain buffer by default, JSON with --json, styled ANSI with --ansi. With --json you also get matched, elapsed_ms, and timeout info, so an agent can tell whether the wait succeeded without a second call.
| Flag | Effect |
|---|---|
--snapshot | Include the post-action screen in the response. Required for any of the flags below. |
--wait-duration DUR | Sleep DUR after sending, then snapshot. Use for programs that don’t produce observable output. |
--wait-until-idle [MS] | Wait until the screen has been quiet for MS ms (default 100). Idle is measured from when the op starts on the server, so a session that was already idle won’t trip the check. |
--wait-until-text STR | Wait until STR appears in the rendered buffer. |
--wait-until-regex RE | Wait until RE (POSIX extended) matches. |
--wait-until-exit | Wait until the child process exits. |
--timeout DUR | Cap on any --wait-until-* (default 30s; 0 = no cap). |
--json / --ansi | Output format for the included snapshot. |
Every input sent via hty send is recorded in the session log as an input event, making sessions fully reproducible and auditable.