Skip to content

rcarmo/apfelstrudel

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

18 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ₯§ Apfelstrudel

Apfelstrudel icon

Live coding music with AI assistance β€” powered by Strudel.cc and Bun

Apfelstrudel combines the expressive power of Strudel's live coding environment with an AI agent that can help you create, modify, and understand music patterns in real time.

Apfelstrudel Interface

Features

  • 🎡 Strudel Integration β€” Full Strudel.cc live coding environment
  • πŸ€– AI Assistant β€” Chat with an agent that understands music and patterns
  • πŸ”„ Real-time Control β€” Agent can edit patterns, control playback, adjust tempo
  • 🎨 Dark Theme β€” Easy on the eyes for those late-night sessions
  • ⌨️ Keyboard Shortcuts β€” Ctrl+Enter to play, Ctrl+. to stop

Quick Start

Prerequisites

  • Bun v1.0 or later
  • OpenAI API key (or Azure OpenAI credentials)

Installation

# Clone the repository
git clone https://github.com/rcarmo/apfelstrudel.git
cd apfelstrudel

# Install backend dependencies
make install

# Vendor frontend dependencies (Preact, HTM, Strudel)
make vendor

# Copy environment template
cp .env.example .env

# Edit .env with your API credentials

Configuration

Create a .env file with your LLM credentials:

# OpenAI
OPENAI_API_KEY=sk-...

# Or Azure OpenAI
AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com
AZURE_OPENAI_KEY=...
AZURE_OPENAI_DEPLOYMENT=gpt-4o-mini

# Optional settings
APFELSTRUDEL_PROVIDER=openai  # or "azure"
APFELSTRUDEL_MODEL=gpt-4o-mini
APFELSTRUDEL_MAX_STEPS=16
PORT=3000

Running

# Development mode with hot reload
make dev

# Production mode
make start

Open http://localhost:3000 in your browser.

Usage

Pattern Editor (Left Panel)

Write Strudel patterns using mini-notation:

// Basic drum pattern
s("bd sd:2 bd bd sd").bank("RolandTR808")

// Melodic pattern
note("c3 e3 g3 b3".fast(2)).sound("sawtooth")
  .lpf(800).lpq(5)

// Stacked patterns
stack(
  s("bd*4"),
  s("~ hh*2"),
  note("c2 g2".slow(2)).sound("sawtooth")
)

AI Assistant (Right Panel)

Ask the assistant to help you:

  • "Make a chill lo-fi beat"
  • "Add some hi-hats to the pattern"
  • "Make it faster"
  • "Explain what this pattern does"
  • "What samples are available?"

Keyboard Shortcuts

Shortcut Action
Ctrl+Enter Play pattern
Ctrl+. Stop
Enter Send chat message
Shift+Enter New line in chat

Development

# Run all checks (lint + typecheck + test)
make check

# Individual commands
make lint      # Run biome linter
make format    # Format code
make typecheck # TypeScript type checking
make test      # Run tests

# Build for production
make build

# Clean build artifacts
make clean

Project Structure

apfelstrudel/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ server/         # Bun HTTP + WebSocket server
β”‚   β”‚   β”œβ”€β”€ index.ts    # Main server entry
β”‚   β”‚   └── websocket.ts # WebSocket handlers
β”‚   β”œβ”€β”€ agent/          # LLM agent implementation
β”‚   β”‚   β”œβ”€β”€ runner.ts   # Agentic loop
β”‚   β”‚   β”œβ”€β”€ llm.ts      # LLM client (OpenAI/Azure)
β”‚   β”‚   └── system-prompt.ts
β”‚   β”œβ”€β”€ tools/          # Agent tools
β”‚   β”‚   β”œβ”€β”€ pattern.ts  # get/set/modify pattern
β”‚   β”‚   β”œβ”€β”€ transport.ts # play/stop/evaluate
β”‚   β”‚   β”œβ”€β”€ tempo.ts    # tempo control
β”‚   β”‚   β”œβ”€β”€ reference.ts # strudel help & samples
β”‚   β”‚   └── todo.ts     # task management
β”‚   └── shared/         # Shared types
β”‚       └── types.ts
β”œβ”€β”€ public/             # Static frontend
β”‚   β”œβ”€β”€ index.html
β”‚   β”œβ”€β”€ styles.css
β”‚   └── app.js
β”œβ”€β”€ SPEC.md            # Detailed specification
β”œβ”€β”€ Makefile
└── package.json

Agent Tools

The AI assistant has access to these tools:

Tool Description
get_pattern Read current pattern code
set_pattern Replace pattern code
modify_pattern Insert code before/after existing pattern
play_music Start playback
stop_music Stop playback
strudel_evaluate Evaluate code without changing editor
set_tempo Adjust BPM
get_strudel_help Query Strudel documentation
list_samples List available samples
manage_todo Track tasks and ideas

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      Browser                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚   Strudel Editor    β”‚  β”‚      Chat Sidebar          β”‚ β”‚
β”‚  β”‚  (CodeMirror)       β”‚  β”‚  (WebSocket messages)      β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚             β”‚                        β”‚                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β”‚ WebSocket              β”‚
              β–Ό                        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Bun Server                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚   Static Files      β”‚  β”‚    WebSocket Handler       β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                      β”‚                    β”‚
β”‚                                      β–Ό                    β”‚
β”‚                           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚                           β”‚     Agent Runner           β”‚ β”‚
β”‚                           β”‚  (Agentic Loop + Tools)    β”‚ β”‚
β”‚                           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                      β”‚                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                       β”‚
                                       β–Ό
                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                              β”‚  OpenAI / Azure β”‚
                              β”‚     LLM API     β”‚
                              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Vendored Samples

Audio samples from the Dirt-Samples library (218 instruments, ~2000 files) are vendored in public/vendor/strudel/samples/dirt/ for offline convenience. These samples were created by the TidalCycles community and are redistributed here temporarily to enable fully offline operation.

Fonts (Inter by Rasmus Andersson, JetBrains Mono by JetBrains) are also vendored locally in public/vendor/fonts/.

If you are packaging or forking this project, please review the upstream licenses for these assets.

License

AGPL-3.0 β€” Required by Strudel.cc dependency.

See LICENSE for details.

Credits

  • Strudel.cc by Felix Roos β€” The amazing live coding environment
  • Dirt-Samples by the TidalCycles community β€” Audio samples
  • Inter by Rasmus Andersson β€” UI typeface
  • JetBrains Mono by JetBrains β€” Editor typeface
  • Bun β€” Fast JavaScript runtime
  • Inspired by rcarmo/steward β€” Tool harness pattern

Made with πŸ₯§ and 🎡

About

Live coding music environment with AI agent chat

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors