Commands

Every omabox command.

Read from omabox help at omabox 0.4.3 when this site was built, so the options match the omabox you install.

Start and end boxes

omabox up

Start a box: headless and invisible unless you ask for a window, any screen size, with your plugins, an isolated network or a save to start from.

Examples
$ omabox up
$ omabox up --size 2560x1440@144 --plugin ~/code/myplugin
$ omabox up --net isolated --allow 8081
omabox up [NAME] [--size WxH[@HZ]|host] [--interactive] [--plugin PATH|ID]... [--overlay DIR]...
          [--ro-bind DIR[:DEST]]... [--net isolated [--allow PORT,...]] [--env KEY=VAL]...
          [--idle DURATION] [--stock-bar] [--systemd] [--xwayland] [--no-shell] [--from SAVE]
          [--hyprland PATH]                            a Hyprland build of yours instead of the installed one
          [--omarchy DIR]                              an Omarchy tree (a checkout) instead of /usr/share/omarchy
          [--workspace WS] [--confirm-close | --no-confirm-close]      (interactive)
          [--new]                                      a free name, box-1, box-2, ... (printed)
          [--json]                                     the box as ls --json lists it, on stdout

omabox down

End a box and everything in it. A session's box also goes when its agent exits.

Examples
$ omabox down
$ omabox down --all
omabox down [NAME | -b NAME | --all]

omabox ls

Every box: its mode, size, state, network, idle time and plugins. --json adds what each one tested: the Omarchy version, the theme, each plugin's commit.

Examples
$ omabox ls
$ omabox ls --json
omabox ls [--json]

omabox path

Where a box lives on disk; its HOME is <dir>/home, so you can seed an app's data files there.

Examples
$ omabox path
$ omabox path --logs
omabox path [NAME | -b NAME] [--logs]                  the box dir (HOME is <dir>/home); --logs: each log's file

omabox mode

Show or change a headless box's screen size and refresh rate while it runs.

Examples
$ omabox mode 3440x1440@144
omabox mode [-b NAME] [WxH[@HZ]|host]                  show or change a headless box's screen mode

omabox save

Keep a box's HOME (an app signed in, a PIN, a library) so new boxes start from it.

Examples
$ omabox save signed-in
$ omabox up --from signed-in
omabox save SAVE [-b NAME] [--force]                   keep the box's HOME: up/run --from SAVE start from it

omabox saves

List the saves, or delete them.

Examples
$ omabox saves
$ omabox saves rm signed-in
omabox saves [--json] | saves rm SAVE...               the saves: list, delete

Run, look and wait

omabox run

Run any command inside a box. -d launches an app and returns; --replace restarts it after a rebuild. With no box up, a throwaway box runs the command and goes.

Examples
$ omabox run -d --wait -- ./build/app
$ omabox run -d --replace --wait -- ./build/app
$ omabox run -- ctest --test-dir build
omabox run [-b NAME] [-d [--wait] [--replace] [-q] [--print-log]] [--pass VAR]... [--env-file FILE]...
           [UP OPTIONS] -- CMD [ARG...]                UP OPTIONS: up's, for a throwaway box only
omabox help run
omabox up [NAME] [--size WxH[@HZ]|host] [--interactive] [--plugin PATH|ID]... [--overlay DIR]...
          [--ro-bind DIR[:DEST]]... [--net isolated [--allow PORT,...]] [--env KEY=VAL]...
          [--idle DURATION] [--stock-bar] [--systemd] [--xwayland] [--no-shell] [--from SAVE]
          [--hyprland PATH]                            a Hyprland build of yours instead of the installed one
          [--omarchy DIR]                              an Omarchy tree (a checkout) instead of /usr/share/omarchy
          [--workspace WS] [--confirm-close | --no-confirm-close]      (interactive)
          [--new]                                      a free name, box-1, box-2, ... (printed)
          [--json]                                     the box as ls --json lists it, on stdout

omabox shot

A PNG of the screen, a region, or one window's own pixels, even covered or on another workspace.

