Files
soundcraft/docs/cli.md
T
JonRC f46ea7d70c soundcraft-cli: print logged warnings and errors to stderr
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.
2026-11-02 23:48:01 -03:00

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> --help lists 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, parity and the info summary of a .scraft session print text and have no --json flag. Whether such listings need one is an open question in the RFC itself.
  • string-error rule (section 3). Its ast-grep rule is on for the CLI code and the shared flags, not yet for the rest of the workspace.