CLI
The srig CLI lets you interact with SiliconRig boards from your terminal.
Installation
# macOS / Linux
curl -fsSL https://siliconrig.dev/install.sh | sh
# or with Go
go install github.com/siliconrig/srig-cli@latestAuthentication
Set your API key as an environment variable:
export SRIG_API_KEY=key_...Or pass it per-command:
srig --api-key key_... statusCreate API keys in the web UI under API Keys.
Commands
srig status
Show available boards and your active sessions.
srig statussrig session
Manage sessions explicitly.
# Create a session on an ESP32-S3 board
srig session create --board esp32-s3
# List your sessions
srig session list
# End a specific session
srig session end sess_xxxxxxxxxxxx
# End your active session (auto-detects)
srig session endsrig flash
Flash firmware to the board in your active session. If --session is not given, auto-detects your active session.
# Flash to the active session
srig flash firmware.bin
# Flash to a specific session
srig flash firmware.bin --session sess_xxxxxxxxxxxxAccepts a raw .bin (all boards), a .uf2 (RP2350), or — for STM32 boards — an .elf or Intel .hex. SiliconRig converts ELF/HEX to a raw image server-side, so the same formats work from the SDK and the API too. The ELF/HEX must be linked at the board's flash base address; see firmware format per board.
srig flash build/firmware.elf --session sess_xxxxxxxxxxxxsrig run
Collapse the create → flash → watch → end workflow into one command. Point it at a firmware image and a pattern to look for, and it exits with a code your CI pipeline can act on — no scripting required:
srig run firmware.bin --board esp32-s3 --expect "All tests passed"Under the hood it creates a session on a free board, flashes the firmware, watches serial output until a pass/fail condition is reached or --timeout elapses, then ends the session — always, even on failure or interruption. Firmware can be a raw .bin, a .uf2, or (for STM32) an .elf / Intel .hex — see firmware format per board.
Flags
| Flag | Default | Description |
|---|---|---|
--board | — | Board type (required) |
--expect | — | Regex that must appear in serial output for the run to pass |
--fail | — | Regex that fails the run immediately if it appears |
--send | — | String to write to the device's UART after boot (interprets \n, \r, \t) |
--log | — | Save the full serial capture to this file |
--timeout | 60s | How long to watch serial output after flashing |
--retries | 0 | Retry on transient infrastructure failures (e.g. no free board); never retries a test failure |
--retry-delay | 15s | Delay between retries |
--json | false | Emit a machine-readable result on stdout instead of human output |
Pass/fail precedence
Only one condition decides the outcome, checked in this order as each serial line arrives:
- Sentinel — a line matching
##srig-exit:N##sets the exit code toNdirectly --fail— if the pattern matches, the run fails immediately--expect— the run passes once the pattern matches; if--timeoutelapses first, the run fails
If neither --expect nor --fail is given, run watches serial for --timeout and exits 0 once it elapses — useful for smoke-testing that firmware boots without crashing.
Exit codes
| Code | Meaning |
|---|---|
0 | Pass |
1 | Test failed, or --expect never matched before --timeout |
2 | Infrastructure error (no free board, connection lost, bad flags, etc.) |
130 | Interrupted (Ctrl-C) |
Because each code's meaning is fixed, run is safe as the last step in a CI job — a non-zero exit fails the job like any test runner would.
The exit sentinel
For firmware with real pass/fail logic, have it print a sentinel line with the exact result instead of relying on --expect to infer success from a log message:
printf("##srig-exit:%d##\n", tests_failed ? 1 : 0);srig run picks up the sentinel over any --expect / --fail pattern, so firmware can report any code — not just pass/fail — and the CLI exits with exactly that code.
Driving interactive firmware
If your firmware waits for a command before running its test path, use --send to write it to the device's UART right after boot — the same bidirectional serial connection srig serial uses:
srig run firmware.bin --board <type> --send "test\n" --expect "##srig-exit:0##"--json output
With --json, serial output goes to stderr and stdout carries a single JSON object once the run concludes:
{
"result": "pass",
"exit_code": 0,
"reason": "expect",
"matched": "All tests passed!",
"session_id": "sess_xxxxxxxxxxxx"
}reason is one of sentinel, fail, expect, timeout, or ran.
Examples
# Pass/fail on a log message
srig run firmware.bin --board <type> --expect "All tests passed"
# Firmware reports its own exit code via the sentinel
srig run firmware.bin --board <type> --send "test\n"
# Fail fast on a panic, with a longer watch window
srig run firmware.bin --board <type> --expect "DONE" --fail "PANIC" --timeout 2m
# Save the serial capture and ride out a busy fleet
srig run firmware.bin --board <type> --expect "READY" \
--log serial.log --retries 5 --retry-delay 30sIn CI, the step's exit code is the run's exit code — a failed on-device test fails the job, no separate grep needed:
- name: Run on-device tests
env:
SRIG_API_KEY: ${{ secrets.SRIG_API_KEY }}
run: |
srig run build/firmware.bin --board <type> \
--expect "All tests passed" --fail "PANIC" --timeout 90s --log serial.logsrig serial
Open an interactive serial console. If --session is not given, auto-detects your active session.
# Connect to the active session
srig serial
# Connect with a timeout (useful in CI)
srig serial --timeout 30s
# Save serial output to a file
srig serial --log output.txtPress Ctrl+] to disconnect. The session stays alive — reconnect or end it explicitly.
Typical workflow
# 1. Reserve a board
srig session create --board esp32-s3
# 2. Flash your firmware
srig flash firmware.bin
# 3. Interact via serial
srig serial
# 4. Done — release the board
srig session endGlobal flags
| Flag | Description |
|---|---|
--api-key | API key (overrides SRIG_API_KEY) |
--base-url | API base URL (default: https://api.srig.io) |
--json | Output as JSON (for CI/CD pipelines) |