Examples
$ omabox shot
$ omabox shot --window myapp --fit 1280
omabox shot [-b NAME] [-o FILE | FILE] [--window SEL | --active] [-g "X,Y WxH"] [--fit N]

omabox windows

The box's windows: where they are, which workspace, what covers them.

Examples
$ omabox windows
omabox windows [-b NAME] [--json]                      the box's windows, where they are, what covers them

omabox wait

Wait for a still screen, a window, a layer or a command, instead of sleeping.

Examples
$ omabox wait window myapp --focused
$ omabox wait still
omabox wait [-b NAME] [--timeout 10s] [--json] COND   until COND holds (exit 0), 124 if not in time
       COND: still [--quiet 300ms] [-g GEOM | --window SEL] [--strict] | change [-g GEOM | --window SEL]
             | window SEL [--gone | --focused] | layer NAMESPACE [--gone] | cmd -- CMD [ARG...]

omabox log

A box's logs: Hyprland's by default, or the shell's, the apps', the last run -d's. -f follows them.

Examples
$ omabox log shell --grep qml -n 20
$ omabox log apps -f
omabox log [-b NAME] [LOG...|all] [-n 100|all] [--grep RE [-i]] [-f]
                                                       a box's logs: hyprland (the default), shell, apps, run,
                                                       events, keyring, labwc, systemd, box, reap

omabox events

What the box's Hyprland reported, stamped: mark a point, act, then read what came after or wait for one event.

Examples
$ omabox events --mark m1
$ omabox events --since m1 --until 'openwindow>>' --timeout 5s
omabox events [-b NAME] [--since MARK] [--grep RE [-i]] [-n N] [--json]   Hyprland's events
omabox events [-b NAME] --mark [MARK]                  from here: prints the offset, keeps MARK for --since
omabox events [-b NAME] [--since MARK] (--until RE [--timeout 10s] | -f) [--json]

omabox gpu

GPU time of one box's processes, to see what your app costs to draw.

Examples
$ omabox gpu 10
omabox gpu [-b NAME] [SECONDS] [--json]                GPU engine time of this box's processes (default 5s)

Keys and the pointer

omabox keys

Key combos for Hyprland binds and the focused app, any Unicode text, or a password from your environment, never on a command line.

Examples
$ omabox keys --wait super+space
$ omabox keys -t 'hello wörld' Return
$ omabox keys --pass PASSWORD Return
omabox keys [-b NAME] [--window SEL] [--wait] (COMBO | -t TEXT | --pass VAR | -s MS)...  e.g. super+space  -t hi  Return

omabox click

Click in screen, window or screenshot coordinates. --steps travels there, hovering what it crosses; --mod holds ctrl, shift or alt.

Examples
$ omabox click --window myapp 40 12
$ omabox click --steps 20 --mod ctrl 960 540
omabox click [-b NAME] [--window SEL [--no-raise] | --in SHOT] [--wait] X Y [left|right|middle] [--double]
             [--steps N] [--mod MODS]                  --steps: travel there; --mod ctrl: ctrl-click

omabox drag

Press, move, hold, release: sliders, selections, drag and drop.

Examples
$ omabox drag --window myapp 10 10 200 80
omabox drag [-b NAME] [--window SEL [--no-raise] | --in SHOT] [--wait | --shot FILE] X1 Y1 X2 Y2 [left|right|middle]
            [--steps 10] [--hold MS] [--mod MODS]      press, move, hold, release

omabox pointer

Raw pointer moves, button presses, scrolls and pauses, for what click and drag don't cover.

Examples
$ omabox pointer --steps 10 -- move 400 300 scroll 3
omabox pointer [-b NAME] [--window SEL | --in SHOT] [--steps N] [--mod MODS] -- ARGS...
               raw: move X Y [--steps N], click/down/up [BTN], scroll DY, sleep MS

The box's Hyprland and shell

omabox hyprctl

The box's Hyprland, never yours.

Examples
$ omabox hyprctl -j clients
omabox hyprctl [-b NAME] ARGS...

omabox lua

Lua in the box's Hyprland, printing what it returns (tables as JSON).

