sigil.radio
Automation API
Protocol sigil-api:v1
Sigil can be driven from scripts while it runs: open a capture, run a decoder, work the Bits workbench, export the results, render the window to a PNG. The API is a local socket speaking JSON, so any language can use it; the bundled sigil app command wraps it for the shell. Scripted actions are real: they change your session the same way your own clicks would.
Turn it on
The API is off by default. Enable it in Sigil ▸ Settings… ▸ Advanced ▸ Local automation API. The app then listens on a Unix domain socket at:
~/Library/Application Support/Sigil/sigil.sock
The socket is owned by your user with permissions no one else can read (mode 0600), and nothing is exposed to the network. To drive Sigil from another machine, forward the socket over SSH:
ssh -L /tmp/sigil.sock:"$HOME/Library/Application Support/Sigil/sigil.sock" mac.local
The protocol
One JSON object per line, UTF-8, in both directions. On connect the server sends a hello: the versioned handshake, which also carries the full command catalog. The schema grows additively within v1.
{"hello":{"api":"sigil-api:v1","app":"Sigil","version":"0.1.11","build":"…",
"commands":[{"name":"open","primaryArg":"path","usage":"open <path> — …"}, …]}}
Requests carry a verb name and an args object. An id is optional and echoed back in the reply:
{"id":1,"command":"open","args":{"path":"/captures/pager1.sigmf"}}
{"id":1,"ok":true,"failures":[]}
Success is an empty failure list. A command succeeds only if its postcondition held (the decode finished, the window appeared, the layout took); otherwise the reply lists what failed. Commands execute strictly in order, one at a time across all connections, and each runs to completion before its reply arrives, so issue them sequentially and trust the answer. v1 is request and response only; there is no event push.
Argument values use the same mini-grammars as the app and the CLI: transform names like whiten:PN9, framing specs like sync or 128:32, layout operations like split:bits:trailing:decoder. Arguments that take a list accept a JSON array or one comma-separated string.
The sigil app client
The bundled CLI is the readiest client. A bare value goes to the verb's primary argument; everything else is key=value:
sigil app list # every verb, from the hello sigil app open ~/captures/pager1.sigmf sigil app select low=929.6e6 high=929.65e6 sigil app run-decoder flex sigil app select-tab bits sigil app bits-export /tmp/bits.json sigil app render-window /tmp/window.png sigil app workspace "Blind RE" --json # raw JSON reply
Any other language
The core of a Python client is a dozen lines:
import json, os, socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect(os.path.expanduser("~/Library/Application Support/Sigil/sigil.sock"))
reader = sock.makefile("rb")
hello = json.loads(reader.readline())
sock.sendall(json.dumps({"command": "open", "args": {"path": path}}).encode() + b"\n")
reply = json.loads(reader.readline())
For exploration, nc works straight from the shell:
echo '{"command":"render-window","args":{"path":"/tmp/w.png"}}' | \
nc -U ~/Library/Application\ Support/Sigil/sigil.sock
Verbs
sigil app list (or the hello's commands array) is the authoritative, always-current catalog for your installed version. The families: session setup (open, select, set-audio-mode, demod-analysis), decoders (run-decoder, select-tab), the Symbols, Demod, and Bits workbenches (adopt-symbols-baud, demod-burst, the bits-* family through bits-export), walkthroughs, panes and dock tabs, workspaces and window layout, auxiliary windows, issue reporting, and window renders (render-window captures the real laid-out window, but GPU-drawn plots such as the spectrum and waterfall render blank in it).
Getting help
The docs page covers the app and the rest of the CLI, and support has contact details if the API does something these pages don't explain.