commit fb439973d7ab1824f58d6eb65e942cb5616f6863 Author: Michael Czechowski Date: Sat Sep 27 14:28:58 2025 +0200 add comprehensive agents.md with strudel live coding guidelines diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..ba19eee --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,223 @@ +# AGENTS.md + +## Strudel Live Coding Assistant Guidelines + +### Overview +This document provides essential guidelines for AI agents assisting with Strudel live coding. Strudel is a JavaScript-based port of TidalCycles for algorithmic music composition and live coding performance. + +### Critical Knowledge Requirements + +#### 1. Core Syntax Understanding +- **NOT JavaScript**: Strudel uses its own pattern-based syntax, not standard JavaScript +- **NO variable declarations**: No `const`, `let`, `var`, `export`, `import` +- **NO function syntax**: Patterns are composed directly, not stored in functions + +#### 2. Parallel Pattern Syntax +```javascript +// ✅ CORRECT - Multiple patterns in parallel +$: sound("bd*4") +$: sound("~ sd ~ sd") +$: sound("hh*8").gain(0.3) + +// ❌ WRONG - JavaScript-style +const kick = sound("bd*4"); +const snare = sound("~ sd ~ sd"); +``` + +#### 3. Muting Patterns +```javascript +// ✅ Mute a pattern (for live performance) +_$: sound("bd*4") // underscore mutes + +// ✅ Active pattern +$: sound("bd*4") // dollar sign plays +``` + +#### 4. Notes and Scales +```javascript +// ✅ CORRECT - Using scale degrees with n() +$: n("0 2 4 6").scale("C:minor").sound("piano") + +// ❌ WRONG - Manual note names (this works but is not idiomatic) +$: note("c eb g bb").sound("piano") + +// ✅ Scale variations +$: n("0 2 4 <[6,8] [7,9]>").scale("C:minor").sound("piano") +``` + +#### 5. Common Scale Names +- `C:major`, `C:minor` +- `A2:minor` (with octave) +- `D:dorian`, `G:mixolydian` +- `A2:minor:pentatonic` +- `F:major:pentatonic` + +#### 6. Pattern Notation (Mini-notation) +```javascript +// Basic patterns +"bd ~ sd ~" // kick-rest-snare-rest +"bd*4" // four kicks per cycle +"bd*<2 4>" // alternating subdivisions +"" // alternating sounds +"[bd sd]" // both in one beat +"bd@3 sd" // bd three times longer +"bd!3 sd" // replicate bd three times +"[bd ~ sd ~]/2" // slow down by half + +// Advanced patterns +"~ 0 ~ 2 ~ 4 ~ 6" // scale degrees with rests +"0*4 2*2 4*2 6*4" // complex subdivisions +"0,2,4,6" // chord (simultaneous) +``` + +#### 7. Sound Sources +```javascript +// Drum samples +$: sound("bd sd hh oh") + +// Instrument banks +$: sound("bd sd").bank("RolandTR909") + +// Synthesizers +$: n("0 2 4 6").sound("sawtooth") // waveforms +$: n("0 2 4 6").sound("piano") // samples +$: n("0 2 4 6").sound("gm_acoustic_bass") // GM sounds +``` + +#### 8. Effects and Modulation +```javascript +// Audio effects +.gain(0.8) // volume +.lpf(800) // low-pass filter +.hpf(2000) // high-pass filter +.reverb(0.4) // reverb amount +.room(0.6) // room reverb +.delay(0.25) // delay time +.pan(-0.3) // stereo pan (-1 to 1) + +// Live modulation +.gain(sine.range(0.5, 1).slow(4)) // oscillating gain +.lpf(sine.range(200, 2000).slow(8)) // filter sweep +.pan(sine.range(-0.5, 0.5).slow(6)) // auto-pan +``` + +#### 9. Time Manipulation +```javascript +.slow(2) // half speed (2x longer cycles) +.fast(2) // double speed (half-length cycles) +.early(0.125) // timing offset +.late(0.125) // timing delay +``` + +#### 10. Probability and Randomness +```javascript +.sometimes(rev) // randomly apply reverse +.often(x => x.fast(2)) // frequently apply effect +.rarely(x => x.gain(0.5)) // rarely apply effect +.mask("1 0 1 1") // rhythmic gating +``` + +### Documentation Sources + +Before providing Strudel code, agents should: + +1. **Always check official documentation**: https://strudel.cc/ +2. **Reference workshop tutorials**: https://strudel.cc/workshop/ +3. **Verify syntax against examples** in the Strudel REPL + +### Common Mistakes to Avoid + +#### ❌ JavaScript Assumptions +```javascript +// WRONG - This is not JavaScript +const pattern = sound("bd*4"); +export default pattern; +import { stack } from "strudel"; +``` + +#### ❌ Function Declarations +```javascript +// WRONG - No function syntax +function createBeat() { + return sound("bd*4"); +} +``` + +#### ❌ Stack Usage +```javascript +// WRONG - stack() doesn't exist in REPL +stack( + sound("bd*4"), + sound("~ sd ~ sd") +) +``` + +#### ❌ Variable References +```javascript +// WRONG - No variable system +const kick = sound("bd*4"); +kick.gain(0.8); +``` + +### ✅ Correct Patterns + +#### Live Performance Setup +```javascript +// Multiple parallel patterns +$: sound("bd*4").gain(0.8) +$: sound("~ sd ~ sd").gain(0.7) +$: sound("hh*8").gain(0.3).hpf(8000) +$: n("0 ~ 2 ~ 4 ~ 6 ~").scale("C2:minor").sound("sawtooth").lpf(120) +$: n("~ 0 ~ 2 ~ 4 ~ 6").scale("C4:minor").sound("piano").room(0.6) +``` + +#### Live Coding Effects +```javascript +// Instant filter sweep +$: sound("bd*4").lpf(sine.range(100, 2000).slow(4)) + +// Rhythmic gating +$: n("0 2 4 6").scale("C:minor").sound("piano").mask("1 0 1 1") + +// Probability effects +$: sound("hh*8").sometimes(rev).often(x => x.gain(0.5)) +``` + +### Agent Response Protocol + +1. **Read documentation first** when unsure about syntax +2. **Provide working examples** that can be copy-pasted into REPL +3. **Use `$:` prefix** for all patterns +4. **Include muting options** with `_$:` for live performance +5. **Explain mini-notation** when using complex patterns +6. **Test understanding** by referring to official examples + +### Git Commit Guidelines + +- **Use lowercase commit messages**: All commit messages must be written in lowercase + +### Live Performance Considerations + +When creating beats for live performance: + +- **Each `$:` line is independently controllable** +- **Use `_$:` to mute sections during performance** +- **Include modulation for evolving sounds** +- **Provide multiple variations/sections** +- **Keep patterns readable for live modification** + +### Example Response Structure + +```javascript +// MAIN BEAT +$: sound("bd*4").gain(0.8) // kick +$: sound("~ sd ~ sd").gain(0.7) // snare +$: sound("hh*8").gain(0.3) // hats +$: n("0 ~ 2 ~ 4 ~ 6 ~").scale("C2:minor").sound("sawtooth") // bass + +// LIVE VARIATIONS (comment/uncomment as needed) +// $: sound("bd*4").lpf(sine.range(200, 2000).slow(8)) // filter sweep +// $: sound("~ sd ~ sd").mask("1 0 1 1") // gated snare +``` + +This structure allows for immediate use and live manipulation in the Strudel REPL environment.