Examples
$ omabox lua 'hl.get_active_window()'
omabox lua [-b NAME] [--json] (EXPR | -)               Lua in the box's Hyprland, printing what it returns

omabox restart-shell

Reload the box's Omarchy shell after you edit a plugin; it says why a plugin did not load.

Examples
$ omabox restart-shell
omabox restart-shell [-b NAME]                         reload the Omarchy shell (after plugin edits)

You and your desktop

omabox peek

A live, view-only window of any box on workspace 9, opened without taking your focus.

Examples
$ omabox peek -b app-tray-5cc72cdc
omabox peek [-b NAME] [--fps N] [--focus] [--workspace WS]  live view-only window of a box (workspace 9)

omabox keys-to-box

For an interactive box: SUPER keys go to it while its window has focus and the pointer is over it.

Examples
$ omabox keys-to-box -b box-1 on
omabox keys-to-box [-b NAME] [on|off]                  interactive: SUPER keys to the box while focused, pointer on it

omabox clip

Your clipboard into an interactive box, once, or the box's back to you. Never for agents.

Examples
$ omabox clip
$ omabox clip --from-box
omabox clip [-b NAME] [--from-box]                     your clipboard into an interactive box, or back

omabox env

Exports that point Wayland tools on your side at a box, so their windows open in it.

Examples
$ eval "$(omabox env)"
omabox env [NAME | -b NAME]                            exports for host-side Wayland tools

omabox host

One command on your real desktop, when you asked for it: the one way past the guard, on the record.

Examples
$ omabox host -- hyprctl reload
omabox host -- CMD [ARG...]                            one command on your real desktop (when asked for)

omabox config

Your settings: where windows open, confirm before closing, the bar icon.

Examples
$ omabox config
$ omabox config workspace special
omabox config [--json | KEY [VALUE | default]]         settings: workspace, confirm-close, bar-icon

Setting up

omabox setup

Links the agent skill and the bar widget, offers the guard; --remove undoes all of it, --aquamarine builds aquamarine's fix.

Examples
$ omabox setup
$ omabox setup --remove
omabox setup [--remove]                                your links (skill, bar widget), settings dir, agent guard
omabox setup --aquamarine [--force]                    build aquamarine's fix (headless NVIDIA boxes, confirm-close)

omabox guard

Opt in, and agents' shells get a display that doesn't exist: a window they forget to box fails instead of reaching yours.

Examples
$ omabox guard on
$ omabox guard exec -- opencode
omabox guard [on|off [claude|codex]]                   the agent guard: show, add, remove
omabox guard exec -- AGENT [ARG...]                    run any other agent under the guard

omabox broker

Lets agents inside ai-jail drive boxes of their own, kept to what the jail has.

Examples
$ omabox broker on
omabox broker [on|off]                                 let agents inside ai-jail drive their own boxes

omabox --version

The version, and which aquamarine new boxes use.

Examples
$ omabox --version
omabox --version                                       and which aquamarine new boxes use

The details

The rest of omabox help: names, networks, windows, waiting, idle boxes and more, as the CLI prints it.

