8.3 KiB
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
// ✅ 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
// ✅ Mute a pattern (for live performance)
_$: sound("bd*4") // underscore mutes
// ✅ Active pattern
$: sound("bd*4") // dollar sign plays
4. Notes and Scales
// ✅ 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:minorA2:minor(with octave)D:dorian,G:mixolydianA2:minor:pentatonicF:major:pentatonic
6. Pattern Notation (Mini-notation)
// Basic patterns
"bd ~ sd ~" // kick-rest-snare-rest
"bd*4" // four kicks per cycle
"bd*<2 4>" // alternating subdivisions
"<bd sd>" // 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
// 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
// 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
.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
.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:
- Always check official documentation: https://strudel.cc/
- Reference workshop tutorials: https://strudel.cc/workshop/
- Verify syntax against examples in the Strudel REPL
Common Mistakes to Avoid
❌ JavaScript Assumptions
// WRONG - This is not JavaScript
const pattern = sound("bd*4");
export default pattern;
import { stack } from "strudel";
❌ Function Declarations
// WRONG - No function syntax
function createBeat() {
return sound("bd*4");
}
❌ Stack Usage
// WRONG - stack() doesn't exist in REPL
stack(
sound("bd*4"),
sound("~ sd ~ sd")
)
❌ Variable References
// WRONG - No variable system
const kick = sound("bd*4");
kick.gain(0.8);
✅ Correct Patterns
Live Performance Setup
// 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
// 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
- Read documentation first when unsure about syntax
- Provide working examples that can be copy-pasted into REPL
- Use
$:prefix for all patterns - Include muting options with
_$:for live performance - Explain mini-notation when using complex patterns
- Test understanding by referring to official examples
Git Commit Guidelines
- Use lowercase commit messages: All commit messages must be written in lowercase
Development Environment Guidelines
- Never use global npm installs: Avoid
npm i -gornpm install -gcommands - Use NixOS shells/dev environments: Always prefer Nix-based development environments for reproducible builds
- Current NixOS version: 25.05
Git Submodules
The Strudel codebase is managed as a git submodule in the 'src' directory. To work with the codebase:
- Initialize submodules:
make submodules-init - Update submodules:
make submodules-update
This ensures the correct version of the Strudel repository is checked out and kept in sync.
Nix Development Shell
Use the following flake.nix for Strudel development:
{
description = "Strudel development environment";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
in
{
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
nodejs_20
pnpm
git
];
shellHook = ''
echo "Strudel development environment loaded"
echo "Node.js: $(node --version)"
echo "pnpm: $(pnpm --version)"
'';
};
});
}
Usage
Option 1: Direct Nix commands
-
Enter development shell:
nix develop -
Install dependencies:
pnpm install -
Start development server:
pnpm dev
Option 2: Using Makefile (recommended) The Makefile provides convenient shortcuts for common development tasks. First, ensure submodules are initialized:
# Initialize and update submodules
make update
# Install dependencies
make install
# Start development server
make dev
# Run tests
make test
# Run linter
make lint
# Format code
make format
# Run all checks
make check
# Enter Nix shell directly
make shell
# Show help
make help
All Makefile commands automatically run within the Nix development environment.
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
// 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.