divergent/docs

Synopsis

div sandbox <subcommand> [arguments] [flags]

div sandbox with no subcommand is div sandbox ls. It uses the API key that div login saves. If your key was created before sandboxes existed, run div login again.

<sandbox> is a sandbox’s name or id. Every subcommand accepts --json, which prints the full API response instead of the usual output.

Subcommands

Subcommand Description
create Create a sandbox and print its name.
ls List the org’s sandboxes.
exec Run a command in a sandbox.
cp Copy a file into or out of a sandbox.
ssh Open a shell on a sandbox.
set Change a sandbox’s idle timeout, whether it stops when its agents finish, or its metadata.
stop Stop a sandbox, keeping its files and processes.
resume Resume a stopped sandbox.
fork Create a new sandbox from another sandbox’s files.
rm Delete a sandbox permanently.
desktop Start, stop or check the desktop.
open Open URLs in the desktop’s browser.
screenshot Save the desktop’s screen as a PNG.
input Send a click, keystroke or scroll to the desktop.
a11y Read the desktop’s accessibility tree, or act on a node.
forward Make a sandbox port available on your machine.
token Print a token that opens only this sandbox’s desktop and screen.
tunnel Make a port on your machine available in the sandbox, or send its traffic through your machine.

create

div sandbox create [--size <size>] [--name <name>] [--secret <NAME>]... [--environment <env>] [--metadata <key>=<value>]... [--idle <duration>] [--stop-when-agents-finish] [--idempotency-key <key>]

Creates a sandbox and starts it. The sandbox is running when the command returns.

Flag Description Default
--size <size> small, standard, large or xl. See sizes and prices. small
--name <name> Lower case letters, digits and dashes. Must start with a letter or digit. The org’s slug and a dash are put in front: in org acme, box becomes acme-box, and a name that already starts with acme- is kept. The full name is at most 63 characters and unique across all orgs. Commands find the sandbox by either name. the org’s slug, -sb- and six hex digits
--secret <NAME> A secret to set as an environment variable in the sandbox, read from --environment. The secret’s products must include sandboxes. Repeat for each secret. A sandbox with secrets cannot have a token. none
--environment <env> The secrets environment to read --secret from. resume reads from the same environment, and a fork keeps it. The environment cannot be deleted while the sandbox exists. default
--metadata <key>=<value> A label of your own, such as the user the sandbox is for. Repeat for each label, up to 16. Keys are 1 to 40 lowercase letters, digits, _, . or -. Values are up to 256 characters. none
--idle <duration> Stop the sandbox after this long without use: 90s, 15m, 2h, 1d, or 0 for never. Between 60 seconds and 7 days. A number without a unit is rejected. See idle timeout. 0
--stop-when-agents-finish Stop the sandbox once its coding agents have finished a turn, no turn is running or queued, and nothing has used the sandbox for 2 minutes. off
--idempotency-key <key> A retry with the same key returns the sandbox the first attempt created instead of creating another. Up to 255 characters. none

Output. The name on stdout, alone, so SB=$(div sandbox create) captures it. A summary on stderr:

sb-4c1e9a
sb-4c1e9a running · small, 1 vCPU, 2 GiB · $0.05/h · runs until stopped

For a sandbox created with --environment other than default, the summary also says secrets from <env>.

Example

SB=$(div sandbox create --size standard --secret GITHUB_TOKEN --idle 30m)
SB=$(div sandbox create --metadata user=42 --metadata team=support)
SB=$(div sandbox create --environment acme --secret ANTHROPIC_API_KEY --metadata customer=acme)

Errors

Code When
unknown_environment No environment named by --environment. Create it with div secrets env add, or list environments with div secrets env ls.
unknown_secrets A --secret is not in the environment, or its products do not include sandboxes. Set it with div secrets set <name> --environment <env>, or run div secrets products <name> runs,sandboxes --environment <env>.

ls

div sandbox ls [--all] [--metadata <key>=<value>]...

