soundcraft · git:20261101.18741c7 · 2026-11-01 · sha256 a63c150d41826f77
soundcraft git:20261101.18741c7A
Immutable. This exact content never changes and is served at /api/v1/blob/a63c150d41826f77.
---
name: soundcraft
description: >-
SoundCraft is an open-source, pure-Rust digital audio workstation (a clean-room Pro Tools-style
DAW) for macOS, Windows, Linux, FreeBSD and the browser: multitrack audio and MIDI editing, a
full mixer with built-in and CLAP/VST3/AU plug-ins, automation, recording, bounce/export, video
and surround — and every action is a command reachable from the CLI, a JSON control channel and
an MCP server. Trigger this skill whenever the user mentions SoundCraft (or `.scraft`, `.scraftz`,
`.scgrp`, `soundcraft-cli`, its control channel/MCP server, or "the SoundCraft app"), asks what it
can or cannot do, which audio/session/MIDI formats it reads or writes, its keyboard shortcuts, or
how to launch, script, automate, inspect or troubleshoot it — and equally when they never name it
but describe the job ("edit this multitrack session", "bounce a mix to WAV", "record takes from my
interface", "convert audio", "drive a DAW from an agent"). Do not infer SoundCraft behaviour from
Pro Tools knowledge: read this first.
---
# SoundCraft
**Audit basis:** this checkout is tag `v0.15.0`, commit `a97ce7556c5362718e8bcab5349477381ff3fb65` (shallow clone of the release tag). The installed `/Applications/SoundCraft.app` reports version `0.15.0`, and its binary prints `SoundCraft 0.15.0 (macos aarch64)`, so the bundle matches this source. **Verify against your installed version** if the ArtCraft Launcher has auto-updated since. Everything below was measured statically from this tree: no build, no GUI launch, no audio device was exercised.
## Overview
SoundCraft is an open-source, pure-Rust digital audio workstation: a clean-room reimplementation of the Avid Pro Tools workflow (recording, editing, mixing, automation, bounce) that also runs in a browser (`README.md`, `docs/target-app-parity.md`). The parity target is Pro Tools Ultimate 2026.4.1. It is a Cargo workspace of 14 crates plus three entry points — the desktop app (egui 0.37 this release), `soundcraft-cli` (now parsed with clap following the repo's RFC-0012), and a WebAssembly build. It is **pre-alpha**: the repo's own generated report counts 397/512 target menu leaves implemented by the engine (77.5 %, `docs/parity-checklist.md`) and the alpha gate still lists failing workflows — interface recording, MIDI recording, session interchange (`docs/roadmap.md` "Alpha gate"). Source: `github.com/storytold/soundcraft`.
v0.15.0 is a **hardening release with no command-registry change**: the engine still registers **482 command specs** (397 literal `cmd!` ids + 94 helper-macro ids + 1 direct), 17 MCP tools and 17 control methods, all re-counted identical to v0.14.0. What is new: **send-fader moves now write send-level automation** (PR #1146); **Zoom Toggle is cancellable** (Alt+Shift+E or Alt-click keeps the current view); the CLI `script --keep-going` **exit status now reports script failures**; the MCP server answers empty batches and non-object messages with a JSON-RPC error instead of silence; `.scgrp` clip-group files **refuse absolute audio paths**; Print Score/MusicXML output is byte-budgeted; and a wave of overflow/hardening fixes (H.264 POC/DPB saturation, CAF cookie caps, BWF/WAV/FLAC field limits, drop-frame timecode rejection, MIDI-import tempo/track flood bounds, VST3 bus-layout limits).
## Capabilities (verified)
### The command layer is the API (start here)
- **482 engine command specs** at this tag, from the 31 production modules registered by `command_specs()` (`crates/engine/src/cmd.rs` `command_specs`).
- Breakdown (re-counted at v0.15.0): 397 literal `cmd!` ids + 94 generated by four local helper macros — `toggle!` 17, `flag!` 61, `radio!` 6, `option!` 10 — + 1 direct `CommandSpec` (`mix.insert_state`) = 482. Identical to v0.14.0; no id was added or removed this release.
- Each spec carries id, label, menu path, shortcut, params doc, enabled reason, journal/undo flags and a run function. Counting textual `cmd!(` occurrences (397 here) overcounts macro-definition/doc lines and misses the 94 generated ids — derive the count from the id literals.
- **67 UI commands** (windows, dialogs, `ui.dock`, `ui.dock.reset`, `ui.theme`, `ui.audio_device`, `ui.set`, `window.*`, `view.mix_section`, `view.scroll_into_view`) live in the UI crate's `UI_COMMANDS` (moved modules in the refactor; count carried from v0.13.1). The desktop control channel appends them to `engine.commands`, so a running app reports **549 ids**; `soundcraft-cli commands` and the headless MCP server report **482**. No id overlaps the two sets.
- **CLI** (`soundcraft-cli`, 10 subcommands + `--version`/`--help`; **arguments are now parsed with clap following RFC-0012**, PR #1136 — same surface, standard clap usage errors for unknown flags): `info FILE`; `convert IN OUT [--bit-depth 16|24|32f] [--rate HZ] [--normalize] [--dither|--no-dither]`; `run [--in S.scraft | --demo] [--cmd ID[=JSON]]… [--bounce OUT] [--start T --end T] [--save S.scraft] [--inspect]`; `script FILE [--in S | --demo] [--save S] [--bounce OUT [--start T --end T]] [--keep-going]` (**`--keep-going` now reports script failures in the exit status** — a script that kept going past errors still exits non-zero; fixed this release); `commands [FILTER]`; `describe ID`; `app [--port P] METHOD [JSON]`; `mcp [--connect PORT] [--demo] [--automation-read-root DIR]… [--automation-write-root DIR]…`; `parity [--write PATH]`; `plugins`.
- Carried behaviour: every flag accepts `--flag=value`; `run`, `script` and `convert` **reject unknown options and missing values**; `--cmd=ID=JSON` inline; `--bounce` with no `--start`/`--end` bounces the **whole session**; `convert` dithers only when resolution is lost unless `--dither`/`--no-dither` says otherwise.
- `app` shorthand: a dotted command id is wrapped as `engine.execute`; accepted control methods stay methods. Caveat: `ui.scroll` and `ui.zoom` are **not** in that whitelist, so `soundcraft-cli app … ui.scroll/ui.zoom` is misrouted; send those two over the raw TCP channel.
- **MCP over stdio** (`crates/automation/src/mcp.rs`): protocol `2025-06-18` (accepts `2025-03-26`, `2024-11-05`); **17 tools**, unchanged. Core: `list_commands`, `execute`, `batch`, `inspect_session`, `new_session`, `open_session`, `save_session`, `import_audio`, `bounce_mix`, `parity`. App-only (need the desktop app plus `mcp --connect`): `screenshot`, `ui_inspect`, `ui_set`, `menu_invoke`, `click`, `drag`, `key`. Resources: `soundcraft://session` and `soundcraft://commands`.
- `batch` runs up to **1000** calls (`MAX_BATCH_CALLS`); larger arrays are rejected before anything runs. Any failed call makes the tool result `isError: true`; `keep_going` still runs the rest. Malformed envelope input (empty batch, non-object message) gets a proper JSON-RPC `Invalid Request` reply (fixed this release).
- Tool schemas are a subset: `new_session`/`open_session`/`save_session`/`import_audio`/`bounce_mix` forward their arguments to the engine command, so extra engine params work. Verify with `describe`.
- **Desktop control channel**: `soundcraft --control <port>` or `SOUNDCRAFT_CONTROL_PORT`; newline-delimited JSON over TCP on `127.0.0.1`, one reply per line. **17 canonical methods** (`crates/ui-egui/src/control.rs`): `engine.execute` (alias `command`), `engine.commands`, `engine.parity`, `session.inspect` (alias `document.inspect`), `ui.inspect`, `ui.menu.list`, `ui.menu.invoke`, `ui.set`, `ui.move`, `ui.click`, `ui.drag`, `ui.scroll`, `ui.zoom`, `ui.key`, `ui.text`, `ui.screenshot`, `app.quit`. `ui.dock`, `ui.dock.reset`, `ui.theme` and `ui.audio_device` are **UI commands**, invoked through `engine.execute`, not top-level methods.
- `ui.screenshot {path?}` needs a presented frame and fails with "no frame was presented (is the window visible?)".
- Two UI commands refuse a direct call and name the replacement: `ui.new_tracks_dialog` ("call `track.new` with parameters") and `ui.bounce_dialog` ("call `file.bounce_mix` with a path").
- Offscreen UI, no window: `cargo run -p soundcraft-ui-egui --example ui_shot -- out.png [script.jsonl] [--blank] [--size WxH]`.
- **Path confinement is MCP-only**: `--automation-read-root` / `--automation-write-root` confine every path for the in-process MCP server; each flag may be repeated, a kind left out grants no access of that kind, roots must exist, and `--connect` with roots is refused. The desktop control channel has no equivalent confinement.
### Editing and arrangement
- Edit window with tracks/clips/waveforms; Mix window (also as a separate native OS window through `window.mix_separate`); movable/dockable panels Tracks/Groups, Clips, MIDI Editor, Memory Locations, Undo History — **Tracks/Groups and Clips now dock as full-height columns** (`crates/ui-egui/src/docking.rs`, PR #1088).
- Five edit modes Shuffle, Slip, Spot, Grid, Grid-Relative; seven tools Zoom, Trim, Selector, Grabber, Scrubber, Pencil, Smart.
- Fades/crossfades in five shapes; cut/copy/paste/duplicate/repeat/shift/insert-silence/separate/heal/consolidate/strip-silence/nudge; Tab to Transient; Zoom Toggle; loop, quantize-to-grid, clip gain and gain envelope, clip effects, edit locks, colour, ratings.
- **Strip Silence has three modes**: `edit.strip_silence {…, mode?: strip|extract|separate, name?, number?, zeros?, suffix?}`; `edit.strip_silence_preview` (query) returns the padded ranges it would keep. Closing the Strip Silence window while the Mix view shows no longer leaves a stuck rectangle scan (fixed this release).
- **Clip Looping**: `clip.loop {clips?, count?, length?, fill?}`; `clip.unloop {mode?: remove|flatten}`.
- **Clip List › Auto Rename**: `clip.auto_rename {clips?, name?, number?, zeros?, suffix?}` sets the names editing gives the clips it separates; the schemes live in the session and survive save/reopen.
- Playlists with comping lanes, clip groups (`.scgrp`), Clip List, track folders, VCA masters, track freeze/commit/bounce, file-based track presets and Import Session Data. **`.scgrp` import now rejects audio paths that are absolute or contain `..`** (hardening this release).
- **`track.commit` keeps the track's exact `ChannelFormat`**, surround/height/ambisonic included, up to the renderer's 16 channels.
- Commands Keyboard Focus single-key editing in the Edit window; `options.keyboard_focus {commands|clips|groups|none}`.
- Undo/redo for document commands, an undo history window, and `engine.history` returning `{undo, can_redo}`.
### Mixing, automation and plug-ins
- 10 inserts and 10 sends per track, busses, aux inputs, master faders, VCAs, routing folders, object/bed routing, solo modes, mute/solo groups, phase invert, input trim, pre/post sends, automatic plug-in delay compensation. Aux and Folder strips are ordered by exact acyclic routing depth.
- **30 built-in plug-ins** in `REGISTRY`: 27 processors + 3 instruments (synth, drum synth, sampler; incl. `auto_pan`, `ring_mod`, `subharmonic`). **Auto Pan now keeps the stereo image** (fix this release). `engine.plugins` / `soundcraft-cli plugins` list them.
- Offline AudioSuite processing via `audiosuite.process {process, params?, clips?, tracks?, start?, end?}`: any built-in plug-in id plus `normalize|reverse|invert|gain|duplicate|time_stretch|pitch_shift|varispeed|speed_ramp|signal_generator` (10 named processes).
- Automation: lanes for volume, pan, mute, send level/pan/mute and any insert parameter; seven modes; **moving a send fader now writes send-level automation** (fixed this release, PR #1146); `automation.set_point`, `write_range`, `clear`, `thin`, `thin_all`, `write_to_current`, `write_to_all`, `volume_to_clip_gain`, plus coalesce commands. Mute automation is evaluated per sample inside a render block.
- Third-party hosting in-process: CLAP, VST3 and macOS Audio Units. Discovery: `engine.clap_plugins {rescan?}`, `engine.vst3_plugins {rescan?}`; ids `clap:<id>`, `vst3:<class id hex>`, `au:<type>:<subtype>:<manufacturer>`. **There is no Audio Unit discovery command** — the UI scans AUs at menu time.
- Plug-in editors: CLAP opens the plug-in's own floating window (Windows hosted-embedded), VST3 editors on macOS and Windows, Audio Units never; on the signed macOS build third-party VST3 is refused (library-validation entitlement).
- Plug-in presets are partly UI-only; for a hosted plug-in's opaque state use `mix.insert_state {track, slot, state: base64|null}` — not undoable and not journaled.
### Recording and audio devices
- Record arm, input monitoring, punch on selection or on the fly, pre/post-roll, loop recording with a playlist per take, destructive and track-punch modes.
- Takes **stream to disk** while recording: one WAV per take, the header rewritten every second; after stop the take is decoded into RAM as a session source.
- **Track input routing exists**: `track.input {"input":"In 3"}`; `plan_takes` records `track.channels()` consecutive device channels. What is missing is an input/output matrix with per-channel gain/delay and latency reporting.
- Device selection is real: `ui.audio_device {system?, output?, input?, sample_rate?, buffer_size?, list?}` changes the audio system/device/rate/buffer and reopens the player; it refuses while recording. **`setup.playback_engine` is a different, legacy engine command** whose settings playback never reads. ASIO is behind the opt-in `asio` build feature.
- Autosave on its own thread after changes, one folder per session, plus crash recovery at launch; `Backups/` beside a session keeps the newest ten timestamped copies on overwrite.
### MIDI, notation, instruments and time
- Instrument and MIDI tracks, piano-roll editor with velocity lane and event list, note add/edit/delete/move, quantize, input quantize, step input, transpose, real-time properties, MIDI track offsets, retrospective record.
- Standard MIDI File: reads formats 0 and 1 fully and format 2 best-effort; **always writes format 1**.
- `mix.sampler_load {track?, path, params?}` / `mix.sampler_clear` for the built-in Sampler.
- Score Editor, MusicXML export (`file.export_sibelius`, `file.send_to_sibelius`), printable SVG score (`file.print_score`).
- Monophonic audio-to-MIDI (`edit.copy_audio_as_midi`, `track.extract_midi`) and chord detection to markers.
- Five timebases; tempo and meter maps with ramps; key signatures; Identify Beat; Beat Detective; Elastic Audio warping.
- **No MIDI hardware I/O at all**: `setup.midi_*` only store settings.
### Audio and session formats
- **Read:** WAV (PCM 8/16/24/32, float 32/64, extensible, RF64/BW64, BWF, unfinalised recordings) and AIFF/AIFF-C natively; FLAC, MP3, Ogg Vorbis, AAC/ALAC in MP4/M4A/M4B, CAF, Matroska and ADPCM/A-law/µ-law via symphonia 0.6. Format is detected from bytes first.
- **Write:** `wav, aif, aiff, flac` only (`ENCODE_EXTENSIONS`), with optional TPDF dither; WAV switches to RF64 above 4 GiB. Float32 WAV and AIFF-C `fl32` keep finite samples above full scale.
- Waveform overviews are generated in memory, not cached as `.wfm` files.
- **Native session `.scraft`**: pretty-printed serde JSON with `format_version` **1**; a newer version is refused; `from_json` sanitises and validates (duplicate ids and an exhausted id space are rejected). Audio that only exists in memory is written as 32-bit float WAV into a sibling `Audio Files/` folder; saves are atomic; an overwrite copies the old file to `Backups/` first. There is no `deny_unknown_fields`, so unknown JSON keys are ignored by serde and dropped when the app next saves.
- `.scraftz` is the **browser** bundle (zip of the `.scraft` plus `Audio Files/`, 10 000-entry / 1 GiB caps). The desktop app does **not** open it.
- Stored media paths are resolved by `craft_docpath.resolve_absolute`: a stored path is followed only when local or on the session's own network share.
- `.scgrp` clip groups are JSON plus a `<name> Audio/` folder of 32-bit float WAVs.
- One session per running app; there are no session tabs.
### Export, bounce and delivery
- `file.bounce_mix {path, format?: wav|aiff|flac, bit_depth?: 16|24|32f, start?, end?, source?: main|bus name, normalize?, dither?, fold_down?: stereo}` streams the render to disk and returns `{path, bytes, seconds, peak_db, lufs, true_peak_db}`; `dither` defaults true, `normalize` false, omitted range means the edit selection else the whole content. **Bounce is about 20 % faster this release with byte-identical output** (PR #1144).
- `file.bounce_stems {dir, format?, bit_depth?, start?, end?, dither?, fold_down?}` writes one file per unmuted, active audio/instrument/MIDI track.
- `file.export_clips {dir, clips?, format?: wav}` writes clips as **WAV only**; `file.export_midi {path, tracks?}`, `file.export_session_text {path?, replace?}`, `file.export_selected_tracks_as_session`, `file.export_sibelius`/`file.send_to_sibelius`, `file.print_score`, `file.export_clip_groups`.
- `session.save_template {path, replace?}` writes a clip-stripped `.scraft`; there is no template browser.
### Video, surround and platforms
- Video track with thumbnails, Video window with optional timecode burn-in, Video Universe strip; pure-Rust decoding of H.264 (8-bit 4:2:0), Apple ProRes (422 family, 4444/XQ) and Motion JPEG. HEVC, AV1 and DNx movies are recognised by the demuxer but frames return "unsupported". Container/bitstream layers are shared craft-libs code (`craft_media::isobmff`, `craft_media::bitstream`).
- Surround/immersive mixing: 34 main/bus format choices from Mono to 9.1.6 and 1st–7th Order Ambisonics; `setup.main_format`; surround panners; `track.object` for object/bed routing; Renderer window.
- Native builds for macOS (universal, signed/notarized), Windows x64/x86/arm64 (per-user install by default now), Linux (AppImage, deb, rpm, Flatpak, tar.gz, riscv64 tarball; **XWayland drag-and-drop by default on Wayland**), FreeBSD, and WebAssembly. The web build has no TCP control channel and no filesystem.
- **Startup update prompt with direct self-updating** (craft-update).
## Known limitations and not-implemented
Do not assign these; each is absent or partial at v0.15.0:
- **MIDI hardware I/O is absent.** No recording from a keyboard, no live playing through instruments, no MIDI out, clock or MTC.
- **No Pro Tools interchange.** No `.ptx`/`.ptf`, AAF, OMF or Media Composer session import/export; the nearest bridge is `file.import_session_data` between SoundCraft `.scraft` sessions.
- **Audio-interface depth.** Input and output are separate cpal streams; the mix runs in fixed 512-sample blocks; no duplex clock, no I/O matrix, no latency reporting, no record-offset compensation.
- **All audio sources are decoded whole into RAM.** No disk streaming for playback; bounces themselves stream to disk.
- **Plug-in limits.** AAX is not hosted. The signed macOS build refuses third-party VST3 (library-validation entitlement). AU editors are not hosted and AUs have no discovery command; CLAP embedded editors only on Windows; VST3 editors only macOS/Windows. No external sidechain, no ARA, no out-of-process sandboxing.
- **No compressed export** (MP3/AAC/M4A/Ogg/Opus) even though those decode on import.
- **Video is decode-only and limited.** No HEVC/AV1/DNxHD/DNxHR decode, no video export or bounce-with-video, no external timecode.
- **No immersive delivery.** No ADM BWF, Dolby Atmos renderer integration or binaural.
- **No control surfaces (HUI/MCU/EUCON) and no external sync (MTC/LTC/video reference).**
- **English-only UI.** No string catalog; a Hangul fallback font is appended for Korean names; no other fallbacks.
- **Session management is thin.** No template browser, no batch rename; the Workspace window is a one-folder file list.
- **No speech-to-text** (settings only) and **no fidelity harness** against Pro Tools.
- **`.scraftz` does not open on the desktop.**
- **Parity is uneven by area.** The generated report counts 397/512 menu leaves implemented (Window 1/52, AudioSuite 0/28, View 92/112, File 22/30). AudioSuite catalog leaves all map to the single `audiosuite.process` command.
- **Docs still lag the code** in places (alpha-gate input-device row, G-16 track-preset recall, the Hangul fallback denial). Trust the code paths cited here, then `soundcraft-cli describe`.
## How to operate
### Launch on macOS
- GUI binary `/Applications/SoundCraft.app/Contents/MacOS/SoundCraft`; `open -a SoundCraft`, or `open -a SoundCraft --args --demo`. A terminal launch with `--control` prints the control port on stdout.
- App flags: `--demo` / `--sample`, `--no-audio` (never arm or record in a smoke test), `--control <port>` (`0` = pick a free port and print it), `--version`/`-V`, and positional files: `.scraft` opens as a session, `.mid`/`.midi`/`.smf` imports MIDI, anything else imports as audio.
- Environment: `SOUNDCRAFT_CONTROL_PORT`, `SOUNDCRAFT_CONFIG_DIR`, `SOUNDCRAFT_NO_PREFS` (recommended for agent test runs), `SOUNDCRAFT_NO_SYSTEM_FONTS`, `RUST_LOG`.
- Settings on macOS: `~/Library/Application Support/SoundCraft/` — `ui.json`, `Autosave/`, `Presets/`, `logs/soundcraft.log`. A `portable.txt` beside the executable switches to `<exe dir>/SoundCraftData`.
- `soundcraft-cli` is **not inside the app bundle**: install `soundcraft-cli-<ver>-macos-universal.zip` from the release, or build it. Check both versions before mixing them.
### Document and window model
One session per app; `session.new`/`session.open`/`session.close` replace it. Programmatic session switches **do not prompt to save** — save first. Edit and Mix are separate views; `window.mix_separate` puts Mix in its own native window. There are no session tabs.
### Positions, references and ranges
- Positions: a JSON integer (or float) is **samples**; `{"seconds": 2.5}` is seconds; a string is parsed in the current main-counter format then all formats, optionally prefixed with `bars_beats:`, `min_secs:`, `timecode:`, `feet_frames:` or `samples:`. CLI `--start`/`--end` parse a bare decimal as seconds.
- Ranges: `start` + `end`, or `start` + `length`; `start` alone is a point range; both omitted = the edit selection. Tracks by id or name; clips by id; buses by case-insensitive name.
### Open, import, save, export
- New/open: `session.new {name?, sample_rate?, bit_depth?: 24, template?: blank|demo}`; `session.open {path}` never fails on missing media (it warns); `session.save {path?, replace?}`, `session.save_as`, `session.save_copy`, `session.save_template`, `session.revert`, `session.close`.
- Import: `file.import_audio {path | paths: [..], track?, at?, new_tracks?}`, `file.import_midi`, `file.import_video`, `file.import_clip_groups`, `file.import_session_data`.
- Export/bounce: see above. Always read the returned `path`/`bytes`/levels; a completed call does not prove the audio is non-silent.
- Audio device: `ui.audio_device {"list":true}` returns `{config, device, systems}`; applying reopens the devices and refuses while recording. Save before changing devices.
### Keyboard shortcuts (verified in code)
Space play/stop; Shift+Space half-speed; Cmd+Space or F12 record; F1–F4 edit modes; F5–F10 tools; Enter new memory location; Cmd+= Mix/Edit; Tab to transient; Cmd+Shift+N new tracks; Cmd+S/O/N save/open/new; Cmd+E separate; Cmd+D duplicate; Cmd+U strip silence; Cmd+Alt+L loop clip; Cmd+Z undo; Cmd+Shift+K export clips; Cmd+Alt+B bounce mix; Cmd+P print score; Cmd+1 Transport, Cmd+3 Big Counter, Cmd+4 Automation, Cmd+5 Memory Locations, Cmd+9 Video; Alt+Shift+C track commit; Cmd+Alt+[ / ] waveform zoom; Cmd+Ctrl+1–5 zoom presets; Cmd+Alt+0–5 clip rating; Cmd+W close window. The in-app **Setup › Keyboard Shortcuts** window (`window.shortcuts`) is the live list.
### Recipes that work at this tag
```sh
# Headless: demo session → set a level → insert an EQ → bounce → print the session JSON.
soundcraft-cli run --demo \
--cmd 'mix.volume={"track":"Kick","db":-6}' \
--cmd 'mix.insert={"track":"Bass","plugin":"eq_7band"}' \
--bounce mix.wav --inspect
# Live app: control channel on a free port, no output device.
/Applications/SoundCraft.app/Contents/MacOS/SoundCraft --demo --no-audio --control 7801 &
soundcraft-cli app --port 7801 mix.new_bus '{"name":"Verb"}'
soundcraft-cli app --port 7801 mix.send '{"track":"Bass","bus":"Verb","level_db":-12}'
soundcraft-cli app --port 7801 automation.write_range '{"track":"Bass","param":"volume","start":0,"end":96000,"value":-6}'
soundcraft-cli app --port 7801 file.bounce_mix '{"path":"mix.wav","source":"Verb"}'
soundcraft-cli app --port 7801 ui.screenshot '{"path":"shot.png"}'
# Named clips from Strip Silence, then preview the ranges without touching the session.
soundcraft-cli run --in song.scraft --cmd 'edit.strip_silence_preview={"tracks":["Vox"]}'
soundcraft-cli run --in song.scraft \
--cmd 'edit.strip_silence={"tracks":["Vox"],"mode":"strip","name":"VOX","number":1,"zeros":2}' \
--save song.scraft --inspect
# Give an MCP client a headless DAW confined to two read folders and one output folder.
claude mcp add soundcraft -- soundcraft-cli mcp --demo \
--automation-read-root ./project --automation-read-root ./samples \
--automation-write-root ./out
```
`mix.insert` takes a built-in id from `engine.plugins` (or a `clap:`/`vst3:`/`au:` id); `mix.send` needs the bus to exist. All positions in these examples are samples.
### Discover the build you are talking to
`soundcraft-cli commands <filter>` lists ids/labels/menu paths; `soundcraft-cli describe ID` prints the authoritative parameter doc; over the control channel use `engine.commands {filter}` and `session.inspect`; over MCP use `list_commands` and `inspect_session`. Labels, menu paths and shortcuts can change between releases — bind to **ids**.
## Working with an AI agent
Legitimate, evidence-checkable work:
- **Prepare and convert inputs.** `soundcraft-cli info FILE` probes audio; `soundcraft-cli convert IN OUT` lands assets in WAV/AIFF/FLAC (output extension decides; anything else is refused).
- **Drive it headlessly** with `soundcraft-cli run` / `script` / `mcp`, or bridge MCP to a running app with `--connect`. Prefer `batch` for many edits (cap 1000), then `inspect_session` and `session.audio_health` to verify. Most document commands are undoable; queries, view/session settings and the explicitly non-journaled `mix.insert_state` are not.
- **Read and repair `.scraft`.** Pretty JSON with `format_version: 1`: you may parse, diff and patch it, but never bump the version, and do not add private top-level keys. Keep ids unique per namespace. Keep `Audio Files/` paths relative to the session folder. Never edit a session while the app or CLI has it open.
- **Compose mix work from commands.** `mix.new_bus` before `mix.send`; `mix.insert {"plugin":"eq_7band"}` then `mix.insert_params`/`mix.insert_param`; `mix.volume`/`pan`/`trim`; `automation.write_range` or `set_point`; `file.bounce_mix … source:"Verb"` to bounce a bus. `engine.plugins` lists built-ins; AU has no query — know the fourcc id or use the UI.
- **Name clips from a batch edit.** `clip.auto_rename` before a cut/Strip Silence run gives every resulting piece a numbered name.
- **Verify exports.** `file.bounce_mix` returns `bytes`, `seconds`, `peak_db`, `lufs`, `true_peak_db`; check the file exists, has plausible duration and non-silent levels, then re-probe with `soundcraft-cli info`. For a stem set, check `files` count and each file.
- **Automate UI acceptance** with the control channel and its UI commands. Run with `--no-audio` and an isolated `SOUNDCRAFT_CONFIG_DIR`; never arm a track, enable input monitoring or start recording in a smoke test.
- **What not to attempt:** driving the GUI blind; promising AAF/OMF/`.ptx`, MIDI-hardware recording/playback, MP3/AAC export, ADM/Atmos delivery or video export; opening `.scraftz` on the desktop; assuming `setup.playback_engine` changes the device (use `ui.audio_device`); expecting Audio Unit discovery or AU editors; reading/copying Pro Tools resources — SoundCraft is clean-room (`AGENTS.md`).
## Verification protocol
SoundCraft is pre-alpha and its docs lag the code in a few places. For any real task:
1. **Round-trip on a throwaway session first**: `session.new` → one edit → `session.save` to a scratch folder → `session.open` it back → `file.bounce_mix` → confirm the returned levels are non-silent and the file exists.
2. **Never trust a silent export**: compare `peak_db`/`lufs`/`true_peak_db` with expectations and re-probe the output with `soundcraft-cli info`.
3. **Back up and version per session**: copy the whole folder (`.scraft` + `Audio Files/`), not just the JSON; `Backups/` keeps the newest ten.
4. **One session at a time, isolated profile**: run agents with `SOUNDCRAFT_CONFIG_DIR` pointing at a fresh folder.
5. **Update apps only between projects**: this skill is pinned to v0.15.0. Check `--version` before relying on a format or parameter detail.
6. **Inspect, don't guess**: `soundcraft-cli describe ID` and `engine.commands` give the authoritative schema; `session.audio_health` checks loaded media without touching files.
## Sources & evidence
- Repo: https://github.com/storytold/soundcraft — inspected at tag **v0.15.0**, commit `a97ce7556c5362718e8bcab5349477381ff3fb65`, release dated 2026-10-31; inspection date **2026-11-01**. Installed app prints `SoundCraft 0.15.0 (macos aarch64)`; `CFBundleIdentifier` `ai.storyteller.soundcraft`. The bundle contains only `SoundCraft`, not `soundcraft-cli`.
- Read: `README.md`, `Cargo.toml`, `apps/soundcraft/src/{main.rs,control_server.rs}`, `apps/soundcraft-cli/src/{main.rs,args.rs,automation_args.rs}`, `crates/engine/src/cmd.rs` (registry) and `crates/engine/src/cmd/` modules (incl. `cmd/strip_silence.rs`, `cmd/setup_more.rs`), `crates/engine/src/{io.rs,autosave.rs,clip_group_file.rs,score.rs,file_access.rs}`, `crates/model/src/{session.rs,mixer.rs,clip.rs,automation.rs,track.rs}`, `crates/audio-io/src/`, `crates/dsp/src/{plugins.rs,plugins/,offline.rs,meter.rs}`, `crates/midi/src/smf.rs`, `crates/mix/src/lib.rs`, `crates/playback/src/{lib.rs,record.rs,devices.rs}`, `crates/video/src/{lib.rs,movie.rs}`, `crates/automation/src/mcp.rs`, `crates/{clap-host,vst3-host,au-host}/src/lib.rs`, `crates/ui-egui/src/{control.rs,docking.rs,fonts.rs,menus.rs}`, `crates/engine/catalog/menus.txt`, `docs/{mcp,control-protocol,gaps,parity-checklist,plugin-parity}.md`.
- Counts recomputed from source at this pin: **482 engine specs — identical to v0.14.0** (397 literal `cmd!` + 94 helper-macro ids [toggle 17 / flag 61 / radio 6 / option 10] + 1 direct struct), 67 UI commands (count carried), 17 MCP tools / 2 resources, 17 control methods (2 aliases), 10 CLI subcommands (clap-parsed), 30 built-in plug-ins, 10 AudioSuite processes, 34 channel formats, 4 write extensions, `FORMAT_VERSION = 1`, `MAX_BATCH_CALLS = 1000`, 512-leaf menu catalog. Menu-parity 397/512 is the repo's generated report.
- Shared library pins from `Cargo.toml`: `craft-docpath`, `craft-media`, `craft-ui` at rev `92d392cf…`; **`craft-update` moved to rev `04aa1703…`** this release.
- Evidence table: `evidence.md` next to this file.