The CLI installed no logger, so every log::warn! and log::error! was dropped: a plugin that failed to load just vanished from engine.clap_plugins with no reason. A small logger now writes warnings and errors to standard error as `warning: <message>` and `error: <message>`, like the CLI's own errors. The level is fixed: RUST_LOG stays a desktop app variable. Fixes #1304.
7.9 KiB
Command-line tool
soundcraft-cli runs SoundCraft without a window: it converts and inspects audio, runs engine
commands on a session, serves MCP, and calls a running app. Follows
RFC-0012 (command-line conventions for the
Craft apps).
soundcraft-cli --help and soundcraft-cli <subcommand> --help are the source of truth for
flags, values and defaults. This page does not repeat them.
| Subcommand | What it does |
|---|---|
info |
Prints an audio file's format as JSON, or a .scraft session's summary |
convert |
Converts an audio file: resample, change the bit depth, normalize |
run |
Runs engine commands on a new, demo or saved session; can bounce, save and inspect |
script |
Runs a file of engine commands, one ID JSON per line |
commands |
Lists the engine commands |
describe |
Prints one engine command's details as JSON |
app |
Calls a running app's control channel (see the control protocol) |
mcp |
Serves MCP on stdin and stdout (see the MCP guide) |
parity |
Prints the parity report as markdown |
plugins |
Lists the built-in plugins |
soundcraft-cli --version # also -V; there is no `version` subcommand
soundcraft-cli help convert # the same as `convert --help`
soundcraft-cli info session.scraft
soundcraft-cli convert in.wav out.flac --bit-depth 16 --rate 44100
soundcraft-cli run --demo --cmd 'mix.volume={"track":"Kick","db":-6}' --bounce mix.wav
soundcraft-cli script steps.txt --demo --keep-going --save out.scraft
soundcraft-cli commands bounce
soundcraft-cli describe file.bounce_mix
Output and exit codes
Results go to standard output, as JSON where a program is meant to read them. info (on an audio
file), describe, app and the --inspect output of run and script pretty-print it; --compact
prints the same JSON on one line. The result lines of run and script (ID: JSON) and the
--bounce and --save results are always one line each. commands, plugins, parity and the
.scraft summary of info are text. Errors go to standard error as error: <message>, and so do the warnings and errors SoundCraft and the plugin hosts log (warning: <message>, error: <message>), such as a plugin that fails to load. mcp writes only the protocol
to standard output.
| Exit code | Meaning |
|---|---|
| 0 | Success |
| 1 | The command failed (a missing file, an unknown engine command, an app that is not running) |
| 2 | Usage error |
Arguments are checked before any work starts. These are usage errors (exit 2): a flag the
subcommand does not take (--fromat), a flag given twice (only --cmd and the two automation
root flags repeat), a value of the wrong type or out of range, flags that conflict
(--dither with --no-dither, --connect with a root flag or --demo) and a missing value. A value flag
never takes the next flag as its value: write a value that starts with - as --bounce=-x.wav, or
give a file as ./-x.wav. File names that are not valid Unicode reach the command unchanged.
The engine writes bounces and saved sessions through commands whose parameters are JSON text, so
those paths must be valid Unicode (--bounce, --save, and the --in session with
--in-place: exit 1).
An output that is one of the inputs is a usage error too, however the path is spelt (a.wav,
./a.wav, a symbolic or hard link):
| Subcommand | Inputs | Outputs | --in-place lets an output replace |
|---|---|---|---|
convert |
IN |
OUT |
IN |
run |
--in |
--bounce, --save |
the --in session, by --save only |
script |
FILE, --in |
--bounce, --save |
the --in session, by --save only; never FILE |
run and script take --in-place only with --in. A --bounce naming the --in session, and
--bounce and --save naming one file, are refused with or without --in-place. With
--in-place, an output that is a symbolic link to the input replaces the file it links to; the
link stays. An existing file that is not an input is replaced without asking.
Environment variables
| Variable | Flag | Notes |
|---|---|---|
SOUNDCRAFT_CONTROL_PORT |
app --port (CLI), --control (desktop app) |
A port or host:port, an IPv6 host in brackets ([::1]:7979). The desktop app takes the port of a loopback host:port (127.0.0.1, localhost). Its control server listens on 127.0.0.1 only, so it ignores another host from the variable, with a log warning, and starts no control server; given to --control, another host is a usage error |
- A flag wins over its variable.
- An empty variable counts as unset.
- A bad value is a usage error that names the variable.
<subcommand> --helplists the variable.- The automation roots (
--automation-read-root,--automation-write-root) are flags only. No variable grants file access.
SOUNDCRAFT_CONFIG_DIR, SOUNDCRAFT_NO_PREFS, SOUNDCRAFT_NO_SYSTEM_FONTS, SOUNDCRAFT_WAYLAND
(Linux) and RUST_LOG configure the desktop app (see the README and
the control protocol), not the CLI. soundcraft --help lists them.
An empty variable counts as unset (RFC-0012 rule 1.7), except SOUNDCRAFT_CONFIG_DIR: empty means
no settings folder.
SOUNDCRAFT_NO_PREFS, SOUNDCRAFT_NO_SYSTEM_FONTS and SOUNDCRAFT_WAYLAND are on/off switches with
one rule: 1/on/true/yes is on, 0/off/false/no is off (any case, spaces ignored), and unset or
blank is the default (off). A value that isn't one of these spellings is ignored (the default applies) and logs a warning that
names the variable.
Desktop app launch flags
soundcraft [OPTIONS] [FILES]... takes the same strict parsing and exit codes.
soundcraft --help lists the flags:
| Flag | Meaning |
|---|---|
FILES |
Sessions, audio and MIDI files to open; put -- before a name that starts with - |
--demo (alias --sample) |
Start with the demo session |
--no-audio |
Don't open an audio device |
--control <PORT> |
Start the control server on this port (0 picks a free port and prints it); falls back to SOUNDCRAFT_CONTROL_PORT |
--version, -V |
Print the version |
--help, -h |
Print the flags and the environment variables |
Man pages and completions
The Linux .deb and .rpm packages install man soundcraft-cli (plus a page per subcommand, such
as man soundcraft-cli-convert) and completions for bash, zsh and fish. The Linux and FreeBSD
tarballs carry the same files. The pages list each flag's environment variable, as --help does.
The desktop app has neither.
Without a package, generate them from a source checkout:
cargo run -p soundcraft-cli --example man-and-completions -- out/
out/ then holds soundcraft-cli.bash, _soundcraft-cli (zsh), soundcraft-cli.fish,
soundcraft-cli.elv (elvish), _soundcraft-cli.ps1 (PowerShell) and the .1 man pages. Copy
soundcraft-cli.bash to ~/.local/share/bash-completion/completions/soundcraft-cli,
soundcraft-cli.fish into ~/.config/fish/completions/, _soundcraft-cli into a directory on
zsh's $fpath, and read a page with man -l out/soundcraft-cli.1.
RFC-0012
soundcraft-cli follows RFC-0012: clap derive
types, thiserror errors, run(args, out, err) behind main, environment variables declared on
their flags, generated completions and man pages, tests that pin help and every usage error, no
output replacing an input without --in-place, and the ast-grep rules in lint/ast-grep. The shared automation flags are declared once in
crates/automation/src/args.rs.
Rules not followed yet:
- JSON flag (rule 1.3).
commands,plugins,parityand theinfosummary of a.scraftsession print text and have no--jsonflag. Whether such listings need one is an open question in the RFC itself. string-errorrule (section 3). Its ast-grep rule is on for the CLI code and the shared flags, not yet for the rest of the workspace.