Lists the org’s sandboxes, newest first.

Flag Description Default
--all Include deleted sandboxes. off
--metadata <key>=<value> List only sandboxes with this label. Repeat to require several; a sandbox must have all of them. all sandboxes

Output. One row per sandbox: name, status, size with vCPUs and memory, hourly price, and total spend. The name is the first column, so div sandbox ls | cut -d' ' -f1 lists names. A summary line on stderr gives the number running and their combined hourly price.

sb-4c1e9a  running  small 1×2G     $0.05/h  spent $0.14
base       stopped  standard 2×4G  $0.10/h  spent $0.52
1 sandbox running, $0.05/h

Status is one of starting, running, stopping, stopped, resuming, destroyed or failed.

With --metadata and no match, the output is No sandboxes with that metadata. on stderr. With --json, each sandbox includes its metadata.

Example

div sandbox ls --metadata user=42

exec

div sandbox exec <sandbox> [--cwd <dir>] [--env KEY=value]... [--timeout <seconds>] -- <command> [args]...
div sandbox exec <sandbox> '<script>'

Runs a command in a running sandbox as root and waits for it to finish.

Flag Description Default
--cwd <dir> Working directory. /root
--env KEY=value An environment variable for this command. Repeat for each variable. none
--timeout <seconds> Maximum run time, up to 600. A command that runs longer is killed and exits 124. 60
  • One argument runs as a shell script: div sandbox exec $SB 'cd app && make'.
  • Several arguments run as a command with those exact arguments: -- echo "a b" prints a b.
  • Put -- before a command that has its own flags. Otherwise div reads them.

Output. The command’s stdout and stderr, unchanged, on stdout and stderr. Each stream is cut at 1 MB. For more output, write it to a file and copy it back with cp. Values of the sandbox’s secrets are masked.

Exit code. The command’s exit code.

Examples

div sandbox exec $SB -- npm test
div sandbox exec $SB --cwd /root/app --timeout 600 'make && make check'
div sandbox exec $SB -- cat /root/log.txt | grep loss

cp

div sandbox cp <from> <to>

Copies one file between your machine and a sandbox. Write the sandbox side as <sandbox>:<path>. Use - for stdin or stdout. Files can be up to 64 MB. For larger files, download them from inside the sandbox with curl.

Output. The size copied, on stderr. Nothing on stdout unless <to> is -.

Examples

div sandbox cp ./app.py $SB:/root/app.py
div sandbox cp $SB:/root/out.json ./out.json
div sandbox cp $SB:/root/out.json - | jq .metrics
tar cz src | div sandbox cp - $SB:/root/src.tgz

ssh

div sandbox ssh <sandbox> [-- <command>]

Opens a root shell on a running sandbox, or runs one command, with your system’s ssh. Requires ssh and ssh-keygen on your PATH, and an API key with the sandboxes:write scope.

  • The first run creates a key at ~/.config/divergent/ssh_ed25519. Each div sandbox ssh adds the key to the sandbox it connects to.
  • The session is encrypted end to end. Output is not masked.
  • The shell has the sandbox’s environment, including its secrets.
  • An open session counts as use, so the sandbox is not stopped as idle.
  • Stopping the sandbox ends the session.

Exit code. The remote command’s exit code, or 255 if ssh fails to connect.

Examples

div sandbox ssh $SB
div sandbox ssh $SB -- tail -f /root/app/server.log

To use scp, rsync or an editor’s remote SSH, see Use a sandbox over SSH.

set

div sandbox set <sandbox> [--idle <duration>] [--stop-when-agents-finish on|off] [--metadata <key>=<value>]... [--clear-metadata]

Changes the idle timeout of a running or stopped sandbox, whether it stops when its agents finish, or its metadata. Give at least one flag.

