overdub

digitakt-llm

markzegarelli/digitakt-llm · ★ 3

A command line tool to help ideate with your Elektron Digitakt or other midi device.

README from GitHub, MIT

digitakt-llm

image

Generate drum patterns on an Elektron Digitakt in real time with Claude Opus 4.6. Describe a vibe in plain English — the pattern plays over USB MIDI and loops until you change it.

Key features

  • Ink terminal UI — Elektron-style layout: transport and tempo in the header, SEQ (8-track step grid with per-step trig metadata), MIX (per-track CC bars and step overrides), optional TRIG side panel for step edits, and CMD (slash commands and natural-language prompts).
  • Live pattern engine — WebSocket-driven grid, playhead, mutes, swing, per-step probability, gates, conditional trigs, and chromatic pitch per track.
  • Claude integration — Beat mode for generation from text; chat mode and /ask for questions; /gen and Ctrl+G to turn answers into patterns; optional activity log.
  • Digitakt-oriented MIDI — Eight tracks map to channels 1–8; CCs for tune, filter, envelopes, sends, and more; save/load patterns, fills, chains, and pattern history.
  • FastAPI backend — REST + /ws event stream so the same server can power the TUI or other clients.

Roadmap

Release gates and v1.0 milestone order (audited against the current tree): docs/ROADMAP.md.

Hardware Requirements

  • Elektron Digitakt (any firmware) connected via USB
  • USB MIDI cable or USB-B to USB-A cable (the Digitakt appears as a class-compliant MIDI device — no driver needed on macOS or Linux)

Requirements

  • Python 3.11+
  • uv (recommended; manages .venv and locked deps)
  • Bun ≥1.1
  • macOS or Linux (Windows untested)
  • An Anthropic API key

Setup

# Python backend + dev tools (uses uv.lock; creates .venv automatically)
uv sync --extra dev

# Bun/Ink frontend
cd tui && bun install && cd ..

# Set your API key
export ANTHROPIC_API_KEY=sk-ant-...
# or add it to a .env file: ANTHROPIC_API_KEY=sk-ant-...

# Launch (adds .venv to PATH for this command) — **legacy Python path**
uv run digitakt
# Build + test
cargo test --workspace -- --test-threads=1

# Headless API (Ink TUI / web dev)
cargo run -p digitakt-cli -- serve
# or: DIGITAKT_URL=http://127.0.0.1:8000 uv run digitakt   # Ink against Rust server

# Web UI dev (Rust API on :8000)
cargo run -p digitakt-cli -- serve &
cd web && bun run dev

# Tauri macOS app (from src-tauri/)
cargo tauri dev

See docs/macos-release.md for bundle builds, optional git pre-commit hook (bash scripts/install-git-hooks.sh), Core MIDI entitlements, and notarization.

Cloud/agent startup bootstrap

For cloud sessions (or any fresh machine), run:

bash scripts/startup-tooling.sh

This script is idempotent and prepares the expected tooling automatically:

  • installs uv if missing
  • syncs Python deps (uv sync --extra dev)
  • installs bun if missing
  • installs Bun deps in tui/ (bun install --cwd tui)
  • prints ready-to-run verification commands for tests and the app

If your agent platform supports startup hooks, you can register:

bash scripts/startup-tooling.sh

After uv sync, you can also run digitakt directly if the venv is activated (source .venv/bin/activate).

Global isolated install (optional): from a checkout, uv tool install . installs the digitakt console script into uv’s tool environment (no manual venv).

Without uv

If you prefer classic venv + pip:

python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
cd tui && bun install && cd ..
digitakt

Usage

digitakt launches the Bun/Ink TUI (shown above) with Tab cycling SEQ → MIX → CMD (plus LOG when the activity log is open):

  • SEQ — Step grid for all eight tracks, live from the server, with keyboard mutes/queued mutes and step edit mode (Enter) to toggle trigs with Space.
  • MIX — Per-track parameters (velocity + CCs), bar readouts, and step mode for per-step CC edits; also shows live trig summary for the selected track at the playhead.
  • TRIG (contextual side panel) — Available from SEQ step edit mode (Tab). Edit per-step probability, velocity, gate, condition, and track note/pitch.
  • CMD — Slash commands, /help (scrollable), and bare-text prompts in beat or chat mode.

Commands

Type /help in the prompt panel for the full reference. All commands are prefixed with / or entered as bare text:

