Major changes: - Pipeline architecture with capability-based dependency resolution - Effects plugin system with performance monitoring - Display abstraction with multiple backends (terminal, null, websocket) - Camera system for viewport scrolling - Sensor framework for real-time input - Command-and-control system via ntfy - WebSocket display backend for browser clients - Comprehensive test suite and documentation Issue #48: ADR for preset scripting language included This commit consolidates 110 individual commits into a single feature integration that can be reviewed and tested before further refinement.
7.0 KiB
ADR: Preset Scripting Language for Mainline
Status: Draft
Context
We need to evaluate whether to add a scripting language for authoring presets in Mainline, replacing or augmenting the current TOML-based preset system. The goals are:
- Expressiveness: More powerful than TOML for describing dynamic, procedural, or dataflow-based presets
- Live coding: Support hot-reloading of presets during runtime (like TidalCycles or Sonic Pi)
- Testing: Include assertion language to package tests alongside presets
- Toolchain: Consider packaging and build processes
Current State
The current preset system uses TOML files (presets.toml) with a simple structure:
[presets.demo-base]
description = "Demo: Base preset for effect hot-swapping"
source = "headlines"
display = "terminal"
camera = "feed"
effects = [] # Demo script will add/remove effects dynamically
camera_speed = 0.1
viewport_width = 80
viewport_height = 24
This is declarative and static. It cannot express:
- Conditional logic based on runtime state
- Dataflow between pipeline stages
- Procedural generation of stage configurations
- Assertions or validation of preset behavior
Problems with TOML
- No way to express dependencies between effects or stages
- Cannot describe temporal/animated behavior
- No support for sensor bindings or parametric animations
- Static configuration cannot adapt to runtime conditions
- No built-in testing/assertion mechanism
Approaches
1. Visual Dataflow Language (PureData-style)
Inspired by Pure Data (Pd), Max/MSP, and TouchDesigner:
Pros:
- Intuitive for creative coding and live performance
- Strong model for real-time parameter modulation
- Matches the "patcher" paradigm already seen in pipeline architecture
- Rich ecosystem of visual programming tools
Cons:
- Complex to implement from scratch
- Requires dedicated GUI editor
- Harder to version control (binary/graph formats)
- Mermaid diagrams alone aren't sufficient for this
Tools to explore:
- libpd (Pure Data bindings for other languages)
- Node-based frameworks (node-red, various DSP tools)
- TouchDesigner-like approaches
2. Textual DSL (TidalCycles-style)
Domain-specific language focused on pattern transformation:
Pros:
- Lightweight, fast iteration
- Easy to version control (text files)
- Can express complex patterns with minimal syntax
- Proven in livecoding community
Cons:
- Learning curve for non-programmers
- Less visual than PureData approach
Example (hypothetical):
preset my-show {
source: headlines
every 8s {
effect noise: intensity = (0.5 <-> 1.0)
}
on mic.level > 0.7 {
effect glitch: intensity += 0.2
}
}
3. Embed Existing Language
Embed Lua, Python, or JavaScript:
Pros:
- Full power of general-purpose language
- Existing tooling, testing frameworks
- Easy to integrate (many embeddable interpreters)
Cons:
- Security concerns with running user code
- May be overkill for simple presets
- Testing/assertion system must be built on top
Tools:
- Lua (lightweight, fast)
- Python (rich ecosystem, but heavier)
- QuickJS (small, embeddable JS)
4. Hybrid Approach
Visual editor generates textual DSL that compiles to Python:
Pros:
- Best of both worlds
- Can start with simple DSL and add editor later
Cons:
- More complex initial implementation
Requirements Analysis
Must Have
- Express pipeline stage configurations (source, effects, camera, display)
- Support parameter bindings to sensors
- Hot-reloading during runtime
- Integration with existing Pipeline architecture
Should Have
- Basic assertion language for testing
- Ability to define custom abstractions/modules
- Version control friendly (text-based)
Could Have
- Visual node-based editor
- Real-time visualization of dataflow
- MIDI/OSC support for external controllers
User Stories (Proposed)
Spike Stories (Investigation)
Story 1: Evaluate DSL Parsing Tools
As a developer, I want to understand the available Python DSL parsing libraries (Lark, parsy, pyparsing) so that I can choose the right tool for implementing a preset DSL.
Acceptance: Document pros/cons of 3+ parsing libraries with small proof-of-concept experiments
Story 2: Research Livecoding Languages
As a developer, I want to understand how TidalCycles, Sonic Pi, and PureData handle hot-reloading and pattern generation so that I can apply similar techniques to Mainline.
Acceptance: Document key architectural patterns from 2+ livecoding systems
Story 3: Prototype Textual DSL
As a preset author, I want to write presets in a simple textual DSL that supports basic conditionals and sensor bindings.
Acceptance: Create a prototype DSL that can parse a sample preset and convert to PipelineConfig
Story 4: Investigate Assertion/Testing Approaches
As a quality engineer, I want to include assertions with presets so that preset behavior can be validated automatically.
Acceptance: Survey testing patterns in livecoding and propose assertion syntax
Implementation Stories (Future)
Story 5: Implement Core DSL Parser
As a preset author, I want to write presets in a textual DSL that supports sensors, conditionals, and parameter bindings.
Acceptance: DSL parser handles the core syntax, produces valid PipelineConfig
Story 6: Hot-Reload System
As a performer, I want to edit preset files and see changes reflected in real-time without restarting.
Acceptance: File watcher + pipeline mutation API integration works
Story 7: Assertion Language
As a preset author, I want to include assertions that validate sensor values or pipeline state.
Acceptance: Assertions can run as part of preset execution and report pass/fail
Story 8: Toolchain/Packaging
As a preset distributor, I want to package presets with dependencies for easy sharing.
Acceptance: Can create, build, and install a preset package
Decision
Recommend: Start with textual DSL approach (Option 2/4)
Rationale:
- Lowest barrier to entry (text files, version control)
- Can evolve to hybrid later if visual editor is needed
- Strong precedents in livecoding community (TidalCycles, Sonic Pi)
- Enables hot-reloading naturally
- Assertion language can be part of the DSL syntax
Not recommending Mermaid: Mermaid is excellent for documentation and visualization, but it's a diagramming tool, not a programming language. It cannot express the logic, conditionals, and sensor bindings we need.
Next Steps
- Execute Spike Stories 1-4 to reduce uncertainty
- Create minimal viable DSL syntax
- Prototype hot-reloading with existing preset system
- Evaluate whether visual editor adds sufficient value to warrant complexity
References
- Pure Data: https://puredata.info/
- TidalCycles: https://tidalcycles.org/
- Sonic Pi: https://sonic-pi.net/
- Lark parser: https://lark-parser.readthedocs.io/
- Mainline Pipeline Architecture:
engine/pipeline/ - Current Presets:
presets.toml