Flag Description Default
--idle <duration> Same values as create. 0 means never. unchanged
--stop-when-agents-finish on|off on stops the sandbox once its agents have finished, as in create. off keeps it running. unchanged
--metadata <key>=<value> Replace every label with the labels given. Same rules as create. Repeat for each label. unchanged
--clear-metadata Remove every label. Cannot be combined with --metadata. off

On a running sandbox, the new timeout counts from now.

--metadata replaces the labels as a whole. To add one label, give every label the sandbox should keep.

Output

sb-4c1e9a running · small, 1 vCPU, 2 GiB · $0.05/h · stops after 2h idle

stop

div sandbox stop <sandbox>

Stops a sandbox. Its files and running processes are kept, and it is billed for storage only. Stopping a stopped sandbox succeeds and changes nothing.

Output. On stderr: the size of the stored data and the sandbox’s total spend.

sb-4c1e9a stopped · 1.2 GB stored · spent $0.14

With --json, stopped_reason is requested, idle, agents_finished or limit_reached.

resume

div sandbox resume <sandbox>

Resumes a stopped sandbox with its files and processes as they were. Takes a few seconds.

Output

sb-4c1e9a running · small, 1 vCPU, 2 GiB · $0.05/h · runs until stopped

fork

div sandbox fork <sandbox> [--name <name>]

Creates a new running sandbox with a copy of another sandbox’s files. The source can be running or stopped and is not changed. The new sandbox has the source’s size, secrets, secrets environment, idle timeout and metadata. Running processes and the desktop are not copied.

Flag Description Default
--name <name> Name of the new sandbox. Same rules as create. the org’s slug, -sb- and six hex digits

Output. The new name on stdout, alone, and a summary on stderr:

try-b
try-b running · small, 1 vCPU, 2 GiB · $0.05/h · runs until stopped · a copy of sb-4c1e9a

rm

div sandbox rm <sandbox>

Deletes a sandbox and its stored data. Billing stops. This cannot be undone.

Output. On stderr: the sandbox’s total spend.

sb-4c1e9a destroyed with all its files · spent $0.14

desktop

div sandbox desktop <sandbox> [start|stop|status] [--resolution <WxH>]

Starts the desktop (the default action), stops it, or reports whether it is running. start returns when the browser is ready.

Flag Description Default
--resolution <WxH> Screen size for start. Width 320 to 1920, height 240 to 1080. 1280x800

Output. The screen size and the dashboard page where you can watch it:

Desktop running on sb-4c1e9a at 1280x800. Watch it at https://app.divergentlabs.xyz/sandboxes/sb-4c1e9a.

With --json: running, size, display, vnc_port, devtools and browser.

open

div sandbox open <sandbox> <url>...

Opens each URL as a tab in the desktop’s Chromium. The desktop must be running.

screenshot

div sandbox screenshot <sandbox> [file] [--region <x0>,<y0>,<x1>,<y1>]

Captures the screen as a PNG. Writes to file, or to stdout when you give no file or -. Refuses to write to a terminal.

Flag Description Default
--region <x0>,<y0>,<x1>,<y1> Capture only this part of the screen: the top-left and bottom-right corners, in screen pixels. The PNG is that part scaled up to fit the screen size, keeping its aspect ratio. the whole screen

Output. The width, height and size, on stderr:

1280×800 PNG, 214 KB

Examples

div sandbox screenshot $SB shot.png
div sandbox screenshot $SB | your-model
div sandbox screenshot $SB zoom.png --region 0,0,640,400

input

div sandbox input <sandbox> click [<x> <y>] [--button left|middle|right] [--count 1|2|3] [--double] [--mods <keys>]
div sandbox input <sandbox> move <x> <y>
div sandbox input <sandbox> down
div sandbox input <sandbox> up
div sandbox input <sandbox> drag <x1> <y1> <x2> <y2> [--mods <keys>]
div sandbox input <sandbox> type <text>
div sandbox input <sandbox> key <combo>... [--repeat <n>]
div sandbox input <sandbox> hold <combo>... --seconds <s>
div sandbox input <sandbox> scroll <up|down|left|right> [notches] [--at <x>,<y>] [--mods <keys>]
div sandbox input <sandbox> cursor