CommandDescription
play / stopStart or stop playback
bpm <n>Set tempo (20–400)
swing <n>Set swing amount (0–100)
length [8|16|32]Set pattern step count
prob <track> <step> <value>Step probability 0–100 (1-indexed, within current pattern length)
vel <track> <step> <value>Step velocity 0–127 (1-indexed, within current pattern length)
gate <track> <step> <0-100>Note gate length (% of step duration)
pitch <track> <0-127>MIDI note number for track (chromatic mode)
cond <track> <step> <1:2|not:2|fill|clear>Conditional trig on a step
random [track|all] [vel|prob] [lo-hi]Randomize velocity or probability
randbeatGenerate a random techno beat
cc <track> <param> <value>Send CC to track globally (0–127)
cc-step <track> <param> <step> <v>Per-step CC override (-1 to clear; step must be within current pattern length)
save <name> [#tag1 #tag2]Save pattern with optional tags
load <name>Queue a saved pattern for the next loop
patterns [#tag]List saved patterns, optionally filtered by tag
fill <name>Queue pattern as a one-shot fill (plays once, reverts)
newReset to empty pattern
undoRevert to previous pattern
historyShow pattern history
logToggle activity log
clearClear activity log
mode [chat|beat]Switch input mode
ask <question>Ask Claude a question (any mode)
helpShow command reference
quit / qExit
(bare text in BEAT mode)Generate a new pattern from your description
(bare text in CHAT mode)Ask Claude a question

First prompt generates a fresh pattern. Subsequent prompts are treated as variations (prior pattern and prompt are passed as context).

CC control

Each track maps to its own MIDI channel (kick → ch 1, snare → ch 2, … perc4 → ch 8), matching the Digitakt's physical track layout.

Tracks: kick snare tom clap bell hihat openhat cymbal

Params:

ParamCC#DefaultDescription
tune1664Sample pitch
filter74127Filter cutoff
resonance750Filter resonance
attack780Amp attack
hold790Amp hold
decay8064Amp decay
volume7100Track volume
reverb830Reverb send
delay820Delay send
> cc kick filter 90
CC set: kick filter = 90

> cc show
        tune  filter  res  atk  dec  vol  rev  dly
kick      64      90   64   64   64  100    0    0
snare     64      64   64   64   64  100    0    0
...

Panels

PanelDescription
SEQStep grid (8/16/32 steps) with mute indicators, prob/gate/condition visualization, and step edit mode
MIXPer-track parameters (velocity, filter, decay, reverb, etc.) plus playhead trig summary
TRIGContextual side panel opened from SEQ step edit mode for per-step trig editing
LOGActivity stream; when TRIG is open, LOG and TRIG share the right-side column
CMDCommands, generation, and /help

Use Tab to cycle focus between panels (see Usage).

Keyboard Shortcuts

KeyAction
TabCycle panels (SEQ → MIX → CMD, and LOG when open)
Enter (SEQ)Enter/exit SEQ step edit mode
SpacePlay/stop (normal), or toggle selected SEQ step on/off in step edit mode
← / → (SEQ step edit)Move selected step
↑ / ↓ (SEQ)Navigate tracks
Tab (while in SEQ step edit)Toggle TRIG side panel
↑ / ↓ (TRIG)Move between trig fields
← / → (TRIG)Adjust selected field ±1
Shift+← / Shift+→ (TRIG)Adjust selected numeric field ±10
[ / ] (TRIG)Move selected SEQ step while keeping TRIG open
0-9 + Enter (TRIG)Type and commit numeric trig value
Esc (TRIG)Close TRIG side panel
+ / -BPM +1 / -1
mMute selected track (SEQ panel)
← / →Adjust velocity or CC ±1 (MIX panel)
Shift+← / Shift+→Adjust velocity or CC ±10 (MIX panel)
[ / ]Previous / next track (MIX panel)
EnterSubmit prompt or command (CMD panel)
Ctrl+CQuit

Environment Variables

VariableDefaultDescription
ANTHROPIC_API_KEY(required)Anthropic API key
PORT8000FastAPI server port
DIGITAKT_HOST127.0.0.1FastAPI bind host (0.0.0.0 only when explicitly needed)
DIGITAKT_ENABLE_TRACES0Enable GET /traces observability endpoint
DIGITAKT_ADMIN_TOKENunsetOptional token required via X-Digitakt-Token for protected admin endpoints (including /traces when set)

API Reference

The FastAPI server starts automatically on http://localhost:8000 (bound to 127.0.0.1 by default).

MethodPathDescription
GET/stateFull application state as JSON
POST/generate{"prompt": "..."} → 202 Accepted
POST/askAsk Claude a question
POST/bpm{"bpm": 140.0}
POST/swing{"amount": 25}
POST/length{"steps": 8|16|32}
POST/playStart playback
POST/stopStop playback
POST/newReset to empty pattern
POST/undoRevert to previous pattern
GET/patterns{"patterns":[{"name":"...","tags":[...]}]}
POST/patterns/{name}Save current pattern
GET/patterns/{name}Load pattern (queued if playing, immediate if stopped)
POST/fill/{name}Queue one-shot fill from saved pattern
POST/probSet step probability
POST/velSet step velocity
POST/gateSet step gate
POST/pitchSet track pitch
POST/condSet conditional trig
POST/randomRandomize velocity or probability
POST/randbeatGenerate a random techno beat
POST/cc{"track": "kick", "param": "filter", "value": 90}
GET/cc-paramsList supported CC params and defaults
POST/cc-stepSet per-step CC override
GET/ccCurrent CC state for all tracks
POST/muteImmediate mute toggle/update
POST/mute-queuedQueue mute for next bar boundary
POST/velocitySet global per-track velocity scale
GET/tracesRecent LLM traces (disabled by default, optional token-protected)
WS/wsEvent stream (see below)

Contributing

See CONTRIBUTING.md for dev setup, test instructions, and PR conventions.

Attaching a Frontend

The WebSocket at ws://localhost:8000/ws pushes every internal event as JSON:

{"event": "pattern_changed", "data": {"pattern": {...}, "prompt": "..."}}
{"event": "generation_started", "data": {"prompt": "..."}}
{"event": "generation_complete", "data": {"pattern": {...}, "prompt": "..."}}
{"event": "generation_failed", "data": {"prompt": "...", "error": "..."}}
{"event": "bpm_changed", "data": {"bpm": 140.0}}
{"event": "playback_started", "data": {}}
{"event": "playback_stopped", "data": {}}
{"event": "midi_disconnected", "data": {"port": "..."}}
{"event": "cc_changed", "data": {"track": "kick", "param": "filter", "value": 90}}

GET /state returns the full AppState shape. Control playback with the REST endpoints above.

License

MIT — see LICENSE.