soundcraft · git:20261102.c601545 · 2026-11-02 · sha256 5c0724bc8fcec1cb

soundcraft git:20261102.c601545A

Immutable. This exact content never changes and is served at /api/v1/blob/5c0724bc8fcec1cb.

---
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.16.0`, commit `db51dd17398852ba70919c5a560d1c8ed9e3e6c6` (shallow clone of the release tag; the v0.15.0 ref was fetched for id diffs). The installed `/Applications/SoundCraft.app` reports version `0.16.0`, and its binary prints `SoundCraft 0.16.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.

v0.15.0 → v0.16.0 adds **`view.zoom_toggle_cancel`** (Cancel Zoom Toggle — Alt+Shift+E or Alt-click keeps the current view, PR #1101) — **one new command, total command specs 483 → 484** — and removes no id. Behaviour: the **Clip menu acts on the whole edit selection when the right-clicked clip is part of it** (#1196); **Mix clamps clip-FX gain and send-level automation** (#1126); **`transport.play {from}` plays at the requested position, not the selection** (#1075); `range_param` defaults the range start to the selection start (#1214); `AutoParam::parse` keeps plugin parameter-id case (#1227); and a hardening wave bounds automation-lane `value_at` (#1215), `GridValue::step_samples` (#1216), TempoMap bar math (#1220), non-finite `remove_dc`/RMS (#1221/#1222), CAF cookie lengths (#1200), drop-frame timecode labels (#1201), WAV byte rates (#1202), FLAC vendor strings (#1211), MIDI-import tempo/track floods (#1212) and H.264 POC/DPB saturation (#1226/#1229). MCP tools (17) and control methods (17) are unchanged — zero diff files under those trees. ⚠️ The previous audit credited the Zoom Toggle cancellation to v0.15.0 — compare-log tail trap; the `view.zoom_toggle_cancel` registration exists only at v0.16.0.

v0.15.0 was a **hardening release with no command-registry change**: what landed there was **send-fader moves writing send-level automation** (PR #1146; send-level automation exists in `crates/mix` at the v0.15.0 tag), the CLI `script --keep-going` **exit status reporting script failures**, the MCP server answering empty batches and non-object messages with a JSON-RPC error instead of silence, `.scgrp` clip-group files **refusing absolute audio paths**, Print Score/MusicXML output byte-budgeting, and overflow/hardening fixes (VST3 bus-layout limits among them).

## 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` (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`.

## Capabilities (verified)

### The command layer is the API (start here)

- **484 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.16.0): **389** literal `cmd!` ids in non-test engine sources (was 388 at v0.15.0; +`view.zoom_toggle_cancel`, none removed) + 94 generated by four local helper macros — `toggle!` 17, `flag!` 61, `radio!` 6, `option!` 10 — + 1 direct `CommandSpec` (`mix.insert_state`) = **484**. ⚠️ The previous ledger printed 482 from "397 literal" (a scope that included test-file registrations) while its own sum omitted the 10 `option!` ids; 484 is the reproducible non-test decomposition. Count your build with the CLI rather than any static number.
  - Each spec carries id, label, menu path, shortcut, params doc, enabled reason, journal/undo flags and a run function. Counting textual `cmd!(` occurrences overcounts macro-definition/doc/test 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 **551 ids**; `soundcraft-cli commands` and the headless MCP server report **484**. 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.16.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.16.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.16.0**, commit `db51dd17398852ba70919c5a560d1c8ed9e3e6c6`, release dated 2026-11-01; inspection date **2026-11-02**; the v0.15.0 ref was fetched for id diffs. Installed app prints `SoundCraft 0.16.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: **484 engine specs — +1 over v0.15.0's 482** (389 non-test literal `cmd!` ids [+`view.zoom_toggle_cancel`] + 94 helper-macro ids [toggle 17 / flag 61 / radio 6 / option 10] + 1 direct struct; the previous ledger's 482 sum omitted the 10 `option!` ids), 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 (unchanged).
- Shared library pins from `Cargo.toml`: **all `craft-libs` crates (`craft-docpath`, `craft-media`, `craft-ui`, `craft-update`) moved to rev `c5a1cbfb…`** this release (were `92d392cf…` + `craft-update` at `04aa1703…`); egui fork stays `6d518fc7…`.
- Evidence table: `evidence.md` next to this file.