Sends one input to the desktop. Positions are screenshot pixels from the top left.

Action Description
click Click at <x> <y>, or where the pointer is when you give no position.
move Move the pointer.
down, up Press or release the left button where the pointer is.
drag Drag with the left button from <x1> <y1> to <x2> <y2>.
type Type the text where the keyboard focus is.
key Press each key or combination in turn.
hold Hold the keys down for --seconds.
scroll Scroll by wheel notches.
cursor Print the pointer’s position as JSON on stdout: {"x":640,"y":400}.
Flag Description Default
--button <button> click only. left, middle or right. left
--count <n> click only. 1, 2 (double-click) or 3 (triple-click). 1
--double click only. The same as --count 2. Do not combine with --count. off
--mods <keys> click, drag and scroll. Keys held down during the action: shift, ctrl, alt or super, joined by +, such as ctrl+shift. none
--at <x>,<y> scroll only. Move the pointer here first. current position
--repeat <n> key only. Press the keys n times, 1 to 100. 1
--seconds <s> hold only, and required. How long to hold the keys, 0 to 300. Decimals are allowed. none
  • type takes the text as one argument. Quote it. Up to 10,000 bytes.
  • key and hold take key names and combinations: Return, Escape, ctrl+l, alt+Tab.
  • scroll moves 3 notches unless you give a number from 1 to 100.
  • A sandbox created before an action existed refuses it with desktop_outdated. Create a new sandbox to use it.

Examples

div sandbox input $SB click 640 400
div sandbox input $SB click 640 400 --count 3
div sandbox input $SB click 200 300 --mods ctrl
div sandbox input $SB type 'hello world'
div sandbox input $SB key ctrl+l
div sandbox input $SB key Down --repeat 5
div sandbox input $SB hold shift --seconds 2
div sandbox input $SB scroll down 5 --at 640,400
div sandbox input $SB cursor

a11y

div sandbox a11y <sandbox> [--app <name>] [--depth <n>] [--hidden]
div sandbox a11y <sandbox> do <ref> <action> [text]

The first form prints the accessibility tree of what is on screen, as JSON on stdout. The second acts on one node.

Flag Description Default
--app <name> Only this application, for example chromium. all applications
--depth <n> Maximum depth. 60
--hidden Include nodes that are not on screen. off

Tree output

{
  "apps": [
    {
      "ref": "n1", "role": "application", "name": "Chromium",
      "children": [
        { "ref": "n7", "role": "push button", "name": "Reload", "states": ["focusable"],
          "bounds": [96, 48, 34, 34], "actions": ["press"] },
        { "ref": "n12", "role": "entry", "name": "Address and search bar",
          "states": ["editable", "focusable", "focused"], "bounds": [140, 48, 880, 34],
          "text": "example.com" }
      ]
    }
  ],
  "nodes": 214,
  "truncated": false
}
Field Description
ref The node’s id for do. Valid until the tree is read again.
role, name What the node is and its label.
states For example focusable, focused, editable.
bounds [x, y, width, height] in screenshot pixels.
actions Actions the node supports.
text The text of a field.
nodes Number of nodes returned.
truncated true when the tree passed 4,000 nodes and was cut. Narrow it with --app or --depth.

Nodes with no name, text or action are left out, and their children take their place.

Actions for do

Action Description
press Press a button or follow a link.
focus Move keyboard focus to the node.
set-text <text> Replace the text in a field.
read Print the node’s current state.
any name in actions Run that action.

If the node has changed since the tree was read, the action is refused. Read the tree again and retry.

Examples

div sandbox a11y $SB --app chromium > tree.json
div sandbox a11y $SB do n12 set-text 'https://example.com'
div sandbox a11y $SB do n7 press

forward

div sandbox forward <sandbox> <port>[:<local port>]

