Commands
Every typed command the Open DJ performance view accepts, listed from the code. Deck A is the list, grouped by part of the rig; Deck B shows an agent sending them.
Generated by tools/gen_commands.py from main of the private development repository (music-dj-tools) at 487fa677d7 (committed Fri 2 Oct 2026) on Sat 3 Oct 2026. Not written by hand.
One list, read from the code.
Most deck and mixer controls are typed commands, reachable over HTTP, the opendj command line and opendj mcp, and an agent sends the same ones the app's own buttons and keys do. Where a button calls the function directly instead, the UI column says so. This page lists every command, straight from the type that checks them.
Where each column comes from
- Command and fields: the
PerformanceCommandunion atperformance-ipc.svelte.ts:196. A?marks an optional field. The muted value after a field is the range the CLI accepts. - CLI verb: the verb table in
apps/opendj_cli/catalog.py. A test fails if the table and the union disagree, and the section groups on this page are that table's own headings. - UI counterpart: a scan of the app's frontend source for the place a control dispatches the command. Hover a file name for the full path and line.
- What it does: one plain line per command, kept in
tools/command_lines.json. The generator stops if a command has no line.
The scan can show that a control sends a command. It cannot show that no control does, so where it finds nothing the page says UNKNOWN rather than guessing. Today that covers type: 'set_waveform_design', type: 'master_delay_ms', type: 'headphone_calibrate_abort', type: 'auto_play_two_track', type: 'pins_show_other_users', type: 'library_panels', type: 'show_stems', type: 'rescue_resume', type: 'rescue_stop_all'. A hand check on Sat 3 Oct 2026 found indirect UI paths the scan does not trace for five of them: rescue_stop_all (the rescue notice's Undo), rescue_resume (restoring after a crash), headphone_calibrate_abort (closing the cue alignment dialog), and set_waveform_design and show_stems (Settings).
Transport.
14 commands, 14 with a UI or keyboard counterpart found.
| Command | Fields | What it does | UI counterpart | CLI verb |
|---|---|---|---|---|
type: 'load' | deck: DeckId 1-4stable_id: stringrefuseIfMaster?: booleanstems?: booleansuppressCommandErrorToast?: boolean | Load a library track onto a deck by its stable id. It can refuse when that deck is the live master. | UI controlBrowserPanel.svelte:2611 | load |
type: 'load_play_intent' | deck: DeckId 1-4generation: numberdesired_play: boolean true|false | Say whether a deck should start playing once its pending load finishes. | UI controlBrowserPanel.svelte:2593+ keyboard | load_play_intent |
type: 'unload' | deck: DeckId 1-4refuseIfMaster?: boolean | Eject the track from a deck. | UI controlBrowserPanel.svelte:2608 | unload |
type: 'play' | deck: DeckId 1-4playing: booleanquantize?: booleanstart_at_context_sec?: number | Start or pause a deck. With quantize set, the start waits until the deck lines up with the master's downbeat. | UI controlBrowserPanel.svelte:2631+ keyboard | playplay_quantizedpause |
type: 'cue' | deck: DeckId 1-4 | Press CUE on a deck. | UI controlDeck.svelte:231 | cue |
type: 'seek' | deck: DeckId 1-4position_ms: number | Move a deck's playhead to a position in milliseconds. | UI controlCreatePairingSheet.svelte:125 | seek |
type: 'waveform_seek' | deck: DeckId 1-4position_ms: numbersnap: WaveformSeekSnap downbeat|beat|exact | Seek the way a waveform click does, snapped to a downbeat, a beat or the exact spot. | UI controlWaveRow.svelte:463 | waveform_seek |
type: 'loop' | deck: DeckId 1-4loop: { in_ms: number; out_ms: number } | null in_ms out_ms | Set a loop from an in point to an out point, or clear it with null. | UI controlDeck.svelte:243+ keyboard | looploop_exit |
type: 'beat_loop' | deck: DeckId 1-4beats: numberstart_ms?: number | Start a loop a given number of beats long. | UI controlDeck.svelte:237+ keyboard | beat_loop |
type: 'beat_jump' | deck: DeckId 1-4beats: number | Jump forward or back by a number of beats. | UI controlDeck.svelte:247 | beat_jump |
type: 'loop_interval_mode' | deck: DeckId 1-4enabled: boolean true|false | Turn the loop controls' interval grid on or off. | UI controlDeck.svelte:251 | loop_interval_mode |
type: 'loop_interval_base' | deck: DeckId 1-4base: number | Set the base length the loop interval grid counts from. | UI controlDeck.svelte:255 | loop_interval_base |
type: 'tempo' | deck: DeckId 1-4ratio: number | Set a deck's tempo as a ratio of the track's own speed. | UI controlCreatePairingSheet.svelte:122 | tempo |
type: 'pitch_range' | deck: DeckId 1-4range: PitchRange 8|16|100 | Set the range of the deck's tempo control. | UI controlDeck.svelte:365 | pitch_range |
Deck modes.
13 commands, 13 with a UI or keyboard counterpart found.
| Command | Fields | What it does | UI counterpart | CLI verb |
|---|---|---|---|---|
type: 'quantize' | deck: DeckId 1-4enabled: boolean true|false | Turn quantize on or off for a deck. | UI controlDeck.svelte:272 | quantize |
type: 'quantize_grid' Partly implemented | deck: DeckId 1-4beats: 1 | 4 | 8 | 'phase' 1|4|8 | Set the quantize grid in beats. The phase option is rejected as not implemented. | UI controlDeck.svelte:282 | quantize_grid |
type: 'beat_sync' | deck: DeckId 1-4enabled: boolean true|false | Turn beat sync on or off for a deck. | UI controlDeck.svelte:287 | beat_sync |
type: 'sync_mode' | deck: DeckId 1-4mode: SyncMode beat|bar | Sync to the beat or to the bar. | UI controlTempoEditModal.svelte:234 | sync_mode |
type: 'master' | deck: DeckId 1-4lock?: boolean | Make a deck the tempo master, optionally locked. | UI controlCreatePairingSheet.svelte:124 | master |
type: 'master_tempo' | deck: DeckId 1-4enabled: boolean true|false | Keep the key steady when the tempo changes. | UI controlDeck.svelte:304 | master_tempo |
type: 'stem_mute' | deck: DeckId 1-4stem: StemControl vocal|instrumental|drumsmuted: boolean true|false | Mute or unmute one stem on a deck: vocal, instrumental or drums. | UI controlDeck.svelte:312 | stem_mute |
type: 'stem_solo' | deck: DeckId 1-4stem: StemControl vocal|instrumental|drumssolo: boolean true|false | Solo or unsolo one stem on a deck. | UI controlBrowserPanel.svelte:2683 | stem_solo |
type: 'stem_eq_mode' | deck: DeckId 1-4enabled: boolean true|false | Turn stem EQ mode on or off for a channel. | UI controlMixer.svelte:103 | stem_eq_mode |
type: 'stem_gain' | deck: DeckId 1-4stem: StemControl vocal|instrumental|drumsvalue: number 0..1 | Set the level of one stem on a deck. | UI controlMixer.svelte:107 | stem_gain |
type: 'slip' | deck: DeckId 1-4enabled: boolean true|false | Turn slip mode on or off. | UI controlDeck.svelte:330 | slip |
type: 'key_sync' | deck: DeckId 1-4enabled: boolean true|false | Turn key sync to the master deck on or off. | UI controlDeck.svelte:338 | key_sync |
type: 'key_nudge' | deck: DeckId 1-4semitones: -1 | 1 -1|1 | Shift a deck's key up or down by a semitone. | UI controlDeck.svelte:345 | key_nudge |
Mixer and headphones.
16 commands, 14 with a UI or keyboard counterpart found.
| Command | Fields | What it does | UI counterpart | CLI verb |
|---|---|---|---|---|
type: 'trim' | deck: DeckId 1-4value: number 0..1 | Set a channel's trim (input gain). | UI controlMixer.svelte:65 | trim |
type: 'eq' | deck: DeckId 1-4band: EqBand low|mid|highvalue: number 0..1 | Set a channel's low, mid or high EQ. | UI controlEqOverlay.svelte:31 | eq |
type: 'filter' | deck: DeckId 1-4value: number 0..1 | Set a channel's filter. | UI controlMixer.svelte:73 | filter |
type: 'fader' | deck: DeckId 1-4value: number 0..1 | Set a channel fader. | UI controlDeck.svelte:87 | fader |
type: 'assign' | deck: DeckId 1-4assign: CrossfaderAssign A|B|THRU | Assign a channel to crossfader side A, side B or THRU. | UI controlMixer.svelte:81 | assign |
type: 'channel_cue' | deck: DeckId 1-4enabled: boolean true|false | Send a channel to the headphone cue, or take it off. (also HTTP) | UI controlMixer.svelte:89 | channel_cue |
type: 'crossfader' | value: number 0..1 | Move the crossfader. | UI controlMixer.svelte:85 | crossfader |
type: 'master_volume' | value: number 0..1 | Set the master output level. | UI controlTopBar.svelte:301 | master_volume |
type: 'headphone_mix' | value: number 0..1 | Blend the headphones between cue and master. (also HTTP) | UI controlMixer.svelte:111 | headphone_mix |
type: 'headphone_level' | value: number 0..1 | Set the headphone level. (also HTTP) | UI controlMixer.svelte:115 | headphone_level |
type: 'head_delay_ms' | value: number 0..500 | Delay the headphone cue signal, in milliseconds. (also HTTP) | UI controlMixer.svelte:123 | head_delay_ms |
type: 'master_mute' | muted: boolean true|falsepersist?: boolean | Mute or unmute the master output. | UI controlTopBar.svelte:862 | master_mute |
type: 'headphone_alignment_mode' | value: HeadphoneAlignmentMode headphones_only|delay_all|hybrid | Choose how a measured headphone-to-room offset is split between the headphone and room delays. (also HTTP) | UI controlMixer.svelte:128 | headphone_alignment_mode |
type: 'master_delay_ms' | value: number 0..1500 | Delay the room (master) output, in milliseconds. (also HTTP) | UNKNOWN | master_delay_ms |
type: 'headphone_calibrate' | interactive?: boolean | Run the microphone calibration that measures the headphone-to-room offset. (also HTTP) | UI, same functionCueAlignModal.svelte:95 | headphone_calibrate |
type: 'headphone_calibrate_abort' | none | Stop a running calibration without applying it. (also HTTP) | UNKNOWN | headphone_calibrate_abort |
Library, outputs and views.
18 commands, 13 with a UI or keyboard counterpart found.
| Command | Fields | What it does | UI counterpart | CLI verb |
|---|---|---|---|---|
type: 'set_waveform_design' | design: WaveformDesign tri-band|mono|line | Pick the waveform style: tri-band, mono or line. | UNKNOWN | set_waveform_design |
type: 'browser_select_playlist' | playlist_id: string | Open a playlist in the library browser. | UI controlBrowserPanel.svelte:1424 | browser_select_playlist |
type: 'headphone_outputs_refresh' | none | Re-list the available audio output devices. (also HTTP) | UI controlMixer.svelte:132 | headphone_outputs_refresh |
type: 'headphone_output_acquire' | none | Ask for access to a separate headphone output device. | UI controlMixer.svelte:136 | headphone_output_acquire |
type: 'headphone_output_select' | device_id: string | Send the headphones to an output device. (also HTTP) | UI controlMixer.svelte:140 | headphone_output_select |
type: 'headphone_master_select' | device_id: string | Send the master output to an output device. (also HTTP) | UI controlMixer.svelte:144 | headphone_master_select |
type: 'headphone_input_select' | device_id: string | Choose the audio input device. (also HTTP) | UI controlMixer.svelte:148 | headphone_input_select |
type: 'preview_cue' | stable_id: stringratio: number 0..1bpm?: number track BPM | Preview a library track in the headphones, starting part way in. No deck is loaded. (also HTTP) | UI, same functionBrowserPanel.svelte:2532 | preview_cue |
type: 'preview_stop' | none | Stop the library preview. (also HTTP) | UI, same functionTrackTable.svelte:1927 | preview_stop |
type: 'output_mode' | mode: HeadphoneOutputMode practice|two_outputs | Choose practice mode (cue blended into the main output), two separate outputs, or split-cable mode (main on the left, cue on the right). The CLI offers the first two. (also HTTP) | UI controlMixer.svelte:119 | output_mode |
type: 'analysis_source' | feature: AnalysisSourceFeature beatgridsource: AnalysisSource rekordbox|own | Choose whether beatgrids come from rekordbox or from Open DJ's own analysis. | UI controlAnalysisSourceToggle.svelte:103 | analysis_source |
type: 'auto_play_two_track' Not implemented | none | Reserved for two-track AutoPlay. Rejected today as not implemented. | UNKNOWN | auto_play_two_track |
type: 'auto_play_next_arm' | none | Arm AutoPlay's early move to the next track. | UI controlTopBar.svelte:169 | auto_play_next_arm |
type: 'auto_play_next_cancel' | none | Cancel an armed AutoPlay move. | UI controlTopBar.svelte:169 | auto_play_next_cancel |
type: 'pins_show_other_users' Not implemented | none | Reserved for showing other people's comment pins. Rejected today as not implemented. | UNKNOWN | pins_show_other_users |
type: 'library_panels' | panel: LibraryPanel next|recommendedcollapsed: boolean true|false | Collapse or expand the Next or Recommended library panel. | UNKNOWN | library_panels |
type: 'show_stems' | enabled: boolean true|false | Show or hide the per-stem waveforms under each deck. | UNKNOWN | show_stems |
type: 'feedback_mark' | vote: 'bad' | 'good' | 'great' bad|good|great | Mark the current moment as bad, good or great. | UI controlVibeMeter.svelte:26 | feedback_mark |
Hot cues and safety loop.
7 commands, 7 with a UI or keyboard counterpart found.
| Command | Fields | What it does | UI counterpart | CLI verb |
|---|---|---|---|---|
type: 'safety_loop_save' | deck: DeckId 1-4 | Save the deck's engaged loop as its safety loop. | UI controlDeck.svelte:259 | safety_loop_save |
type: 'safety_loop_arm' | deck: DeckId 1-4armed: boolean true|false | Arm or disarm the deck's safety loop. | UI controlDeck.svelte:263 | safety_loop_arm |
type: 'safety_loop_clear' | deck: DeckId 1-4 | Clear the deck's saved safety loop. | UI controlDeck.svelte:267 | safety_loop_clear |
type: 'hot_cue_save' | deck: DeckId 1-4slot: HotCueSlot A-Hin_ms: numberrevision: stringcomment?: string | null | Save a hot cue on a pad. The track needs a rekordbox mapping. | UI controldeck-hot-cue-actions.ts:49 | hot_cue_save |
type: 'hot_cue_clear' | deck: DeckId 1-4slot: HotCueSlot A-Hrevision: string | Delete the hot cue on a pad. | UI controldeck-hot-cue-actions.ts:84 | hot_cue_clear |
type: 'hot_cue_restore' | deck: DeckId 1-4slot: HotCueSlot A-Hrevision: stringreversal_id: string | Undo the last hot cue save or delete, using its reversal id. | UI controldeck-hot-cue-actions.ts:106 | hot_cue_restore |
type: 'hot_cue_trigger' | deck: DeckId 1-4slot: HotCueSlot A-H | Jump to a hot cue. With BeatSyncMax on, a playing deck with no loop waits for its next downbeat. | UI controlDeck.svelte:205 | hot_cue_trigger |
Overlay, pairing and rescue.
12 commands, 10 with a UI or keyboard counterpart found.
| Command | Fields | What it does | UI counterpart | CLI verb |
|---|---|---|---|---|
type: 'tech_mode_toggle' | none | Turn technically-working mode on or off. It is a view overlay with no engine effect. | Keyboardtechnically-working-hotkeys.ts:100 | tech_mode_toggle |
type: 'tech_mode_peek' | peeking: boolean true|false | Start or stop a peek at technically-working mode. | Keyboardtechnically-working-hotkeys.ts:101 | tech_mode_peek |
type: 'tech_mode_opt_reveal' | revealed: boolean true|false | Set the Option-key reveal in technically-working mode. | Keyboardtechnically-working-hotkeys.ts:107 | tech_mode_opt_reveal |
type: 'tech_mode_eq_raised' | raised: boolean true|false | Raise or lower the EQ in technically-working mode. | Keyboardtechnically-working-hotkeys.ts:122 | tech_mode_eq_raised |
type: 'tech_mode_edge_hover' | edge: EdgeRegion top|left|right|bottomhovered: boolean true|false | Mark a screen edge as hovered or not in technically-working mode. | Keyboardtechnically-working-hotkeys.ts:79 | tech_mode_edge_hover |
type: 'pairing_snapshot_open' | none | Open a pairing snapshot of the current decks. | UI controlTopBar.svelte:305 | pairing_snapshot_open |
type: 'pairing_snapshot_remove_eq_adjuster' | deck: DeckId 1-4band: EqBand low|mid|high | Drop one EQ adjustment from a deck in the open pairing snapshot. | UI controlCreatePairingSheet.svelte:45 | pairing_snapshot_remove_eq_adjuster |
type: 'pairing_snapshot_save' | from_deck: DeckId 1-4to_deck: DeckId 1-4 | Save the open snapshot as a pairing from one deck's track to another's. | UI controlCreatePairingSheet.svelte:52 | pairing_snapshot_save |
type: 'playlist_undo' | none | Undo the last playlist edit. | UI controlplaylist-history-chrome.svelte.ts:54+ keyboard | playlist_undo |
type: 'playlist_redo' | none | Redo the last undone playlist edit. | UI controlplaylist-history-chrome.svelte.ts:58+ keyboard | playlist_redo |
type: 'rescue_resume' | decks: Array<{ deck: DeckId; position_ms: number }> 1:5000[,3:12000] | Restart several decks together at saved positions after a crash. | UNKNOWN | rescue_resume |
type: 'rescue_stop_all' | none | Stop every deck that a rescue restart brought back. | UNKNOWN | rescue_stop_all |
An agent at the decks.
An agent sends the same commands three ways. All three need the performance view open in the app: there is no audio without it.
Three ways in
- In the page:
window.musicDjToolsPerformanceexposesdispatchandquery, among others. A browser agent drives the open page directly. - Over HTTP:
POST /api/v1/commandstakes one order:single,sequence,parallelorramp. The open page claims it, runs it through the same dispatcher and returns the result. With no page open the route answers409. - From a terminal: the
opendjcommand is a client of that HTTP route. It runs from a source checkout, and the Mac app's payload carries it, plus theopendj mcpserver for MCP clients (AGENT-05, AGENT-11).
The CLI checks each order against the app's state mirror and exits with its own code when the page accepted an order but the mirror never confirmed it. Read state back with opendj state or query() before assuming a deck moved.
tests/opendj_cli/test_cli_end_to_end.py:375page.start()
try:
code = main(_argv(engine, "do", "load 1 warehouse", "then", "play 1", "and", "play 2"))
assert code == EXIT_CONFIRMED
assert page.mirror["decks"]["1"]["stable_id"] == "warehouse"
assert page.mirror["decks"]["1"]["playing"] is True
assert page.mirror["decks"]["2"]["playing"] is True
finally:
page.stop()
assert page.orders == [
{"kind": "single", "payload": {"type": "load", "deck": 1, "stable_id": "warehouse"}},
{
"kind": "parallel",
"payload": [
{"type": "play", "deck": 1, "playing": True},
{"type": "play", "deck": 2, "playing": True},
],
},
]
tests/opendj_cli/test_commands_master_mute_persist.py:24response = httpx.post(
f"{engine.base_url}/api/v1/commands",
json={"single": {"type": "master_mute", "muted": True}},
timeout=10.0,
)
apps/webui/frontend/tests/e2e/performance-unexpected-pause.spec.ts:103await page.evaluate(() => {
return window.musicDjToolsPerformance!.dispatch({ type: 'play', deck: 1, playing: false });
});
The CLI and HTTP examples are from the CLI's test suite, which runs the real engine routes against a model of the page, not against audio. The browser example is from an end-to-end test that drives the real page. Each header names the file and starting line at 487fa677d7.