CLI
A third way to talk to sandbin, alongside the browser playground and the raw HTTP API — run code straight from a terminal, with no server required by default.
Install
git clone https://github.com/ayazdoruck/sandbin.git
cd sandbin
npm install
npm link
npm link puts sandbin on PATH. Without it, node bin/sandbin.mjs ... works identically.
Two modes, one command
Local (the default). No server, no port —
bin/sandbin.mjs imports sandbox.mjs directly
and calls run() itself:
sandbin run script.py
Remote, with --server. Submits over the
exact same HTTP + WebSocket protocol the browser frontend speaks
against a running instance, local or not:
sandbin run script.py --server localhost:8080
Local is the default on purpose: the more common case for someone who
already has the repo checked out is "run this file through the real
sandbox right now," which needs nothing running and no port to pick.
Local mode needs the same host requirements as npm start
itself — see Architecture.
Getting code in
Exactly one source, never ambiguous about which wins:
sandbin run script.py # from a file
sandbin run -l python -e 'print(1 + 1)' # inline
cat script.sh | sandbin run -l bash # piped stdin
Language is inferred from the file extension (.py,
.sh/.bash, .js/.mjs/.cjs,
.c, .go) when a file is given.
-l/--language overrides it, or supplies it
outright for -e or piped input.
Output and exit codes
Stdout and stderr stream live, each to their own real stream, as
chunk events arrive — in local mode via
run()'s own onChunk, in remote mode via the
same WebSocket messages the frontend renders. A summary prints to
stderr once it finishes:
$ sandbin run -l python -e 'print("hi")'
hi
verdict ok
duration 14ms
cpu 6ms
peak memory 3.9 MB
exit code 0
The process exits 0 for verdict ok,
1 otherwise — deliberately not a passthrough
of the guest's own exit code. A guest that calls sys.exit(3)
still means the CLI itself succeeded at running it and observing that;
the verdict (printed alongside duration, CPU and peak memory) is what
actually failed. Safe to use directly in shell scripts and CI:
sandbin run deploy-check.py || echo "check failed, see verdict above"
run()'s onChunk only ever covers the
execute phase — the compile phase (c,
go) never gets the callback at all. A compile failure
was streaming nothing and then printing a bare
verdict compile_error with zero indication of what the
compiler actually said. The CLI now prints the result's own captured
stderr in full for exactly the two verdicts where the
streamed callback wouldn't have shown it
(compile_error, setup_failed) — not a
change to sandbox.mjs itself, the diagnostic was already
there, the CLI just wasn't showing it.
Other commands
| Command | Does |
|---|---|
sandbin languages | lists what this host can run — reads local IMAGES directly, so go only appears if a toolchain was actually found |
sandbin keys create | wraps POST /keys against a running server |
sandbin keys status <key> | wraps GET /keys/:key |
sandbin --help | every flag, including the limit overrides below |
Flags
| Flag | Meaning |
|---|---|
-l, --language <lang> | override or supply the language |
-e, --eval <code> | inline code instead of a file |
-i, --stdin <file> | file whose contents become the guest's stdin (- reads this process's own stdin) |
-s, --server <url> | submit to a running server instead of running locally (env SANDBIN_SERVER) |
-k, --key <key> | API key sent as X-Sandbin-Key (env SANDBIN_KEY) |
--json | print the full result object once, instead of streaming |
--memory / --cpu / --timeout / --pids | override the matching resource limit |
--json skips live streaming entirely and prints the whole
result object — verdict, stdout,
stderr, durationMs, cpuMs,
peakBytes, and the rest — once, for scripting:
sandbin run server.js --json | node -pe "JSON.parse(require('fs').readFileSync(0)).verdict"
Tested as a real subprocess
src/cli-test.mjs spawns the actual bin/sandbin.mjs
with node, not by importing its functions — both
against run() directly (local) and against a real
createServer() on an ephemeral port (remote), asserting on
captured stdout/stderr/exit code exactly the way a real caller would
observe them. See Testing.