Urbit Interactive Terminal (screen/tmux)
Attach to and interact with a running Urbit ship's dojo terminal through screen or tmux sessions.
Step 1: Discover Ship Sessions
Scan for screen sessions
screen -ls 2>/dev/null | grep -iE '(zod|bus|nec|bud|wes|sev|per|sut|let|ful|pen|syt|dur|wep|ser|wyl|sun|ryp|syx|dyr|nup|heb|peg|lup|dep|urbit|ship|pier)' || echo "No urbit screen sessions found"
Scan for tmux sessions
tmux list-sessions 2>/dev/null | grep -iE '(zod|bus|nec|bud|wes|sev|per|sut|let|ful|pen|syt|dur|wep|ser|wyl|sun|ryp|syx|dyr|nup|heb|peg|lup|dep|urbit|ship|pier)' || echo "No urbit tmux sessions found"
Broad scan (all sessions)
If ship-name-based discovery finds nothing, list all sessions and ask the user which one:
screen -ls 2>/dev/null
tmux list-sessions 2>/dev/null
Detect session type
When the user provides a session name, determine which multiplexer owns it:
# Check screen first
screen -ls 2>/dev/null | grep -q "<SESSION>" && echo "screen" || \
(tmux has-session -t "<SESSION>" 2>/dev/null && echo "tmux" || echo "not found")
Step 2: Send Commands
Screen
Send a dojo command to a screen session:
# Send command followed by Enter
screen -S <SESSION> -X stuff '<DOJO-COMMAND>\n'
Examples:
screen -S zod -X stuff '+vats\n'
screen -S zod -X stuff '|pack\n'
screen -S zod -X stuff '-eval '\''(add 2 2)'\''\n'
Tmux
Send a dojo command to a tmux session:
# Send command followed by Enter
tmux send-keys -t <SESSION> '<DOJO-COMMAND>' Enter
Examples:
tmux send-keys -t zod '+vats' Enter
tmux send-keys -t zod '|pack' Enter
tmux send-keys -t zod "-eval '(add 2 2)'" Enter
Sending multi-line input
For screen:
# Send each line separately
screen -S <SESSION> -X stuff 'line1\n'
screen -S <SESSION> -X stuff 'line2\n'
For tmux:
tmux send-keys -t <SESSION> 'line1' Enter
tmux send-keys -t <SESSION> 'line2' Enter
Step 3: Capture Output
Screen — capture scrollback
# Capture scrollback to a temp file, then read it
screen -S <SESSION> -X hardcopy -h /tmp/urbit-screen-capture.txt
cat /tmp/urbit-screen-capture.txt
For just the last N lines:
screen -S <SESSION> -X hardcopy -h /tmp/urbit-screen-capture.txt
tail -n 50 /tmp/urbit-screen-capture.txt
Tmux — capture pane
# Capture visible pane content
tmux capture-pane -t <SESSION> -p
# Capture with scrollback history (last 500 lines)
tmux capture-pane -t <SESSION> -p -S -500
Strategy for command + capture
To send a command and read its output:
- Capture current scrollback length (baseline)
- Send the command
- Wait briefly for the command to complete
- Capture new scrollback and diff against baseline
# Tmux example: send command and capture output
tmux capture-pane -t <SESSION> -p -S -500 > /tmp/urbit-before.txt
tmux send-keys -t <SESSION> '<COMMAND>' Enter
sleep 2
tmux capture-pane -t <SESSION> -p -S -500 > /tmp/urbit-after.txt
diff /tmp/urbit-before.txt /tmp/urbit-after.txt | grep '^>' | sed 's/^> //'
# Screen example: send command and capture output
screen -S <SESSION> -X hardcopy -h /tmp/urbit-before.txt
screen -S <SESSION> -X stuff '<COMMAND>\n'
sleep 2
screen -S <SESSION> -X hardcopy -h /tmp/urbit-after.txt
diff /tmp/urbit-before.txt /tmp/urbit-after.txt | grep '^>' | sed 's/^> //'
Note: The sleep duration may need to be increased for long-running commands (e.g. |pack, |meld, +vats on large ships).
Dojo Command Reference
Generators (prefixed with +)
| Command | Description |
|---|---|
+vats | Show desk status and OTA info |
+code | Show web login code |
+trouble | Generate a trouble report |
+keys | Show Azimuth key information |
Hood generators (prefixed with |)
| Command | Description |
|---|---|
| ` | pack` |
| ` | meld` |
| ` | ota ~source %desk` |
| ` | ota %disable` |
| ` | install ~ship %desk` |
| ` | uninstall %desk` |
| ` | suspend %desk` |
| ` | revive %desk` |
| ` | bump` |
| ` | exit` |
| ` | mass` |
| ` | hi ~ship` |
| ` | pass` |
Threads (prefixed with -)
| Command | Description |
|---|---|
-eval '<hoon>' | Evaluate a Hoon expression |
-khan-eval '<thread>' | Run an inline thread |
Agent interaction (prefixed with :)
| Command | Description |
|---|---|
:agent +dbug | Debug an agent |
:agent &mark <data> | Poke an agent |
:dojo|allow-remote-login ~ship | Allow remote dojo access |
:dojo|acl | View remote access list |
Dojo-specific commands
| Command | Description |
|---|---|
=dir /path | Change working directory |
+ls /path | List files at path |
+cat /path | Print file contents |
Ctrl+X | Clear the current input line |
Ctrl+C | Cancel current computation |
Dojo link commands
| Command | Description |
|---|---|
|dojo/link %app | Connect to a local CLI app |
|dojo/unlink %app | Disconnect from a CLI app |
Safety Guards
Before sending any command, always:
- Confirm the target session — verify which ship the session belongs to by capturing recent output and looking for the dojo prompt (e.g.
~zod:dojo>) - Warn before destructive commands — the following require explicit user confirmation:
|exit— shuts down the ship entirely|nuke %desk— destroys a desk and all its data|nuke %desk, =sure &— confirmed destructive nuke|uninstall %desk— removes a desk%ovuminjection via-evalor-khan-eval
- Long-running operations — warn the user that
|pack,|meld, and|bumpcan take significant time and will block the ship during execution - Never send Ctrl+D — this detaches the terminal from the ship process; if running directly (not in screen/tmux), this will shut the ship down
Critical Warning: Garbled Dojo Input is Permanent
If garbled or malformed input is sent to the dojo via tmux send-keys or screen -X stuff, it becomes part of the permanent event log. It persists across restarts and cannot be cleared. There is no way to undo garbled dojo input.
Recommendation: For programmatic ship interaction, strongly prefer conn.c (see the urbit-conn skill) over terminal multiplexer send-keys. The conn.c socket provides structured command injection without the risk of corrupting the dojo input buffer.
Use tmux send-keys / screen -X stuff only for:
- Simple, well-tested dojo commands (e.g.
+vats,|pack) - Interactive sessions where a human is monitoring output
- Cases where conn.c is unavailable
Troubleshooting
"No screen session found" / "session not found"
- The ship may not be running in screen/tmux
- Check if it's running as a bare process:
pgrep -a urbit - Consider using the
urbit-connskill instead (conn.c socket doesn't require screen/tmux) - Most systems come with either screen or tmux installed, but it is not available advise the user to install tmux or screen before proceeding
Commands appear to hang
- The ship may be processing a long computation (spinner shows in terminal)
- Increase the sleep duration before capturing output
- Check if the ship is responsive: send an empty Enter and see if the prompt returns
Screen hardcopy is empty
- Ensure the screen session name is correct
- Try
screen -lsto get the exact session identifier (may include PID prefix like12345.zod)
Tmux capture-pane shows old content
- Increase
-Svalue to capture more scrollback - The pane index may be wrong — use
tmux list-panes -t <SESSION>to check
