omarchy-microsandbox
August 22, 2026 · View on GitHub
An Omarchy shell plugin for managing microsandbox microVMs from the bar.
The bar shows a cube with the number of running sandboxes. Click it for a keyboard-friendly panel that lists every sandbox msb knows about, with the image, CPU and memory allocation, published ports, and age of each one. From there you can start, stop, and remove sandboxes, open a shell into a running one, or follow its logs — all without leaving the desktop.
Features
- Running sandbox count in the bar; greyed out when nothing is running or
msbis missing - Panel listing all sandboxes, running ones first, each with image · ports · resources · age (a forward reads as
8080→80; loopback and tcp are the defaults and stay implicit) - Start / stop a sandbox inline, with a pending state while
msbworks - Open a shell (
msb ssh) or follow logs (msb logs -f) in a terminal window - Remove a sandbox with a confirmation step; a running sandbox is stopped first (
msb rm --force) - Detects
msbin~/.local/binand~/.microsandbox/binas well as onPATH - Points at the official install guide when
msbis not found (the plugin never downloads or runs remote code) - Everything is keyboard-driven;
rrefreshes,Esccloses
Requirements
-
Omarchy with the Quickshell desktop (
omarchy-shell) -
microsandbox
msbCLI — follow the official install guide. The plugin does not install it; it looks formsbonPATH, in~/.local/bin, and in~/.microsandbox/bin. microsandbox needs KVM on Linux — runmsb doctoronce to check the host. -
jq(ships with Omarchy) — used to merge the twomsblistings into one status read
Install
omarchy plugin add https://github.com/ya-luotao/omarchy-microsandbox.git --enable
The plugin lands in the right section of the bar. Move it with omarchy bar move luotao.microsandbox, or drag it around in Setup > Bar.
To install by hand instead, clone or copy this directory to ~/.config/omarchy/plugins/luotao.microsandbox/, then:
omarchy-shell shell rescanPlugins
omarchy plugin enable luotao.microsandbox
Remove
omarchy plugin remove luotao.microsandbox
That disables the widget and deletes the checkout under ~/.config/omarchy/plugins/. The plugin keeps no state of its own: its only setting lives on the widget's entry in ~/.config/omarchy/shell.json, which omarchy plugin remove drops with the entry. It never touches your msb installation or sandboxes.
Keyboard
Inside the panel:
| Key | Action |
|---|---|
j / k, arrows | Move the cursor |
Enter / Space | Start or stop the selected sandbox |
s | Open a shell in the selected sandbox (running only) |
g | Follow the selected sandbox's logs |
x | Remove the selected sandbox (asks first) |
r | Refresh |
i | Open the install guide (when msb is missing) |
Esc | Close |
In the bar: left click opens the panel, right click refreshes.
Settings
Set in ~/.config/omarchy/shell.json on the widget's entry, or through Setup > Bar:
| Key | Default | Meaning |
|---|---|---|
refreshIntervalSec | 15 | How often to re-read the sandbox list (5–3600) |
showCount | true | Show the running count next to the bar icon |
IPC
The panel registers the luotao.microsandbox IPC target:
omarchy-shell luotao.microsandbox toggle
omarchy-shell luotao.microsandbox refresh
omarchy-shell luotao.microsandbox start devbox
omarchy-shell luotao.microsandbox stop devbox
omarchy-shell luotao.microsandbox status # prints the summary line
Bind a key in ~/.config/hypr/bindings.lua to summon it, for example bind("SUPER", "M", "omarchy-shell luotao.microsandbox toggle").
Optional: a menu entry
Menu rows cannot ship inside a plugin, but one line in ~/.config/omarchy/extensions/omarchy-menu.jsonc adds a row that opens the panel from the Omarchy menu:
"microsandbox": {"icon":"","label":"Microsandbox","when":"command -v msb >/dev/null || [[ -x $HOME/.local/bin/msb ]]","action":"omarchy-shell luotao.microsandbox toggle"}
How it works
microsandbox has no daemon, so the plugin polls the CLI. Each refresh runs one bash -c that calls msb ls --format json and msb ps -a --format json and merges them with jq into a single {ls, ps} document — ls carries created_at, ps -a carries the CPU, memory, and port allocation. Model.js turns that into rows; Service.qml owns the processes, timers, and a watchdog that reaps a hung msb; Panel.qml is the bar button and the panel.
msb is treated as untrusted input, and nothing it prints ever reaches the filesystem. Each listing streams through head -c into a shell variable, so a run that overruns 4 MiB is cut off at the cap and rejected before jq sees it; stderr streams through tail -c so only its last 4 KiB is ever held; msb's exit status rides along as a trailing marker line. The parser then accepts at most 500 rows per listing and bounds every string it keeps, and lifecycle actions return only the tail of their output. No temp files means no predictable paths to pre-create, nothing to chmod, and nothing a killed poll can leave behind. Every panel text that shows msb-derived data is Text.PlainText, and strings that reach shared components (hero, confirm dialog) are stripped of control characters and markup first.
Sandbox statuses are the Rust Debug form msb prints: Running and Draining count as running, Crashed is flagged, and Created / Starting / Paused render as in transition.
Development
./test/model-test.sh # Node tests for Model.js against fixtures in test/fixtures/
./test/script-test.sh # runs the generated bash against a hostile fake msb
omarchy plugin validate . # manifest and entry-point checks (needs jq)
Saving any file under ~/.config/omarchy/plugins/ hot-reloads the plugin, so symlinking a checkout there is the quickest way to iterate:
ln -s "$PWD" ~/.config/omarchy/plugins/luotao.microsandbox
omarchy-shell shell rescanPlugins
Note that omarchy plugin add refuses symlinks inside a plugin folder, but a symlinked plugin directory is fine for local development.
License
MIT