Makes a port on the sandbox’s 127.0.0.1 available on 127.0.0.1 on your machine until you press Ctrl-C. A single number uses the same port on both sides. Requires ssh on your PATH.

Port Use
9222 The desktop browser’s DevTools protocol, for Playwright or Puppeteer.
5900 The desktop’s screen, for a VNC viewer.

Output

Forwarding localhost:9222 to sb-4c1e9a:9222. Press Ctrl-C to stop.

Examples

div sandbox forward $SB 9222
div sandbox forward $SB 3000:13000    # the sandbox's 3000 on your 13000

token

div sandbox token <sandbox> [--ability view|control] [--expires <duration>] [--origin <url>]...

Prints a token that opens one sandbox’s desktop and screen, and nothing else. Give it to a page or a program that must not hold your API key, such as the SDK’s screen. The sandbox must have no secrets.

Flag Description Default
--ability <ability> view watches the screen and takes screenshots. control also sends input and starts or stops the desktop. control
--expires <duration> How long the token works: 90s, 15m or 1h. Between 60 seconds and 1 hour. A number without a unit is rejected. 15m
--origin <url> A page that may use the token in a browser, as a scheme and host with no path: https://app.example.com. Repeat for each origin, up to 10. none
  • Without --origin, a request from a browser is refused. Requests from a server, which send no Origin header, work on every plan.
  • The token stops working when it expires, when the key that minted it is revoked, or when the sandbox has secrets.

Output. The token on stdout, alone, so TOKEN=$(div sandbox token $SB) captures it. A summary on stderr:

dvs_SFMyNTY.g2gDdAAAAAZtAAAAAWF...
For sb-4c1e9a · view and control · expires 2026-10-07T12:15:00Z · from https://app.example.com

With --json: token, sandbox, abilities, origins and expires_at.

Examples

TOKEN=$(div sandbox token $SB --ability view --expires 1h)
div sandbox token $SB --origin https://app.example.com --origin http://localhost:5173

Errors

Code When
sandbox_has_secrets The sandbox was created with --secret, in any environment. Create a sandbox without secrets.

tunnel

div sandbox tunnel <sandbox> [<port>[:<local port>]]... [--exit]

Makes ports on your machine available on the sandbox’s 127.0.0.1, sends the sandbox’s internet traffic through your machine, or both, until you press Ctrl-C. Give at least one port or --exit. Requires ssh on your PATH.

Argument or flag Description Default
<port> Your machine’s port, available on the same port in the sandbox. none
<port>:<local port> Your machine’s <local port>, available on the sandbox’s <port>. The sandbox’s port comes first, as in forward. none
--exit The sandbox’s TCP traffic and DNS lookups go out through your machine, to public addresses only. Uses port 1080 on the sandbox’s 127.0.0.1. One --exit tunnel per sandbox at a time. off
  • A tunnel that drops after it connects reconnects on its own. If the sandbox is stopped, the tunnel waits until it is resumed. If the sandbox is deleted, the tunnel exits 1.
  • A tunnel that fails on its first attempt exits without retrying, usually because a port is already in use in the sandbox. A closed tunnel’s ports can stay in use for up to a minute.
  • When the tunnel ends, the sandbox’s traffic goes out directly again.

Output

Forwarding sb-4c1e9a:3000 to port 3000 on this machine.
Forwarding sb-4c1e9a:5432 to port 15432 on this machine.
Sending sb-4c1e9a's internet traffic through this machine.
Press Ctrl-C to stop.

Examples

div sandbox tunnel $SB 3000
div sandbox tunnel $SB 3000 5432:15432 --exit

See Reach your machine from a sandbox.

Exit codes

Code When
the command’s own exec, and ssh with a command
0 The subcommand succeeded.
1 The API refused the request, the desktop is not running, or the sandbox was deleted during a tunnel. The message says what to do next.
2 A subcommand, argument or flag was typed wrong.
124 exec reached its --timeout.
255 ssh, forward or tunnel could not connect.

These match every div command.

esc