NAME defaults to $OMABOX, else the current git repo's name, else "default". In an agent session
(Claude Code, Codex, `guard exec`) that name gets the session's id, myrepo-5cc72cdc: one box per
session, gone when its agent exits. OMABOX_SESSION= (empty) turns that off. A git worktree is named
by its own folder, so each worktree has its own box. -b NAME also goes before the command
(omabox -b NAME windows), for every command that takes it.
`omabox run` with no box up starts a throwaway box for the command, with the current repo
mounted as a discarded overlay (writes succeed, vanish at teardown), and tears it down after.
A box named with -b or $OMABOX must be up: `run` fails rather than start a throwaway. With a
box up, `run` uses it and the repo is read-only there (tests that write into the tree: down first).
--net isolated --allow PORTS on a throwaway `run` keeps tests off your real local services.
Every box has its own network (pasta): by default the internet, the LAN and your servers. Across
the box boundary use 127.0.0.1, not localhost; a box's servers appear on your 127.0.0.1 about a
second after they listen. --net isolated: a loopback and the --allow ports only.
`run` starts the command with the box's environment, not yours: --pass VAR hands it one of your
variables (a password too: never on a command line); --env-file FILE hands it a file's KEY=VAL lines
(a dev.env: read as data, nothing expanded; --pass wins); `keys --pass VAR` types one (never `-t`
for a secret: the process list shows it). --env KEY=VAL is the box session's, on `up`.
--no-shell: Hyprland only, no Omarchy shell (faster; no bar, tray or notifications).
--plugin PATH|ID: a shell plugin, read-only, enabled where its manifest says; `up` and
`restart-shell` warn when Omarchy's validator or the shell refuses it (`ls --json`: plugin_status).
--hyprland PATH: the box runs that binary (its folder mounted read-only at its own path) with the
box's aquamarine, so a build must link a libaquamarine soname the box has (checked before the box
starts); hyprctl and hyprpm stay the installed ones (a warning when the versions differ). `ls` and
`windows` name it. Compositor logic runs for real (layouts, focus, input routing, the Lua config,
IPC, protocols); DRM/KMS, real monitors, HDR/VRR, multi-GPU, libinput with real devices and the
session/suspend/lock paths never run in a box.
SEL picks one window: active, its address (0x...), pid:N, class:RE, title:RE, initialClass:RE,
initialTitle:RE (any case), or a word (its class or the class's last part, nautilus for
org.gnome.Nautilus, or part of its title); repeat to narrow. None or
several is exit 2, with the candidates (`wait window SEL` asks for a window like it: any of several
does, each named). `shot --window` (-w; --active is --window active) is the
window's own pixels, covered or on another workspace too; `click --window` takes the window's
coordinates and focuses it first when it is off screen or covered there (--no-raise refuses instead);
`keys --window` focuses it, then types. --fit N scales a shot's longest side down to N pixels.
-g "X,Y WxH" (or X,Y,W,H) crops: the screen's, or with --window the window's own coordinates.
A cropped or scaled shot says so on stderr: `click --in SHOT X Y` (and `drag`, `pointer --in`)
take that image's pixels (a window shot follows the window if it moved). Screen shots show the
pointer; window shots never do. -o makes the file's folder if it is missing.
The pointer starts at the screen's centre and stays where it was left; `click` and `pointer move`
jump there. --steps N travels in N steps from where it is, over what lies between: under Omarchy's
focus-follows-mouse the windows on the way take focus, as with a real mouse (`pointer --steps N --
move A move B` passes through A). --mod MODS (ctrl, shift, alt, super, altgr; ctrl+shift, or --mod
again) holds modifiers down across a click, drag or pointer run, released after it, whatever happens
to omabox. SUPER with the left or right button is Hyprland's move or resize window, not the app's.
`wait still`: nothing on screen changed for --quiet; a caret (4 px or thinner) and the cursor do not
count, and are said (--strict counts them). `keys`, `click` and `run -d` take --wait [--start 2s]
[--quiet 300ms] [--timeout 10s] [--json]: a change within --start (5s for run -d), then quiet.
Exit 0 satisfied, 124 not by --timeout (after --wait: the input WAS sent), 1 unknown (the box went
down, an interactive box's hidden window renders nothing): never 0 for what could not be seen.
Durations: 300ms, 2s, 1m; --timeout at most 10m. Waiting counts as using the box.
$OMABOX_READY_TIMEOUT: seconds `up` waits for Hyprland and the shell (default 30).
`lua` takes an expression or statements (`return` what to print); one line per value: strings and
numbers as they are, nil as nil, tables and Hyprland's objects (a window, a monitor) as JSON (--json:
strings quoted too). A Lua error is exit 1 with its message. An error inside a callback (hl.on,
hl.timer) that runs later is logged nowhere: catch it with pcall.
`log` prints the last -n lines (100) of each log named, of a box that died too; run is the latest
`run -d`'s, apps what Omarchy's launcher started, box bwrap's. -f follows them until the box goes
down (-n then counts lines before --grep). Hyprland writes its log in pieces: its newest lines can
come late.
`events`: what the box's Hyprland reported on its event socket (activewindow>>, urgent>>, ...) from
its start, never cleared. --mark MARK takes "from here" (a byte offset: safe while events come);
--since MARK (a mark, an offset, or 30s/2m/1h ago) reads from there. --grep and --until match the
EVENT>>DATA part (grep -E). --until: the first matching event from --since (or from now), printed:
exit 0, 124 none by --timeout, 1 the box went down; -f follows until the box goes down.
Interactive boxes and peek windows open on workspace 9, without focus: `omabox config workspace WS`
(1-99, special = Omarchy's scratchpad on SUPER+S, special:NAME) or --workspace. A peek window shows
click, pointer and keys for ~3 s (a ring, key captions, --pass values as *); never the box's own frames.
Closing an interactive box's window ends the box; `omabox config confirm-close on` asks first (a
second close is a yes).
aquamarine's fix for nested Wayland outputs (hyprwm/aquamarine#415, until a release has it): a
headless box on an NVIDIA render node and confirm-close need it, and `up` refuses them without it;
`omabox setup --aquamarine` builds it (a checkout's build/prefix, else ~/.local/share/omabox).
OMABOX_AQUAMARINE=system: the system's aquamarine all the same (testing).
SUPER + ALT + ESCAPE toggles sending SUPER keys to an interactive box, once:
until focus leaves it, or a key is pressed with the pointer off it. `keys-to-box on` makes them
follow focus and the pointer, for the box's lifetime: its window has focus and the pointer is over
it, SUPER is the box's; focus goes elsewhere or the pointer leaves it (your bar, another monitor),
it is yours, and the pointer back over it gives it to the box again. SUPER + ALT + ESCAPE over the box
gives the keys back until the box loses focus and gets it again. No argument prints on or off. While keys go to a box, its window's border takes the
theme's red and the bar widget's icon is lit.
`clip` hands your clipboard's item (text, else an image by its type) to an interactive box, once;
--from-box hands the box's back. With no -b: the interactive box whose window has focus, else the only
one. Never for agents (refused in their sessions, under the guard, in ai-jail). Nothing keeps
watching either clipboard. Bind it to a key in your Hyprland config to paste into the box you are in.
A headless box goes down after $OMABOX_IDLE (default 2h) with no omabox command against it, no
peek window and no `omabox run` still running; --idle 30m|2h|0 (never) per box. Interactive: never.
`run -d` says where the command's output goes (its log) on stderr: -q says nothing (errors still),
--print-log prints the log's path on stdout (first, before --wait's line). `run -d --replace`
first stops what `run -d` started in that box with the same command and arguments (SIGTERM to its
session, SIGKILL after 5 s) and waits for its windows to go: a rebuilt app in one step. Nothing
else in the box is touched: an app started some other way stays.
A `run -d` job is not activity: a server only polled over HTTP needs --idle 0 (or longer).
At --idle 0 a session's box still goes with its agent (`ls` says never); a box with another name
(-b NAME) stays.
Sizes: WxH is @60; `host` copies your focused monitor's size and refresh rate (scale stays 1).
Measure rendering cost with `omabox gpu` in a box whose mode matches your monitor.
The agent guard (opt-in) gives agents' shell commands (Claude Code, Codex) a display that does not
exist, so a window, hyprctl or grim outside a box fails instead of reaching your desktop; omabox
still works, and `omabox host` runs a command you asked for on the real desktop.
An agent inside ai-jail cannot enter a box: `omabox broker on` (a systemd user socket) lets its
omabox hand commands to omabox outside, which keeps the jail's boxes to what the jail has (its
project, its network or none) and to themselves. It prints the lines to add to ~/.ai-jail.
Crashes in a box skip the desktop's crash notifications (core limit 1 byte; raise it inside for a core).
A save keeps what a box's apps set up (signed in, a PIN, a library): the box HOME without .cache and
its logs, keyring included, paused for the copy. `up --from` starts with it, then seeds your Omarchy
look on top as for any box (theme, bar, terminals: today's, not the save's). Close an app first for a
clean save. Saves live in ~/.local/share/omabox/saves until `saves rm`.