musalce-server 0.8.0 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2230cb912aab835e98533a65b0a8b0ae44c5b815bce0555ecfe1433807048502
4
- data.tar.gz: 4b3323bdc75f6a1e54f9ec75a42ccb649aaa82ed20fb150bf84258c098e9b908
3
+ metadata.gz: 10e3d4f033d3eacba2acafbb6e99abc3306296254ea044f9b23fc1ed266444a1
4
+ data.tar.gz: f0d2d8eb2af59d4c257afb52f0e51ce34a896d087cff4caaf91d45c264e30b42
5
5
  SHA512:
6
- metadata.gz: cfbc543f1927cf246604d5d0c25390fbba0f932a81c43232e5ae31e6020e06dc5995b8bd5eec44f251f76e40a22f8eccc13c6fadc1c1d5bcbeed6373d4ea80de
7
- data.tar.gz: 0bacccdb81eaea73d307b3667871ed4a092e791ba5822c10870ac5bf56ecc3ec3e815946634c5e9035f2ff658745fb1f60f21cd652c1df5b14d2928e35b37c08
6
+ metadata.gz: a8e4291be4780a9b13f0bc42076806a09c2107759696e51c7dd1121226572edc3d8fec28b28e3feda9ab50b2f3db16f15cd7b5cdb1be1b48db303e72df49879a
7
+ data.tar.gz: 5ebb527af34b1776cd7574eaa82b4a2a565a4ed8859e104a955336d598a272fa4d3c5ba3f79d10623054a9881b41129f1b80f211d0a9a0b166e06df7705e19bd
@@ -8,10 +8,10 @@ jobs:
8
8
  notify:
9
9
  runs-on: ubuntu-latest
10
10
  steps:
11
- - name: Trigger nota-plugin-for-claude rebuild
11
+ - name: Trigger nota-plugin rebuild
12
12
  uses: peter-evans/repository-dispatch@v3
13
13
  with:
14
14
  token: ${{ secrets.PLUGIN_REBUILD_PAT }}
15
- repository: javier-sy/nota-plugin-for-claude
15
+ repository: javier-sy/nota-plugin
16
16
  event-type: source-updated
17
17
  client-payload: '{"repo": "${{ github.repository }}", "sha": "${{ github.sha }}"}'
data/README.md CHANGED
@@ -1,20 +1,20 @@
1
- # MusaLCE Server
1
+ # MusaLCE Server Suite
2
2
 
3
3
  [![Ruby Version](https://img.shields.io/badge/ruby-2.7+-red.svg)](https://www.ruby-lang.org/)
4
4
  [![License](https://img.shields.io/badge/license-GPL--3.0--or--later-blue.svg)](https://www.gnu.org/licenses/gpl-3.0.html)
5
5
 
6
- **Musa-DSL Live Coding Environment Server for Ableton Live 11+ and Bitwig Studio 5+**
6
+ **Musa-DSL Live Coding Environment Server Suite for Ableton Live 11+ and Bitwig Studio 5+**
7
7
 
8
8
  This server enables live coding music composition using [Musa-DSL](https://github.com/javier-sy/musa-dsl) with your favorite DAW and code editor.
9
9
 
10
10
  ## Overview
11
11
 
12
- The MusaLCE system allows you to write Ruby code in your editor (Visual Studio Code recommended) and have it executed in real-time, sending MIDI to tracks in your DAW. The typical workflow is:
12
+ The MusaLCE Server Suite system allows you to write Ruby code in your editor (Visual Studio Code) and have it executed in real-time, sending MIDI to tracks in your DAW. The typical workflow is:
13
13
 
14
- 1. Start the MusaLCE Server with your DAW choice
15
- 2. Open your code editor with the MusaLCE extension
14
+ 1. Start the MusaLCE Server Suite with/inside your DAW choice (Bitwig Studio or Ableton Live)
15
+ 2. Open your VS Code editor with the MusaLCE extension (MusaLCEforVSCode)
16
16
  3. Write and execute Musa-DSL code interactively
17
- 4. The code controls MIDI instruments in your DAW
17
+ 4. The code controls MIDI instruments and transport in your DAW
18
18
 
19
19
  ## Requirements
20
20
 
@@ -25,7 +25,7 @@ The MusaLCE system allows you to write Ruby code in your editor (Visual Studio C
25
25
  - **Ableton Live 11+** with [MusaLCE for Live](https://github.com/javier-sy/MusaLCEforLive) MIDI Remote Script
26
26
  - A code editor with MusaLCE client extension:
27
27
  - **Visual Studio Code** (recommended) with [MusaLCE Client for VSCode](https://github.com/javier-sy/MusaLCEClientForVSCode)
28
- - Atom with [MusaLCE Client for Atom](https://github.com/javier-sy/MusaLCEClientForAtom) (Atom is discontinued)
28
+ - Atom with [MusaLCE Client for Atom](https://github.com/javier-sy/MusaLCEClientForAtom) (not recommended because Atom is discontinued)
29
29
 
30
30
  ## Installation
31
31
 
@@ -43,12 +43,12 @@ gem install musalce-server
43
43
 
44
44
  ## Quick Start
45
45
 
46
- 1. **Install the DAW controller extension** for your DAW (Bitwig or Live)
46
+ 1. **Install the DAW controller extension** for your DAW (for Bitwig: [MusaLCE for Bitwig](https://github.com/javier-sy/MusaLCEforBitwig), for Ableton Live: [MusaLCE for Live](https://github.com/javier-sy/MusaLCEforLive))
47
47
  2. **Install the VSCode extension** [MusaLCE Client for VSCode](https://github.com/javier-sy/MusaLCEClientForVSCode)
48
- 3. **Start your DAW** and ensure the MusaLCE controller is loaded
48
+ 3. **Start your DAW** and ensure the MusaLCE controller is loaded and configured
49
49
  4. **Start the server** (see below)
50
50
  5. **Open VSCode** and create a `.rb` file
51
- 6. **Execute code** using the MusaLCE extension commands
51
+ 6. **Execute code** using the MusaLCE extension commands (Ctrl+Alt+Return, Ctrl+Alt+M)
52
52
 
53
53
  ## Starting the Server
54
54
 
@@ -73,7 +73,7 @@ The server runs in the foreground and logs activity to the console. Use `Ctrl+C`
73
73
 
74
74
  ## Running Environment
75
75
 
76
- A complete MusaLCE live coding session requires **three components running simultaneously**:
76
+ A complete MusaLCE Server Suite live coding session requires **three components running simultaneously**:
77
77
 
78
78
  1. **Code Editor** (Visual Studio Code with MusaLCE extension)
79
79
  - Where you write and execute Ruby/Musa-DSL code
@@ -133,10 +133,10 @@ The following commands are available in the REPL context (executed from your edi
133
133
  ```ruby
134
134
  daw # Access the DAW controller object
135
135
  daw.sequencer # Access the Musa-DSL sequencer
136
- daw.clock # Access the MIDI clock
137
- daw.transport # Access the transport (callbacks survive Stop/Play)
138
- daw.tracks # Access all tracks
139
- daw.surface # Access the control surface (Stream Deck, etc.)
136
+ daw.clock # Access the Musa-DSL MIDI clock
137
+ daw.transport # Access the Musa-DSL transport
138
+ daw.tracks # Access all tracks on the daw by name
139
+ daw.surface # Access the control surface (currently elgato Stream Deck)
140
140
  ```
141
141
 
142
142
  #### Persistent actions across DAW Stop/Play
@@ -181,7 +181,7 @@ bass.out.all_notes_off
181
181
 
182
182
  ### Transport Controls
183
183
 
184
- Transport controls send commands to the DAW. **Only available for Bitwig Studio** (Live's MIDI Remote Script API doesn't support transport control).
184
+ Transport controls send commands to the DAW. **Only available for Bitwig Studio** (Live's controller doesn't support transport control by now).
185
185
 
186
186
  ```ruby
187
187
  daw.play # Start playback
@@ -260,18 +260,18 @@ daw.panic! # Send All Notes Off to all tracks
260
260
  shutdown # Stop the server
261
261
  ```
262
262
 
263
- ### Module Import
263
+ ### File Require
264
264
 
265
265
  ```ruby
266
- # Import additional modules into the REPL context
267
- import(MyHelperModule)
266
+ # Require files relative to your editor's current file
267
+ require_relative 'my_patterns'
268
268
  ```
269
269
 
270
- ### File Require
270
+ ### Module Import
271
271
 
272
272
  ```ruby
273
- # Require files relative to your editor's current file
274
- require_relative 'my_patterns'
273
+ # Import additional modules into the REPL context
274
+ import(MyHelperModule)
275
275
  ```
276
276
 
277
277
  ## DAW-Specific Notes
@@ -283,15 +283,15 @@ Requires [MusaLCE for Bitwig](https://github.com/javier-sy/MusaLCEforBitwig) con
283
283
  - Full transport control support (play, stop, continue, goto, record)
284
284
  - Track names must be unique
285
285
  - MIDI clock sync from any controller marked as clock source
286
- - Controllers and channels configured in the Bitwig extension
286
+ - Controllers and channels should be configured in the Bitwig extension
287
287
 
288
288
  ### Ableton Live
289
289
 
290
290
  Requires [MusaLCE for Live](https://github.com/javier-sy/MusaLCEforLive) MIDI Remote Script.
291
291
 
292
- - **No transport control** (Live's MIDI Remote Script API limitation)
292
+ - **No transport control** by now
293
293
  - Multiple tracks can have the same name
294
- - Use `daw.midi_sync('Device Name')` to set MIDI clock source
294
+ - Use `daw.midi_sync('MIDI Device Name')` to set MIDI clock source
295
295
  - Track routing configured in Live's preferences
296
296
 
297
297
  ```ruby
@@ -307,20 +307,9 @@ daw.midi_sync('IAC Driver Bus 1')
307
307
  | [MusaLCE Server](https://github.com/javier-sy/musalce-server) | Live coding server (this gem) |
308
308
  | [MusaLCE for Bitwig](https://github.com/javier-sy/MusaLCEforBitwig) | Bitwig Studio controller extension |
309
309
  | [MusaLCE for Live](https://github.com/javier-sy/MusaLCEforLive) | Ableton Live MIDI Remote Script |
310
- | [MusaLCE Client for VSCode](https://github.com/javier-sy/MusaLCEClientForVSCode) | VSCode extension (recommended) |
310
+ | [MusaLCE Client for VSCode](https://github.com/javier-sy/MusaLCEClientForVSCode) | VSCode extension |
311
311
  | [MusaLCE Client for Atom](https://github.com/javier-sy/MusaLCEClientForAtom) | Atom plugin (discontinued) |
312
312
 
313
- ## Documentation
314
-
315
- API documentation is available via YARD:
316
-
317
- ```bash
318
- bundle exec yard doc
319
- bundle exec yard server
320
- ```
321
-
322
- Then open http://localhost:8808 in your browser.
323
-
324
313
  ## Author
325
314
 
326
315
  * [Javier Sánchez Yeste](https://github.com/javier-sy)
data/docs/architecture.md CHANGED
@@ -1,8 +1,8 @@
1
- # MusaLCE Suite Architecture
1
+ # MusaLCE Server Suite Architecture
2
2
 
3
- This document is the canonical reference for the **suite workflow** of MusaLCE — running [musalce-server](https://github.com/javier-sy/musalce-server) together with the per-DAW extension to drive Bitwig Studio or Ableton Live from a code editor in real time, optionally with Stream Deck integration through [Pulso](https://github.com/javier-sy/pulso).
3
+ This document is the canonical reference for the **musalce-server suite** — running [musalce-server](https://github.com/javier-sy/musalce-server) together with the per-DAW extension to drive Bitwig Studio ([MusaLCEforBitwig](https://github.com/javier-sy/MusaLCEforBitwig)) or Ableton Live ([MusaLCEforLive](https://github.com/javier-sy/MusaLCEforLive)) from a code editor (VSCode + [MusaLCEClientForVSCode](https://github.com/javier-sy/MusaLCEClientForVSCode)) in real time, optionally with **elgato Stream Deck** integration via **Pulso** — [yeste.studio](https://yeste.studio)'s upcoming Stream Deck workflow system for DAWs.
4
4
 
5
- It is a companion to (not a replacement for) the lower-level [musa-dsl REPL subsystem doc](https://github.com/javier-sy/musa-dsl/blob/master/docs/subsystems/repl.md), which covers the **standalone REPL** workflow (case 1). The suite documented here is **internally a specialization** of that case — `musalce-server` opens `Musa::REPL::REPL.new(binding)` after pre-building the sequencer, clock, transport, DAW handler and surface, so you don't have to.
5
+ It is a companion to (not a replacement for) the lower-level [musa-dsl REPL component](https://github.com/javier-sy/musa-dsl/blob/master/docs/subsystems/repl.md), which covers the **standalone REPL** workflow. The **musalce-server suite** documented here is **a specialization** of that case — `musalce-server` opens `Musa::REPL::REPL.new(binding)` after pre-building the sequencer, clock, transport, DAW handler and surface, so you don't have to. It also adds the connection to the DAW (Bitwig or Ableton Live) through **MusaLCEforBitwig**/**MusaLCEforLive** and exposes a `daw.*` object to access and to control the DAW from your editor.
6
6
 
7
7
  ## When to use this (vs the standalone REPL)
8
8
 
@@ -10,10 +10,10 @@ It is a companion to (not a replacement for) the lower-level [musa-dsl REPL subs
10
10
  |---|---|
11
11
  | Target is Bitwig Studio or Ableton Live | Target is SuperCollider, Max/MSP, OSC apps, custom hardware |
12
12
  | You want `daw.*`, `surface[:event]` and DAW transport out of the box | You want full control over the wiring |
13
- | You want Stream Deck integration via Pulso (Bitwig only today) | You're prototyping a personal live-coding DSL |
13
+ | You want a Stream Deck wired into your score via Pulso's MusaLCE Surface integration (Bitwig only today) | You're prototyping a personal live-coding DSL |
14
14
  | Worked example: `_demo-13b-live-coding-suite` (planned) | Worked example: [`_demo-13-live-coding`](https://github.com/javier-sy/musadsl-demo) |
15
15
 
16
- Both workflows use the same [MusaLCEClientForVSCode](https://github.com/javier-sy/MusaLCEClientForVSCode) extension; the extension does not know or care which server is on the other end of TCP/1327.
16
+ Both workflows use VS Code as editor and the same [MusaLCEClientForVSCode](https://github.com/javier-sy/MusaLCEClientForVSCode) editor extension. The editor extension connects to the server via TCP socket on port 1327.
17
17
 
18
18
  ## The big picture
19
19
 
@@ -21,25 +21,26 @@ Both workflows use the same [MusaLCEClientForVSCode](https://github.com/javier-s
21
21
  ┌────────────────────────────┐
22
22
  │ Stream Deck plugin │
23
23
  │ (Pulso Workflow .sdPlugin) │
24
- └─────────────┬──────────────┘
24
+ └────────────────────────────┘
25
+ ^
25
26
  │ OSC over UDP (Pulso wire)
26
27
 
27
- ┌────────────────────┐ TCP 1327 ┌──────────────────┐ ┌─────────────────────────┐ ┌──────────────────┐
28
- │ VSCode + │ ◀──────────▶ │ musalce-server │ ─────▶ │ MusaLCEforBitwig │ ◀────▶ │ Bitwig Studio │
29
- │ MusaLCEClient │ (REPL) │ (Ruby gem) │ │ + Pulso Bridge relay │ └──────────────────┘
28
+ ┌────────────────────┐ TCP 1327 ┌──────────────────┐ ┌─────────────────────────┐ ┌──────────────────┐
29
+ │ VSCode + │ ◀──────────▶ │ musalce-server │ ◀────▶ │ MusaLCEforBitwig │ ◀────▶ │ Bitwig Studio │
30
+ │ MusaLCEClient │ (REPL) │ (Ruby gem) │ │ + Pulso Bridge relay │ └──────────────────┘
30
31
  │ ForVSCode │ │ │ UDP └─────────────────────────┘
31
32
  └────────────────────┘ │ • REPL │ OSC OR
32
33
  │ • Sequencer │
33
- │ • DAW handler │ ─────▶ ┌─────────────────────────┐ ┌──────────────────┐
34
+ │ • DAW handler │ ◀────▶ ┌─────────────────────────┐ ┌──────────────────┐
34
35
  │ • Surface │ │ MusaLCEforLive │ ◀────▶ │ Ableton Live │
35
- │ • MIDI out │ │ (Python) │ └──────────────────┘
36
+ │ • MIDI out │ │ (Python) │ └──────────────────┘
36
37
  └──────────────────┘ └─────────────────────────┘
37
38
  ```
38
39
 
39
40
  Two parallel OSC contracts cross the server ↔ extension boundary:
40
41
 
41
42
  - **Handler protocol** — `/musalce4bitwig/*` or `/musalce4live/*` plus a common `/hello`, `/version`, `/reload`. Carries DAW control (transport, track sync, channels). Documented [below](#osc-handler-protocol).
42
- - **Surface protocol** — `/musalce/surface/*`. Carries Stream Deck control state (inventory, triggers, state propagation). [Single source of truth in pulso/docs/osc-protocol.md](https://github.com/javier-sy/pulso/blob/main/docs/osc-protocol.md). Bitwig only today; Live side not implemented.
43
+ - **Surface protocol** — `/musalce/surface/*`. Carries elgato Stream Deck control state (inventory, triggers, state propagation). The canonical Pulso-side spec will be linked here once Pulso publishes.
43
44
 
44
45
  ## Component responsibilities
45
46
 
@@ -48,13 +49,13 @@ Two parallel OSC contracts cross the server ↔ extension boundary:
48
49
  | **musa-dsl** | [musa-dsl](https://github.com/javier-sy/musa-dsl) | The composition framework: series, sequencer, neumas, transport, REPL primitive. | Ruby |
49
50
  | **musalce-server** | [musalce-server](https://github.com/javier-sy/musalce-server) | Packages the REPL + sequencer + per-DAW handler + surface into a single command (`musalce-server bitwig\|live`). | Ruby |
50
51
  | **MusaLCEforBitwig** | [MusaLCEforBitwig](https://github.com/javier-sy/MusaLCEforBitwig) | Bitwig controller extension; bridges Bitwig and musalce-server over OSC, includes the `MusaLCESurfaceRelay` for Pulso. | Java (Bitwig Extension API 18) |
51
- | **MusaLCEforLive** | [MusaLCEforLive](https://github.com/javier-sy/MusaLCEforLive) | Ableton Live MIDI Remote Script; bridges Live and musalce-server over OSC. Inherits `/live/*` from AbletonOSC. | Python |
52
+ | **MusaLCEforLive** | [MusaLCEforLive](https://github.com/javier-sy/MusaLCEforLive) | Ableton Live MIDI Remote Script; bridges Live and musalce-server over OSC. | Python |
52
53
  | **MusaLCEClientForVSCode** | [MusaLCEClientForVSCode](https://github.com/javier-sy/MusaLCEClientForVSCode) | VSCode extension that is a REPL client over TCP/1327. | TypeScript |
53
- | **Pulso Bridge** *(optional)* | [pulso](https://github.com/javier-sy/pulso) | Bitwig controller that bridges between MusaLCEforBitwig (Surface relay side) and the Stream Deck plugin. | Java |
54
+ | **Pulso Bridge** *(optional)* | *public release pending* | The DAW-side component of [yeste.studio](https://yeste.studio)'s upcoming Pulso, a Stream Deck workflow system for DAWs (Bitwig today; Ableton planned). Pulso's primary scope is generic DAW control (transport, tracks, devices, browser, parameter encoders); Pulso Bridge can also relay user actions and feedback data to/from the Stream Deck through the MusaLCE Surface protocol in MusaLCEforBitwig/Live — that's the integration described in this doc. | --- |
54
55
 
55
- ## REPL DSL surface (`daw.*`)
56
+ ## Accessing the DAW (`daw.*`)
56
57
 
57
- The DSL context exposed in the REPL of the suite workflow extends what's available in the standalone REPL with a `daw` accessor. Quick reference (full reference: [musalce-server README → REPL Commands Reference](https://github.com/javier-sy/musalce-server#readme)):
58
+ **musalce-server** exposes to the user access to the daw through a `daw.*` accessor. Quick reference:
58
59
 
59
60
  | Accessor | Returns | What it's for |
60
61
  |---|---|---|
@@ -67,58 +68,6 @@ The DSL context exposed in the REPL of the suite workflow extends what's availab
67
68
  | `daw.play`, `daw.stop`, `daw.continue`, `daw.goto(bar)`, `daw.record` | — | Transport remote control. **Bitwig only** (Live API limitation). |
68
69
  | `daw.panic!` | — | All-notes-off to every track |
69
70
 
70
- ## `surface[:event]` DSL — Stream Deck integration
71
-
72
- A *Surface* control is named by an **event Symbol** that doubles as the identifier the sequencer uses when dispatching from a physical control. The surface is registered by the Pulso Bridge (via the inventory protocol — see [pulso/docs/osc-protocol.md](https://github.com/javier-sy/pulso/blob/main/docs/osc-protocol.md)); the server **owns the state** (message, enabled, value, range) and propagates changes outbound.
73
-
74
- There are three control types: **Toggle**, **Trigger** and **Encoder**.
75
-
76
- ### Trigger — momentary
77
-
78
- ```ruby
79
- # In score code:
80
- surface[:launch_chorus].set(message: "Chorus")
81
-
82
- on :launch_chorus do |payload|
83
- puts "Stream Deck button fired (#{payload.inspect})"
84
- # ... schedule the chorus section ...
85
- end
86
- ```
87
-
88
- A Trigger has no persistent state beyond an optional `message`. Pressing the Stream Deck button reaches the `on :launch_chorus do |payload| … end` handler through the sequencer's event dispatch.
89
-
90
- ### Toggle — three-state (Action / Ready / Idle)
91
-
92
- ```ruby
93
- surface[:mode].set(message: "Verse", enabled: true)
94
-
95
- on :mode do |payload|
96
- if surface[:mode].enabled
97
- surface[:mode].enabled = false
98
- # ... toggle off behaviour ...
99
- else
100
- surface[:mode].enabled = true
101
- # ... toggle on behaviour ...
102
- end
103
- end
104
- ```
105
-
106
- `enabled` accepts `true` / `false` / `:inactive` — Pulso paints the three states with distinct palettes (Action / Ready / Idle).
107
-
108
- ### Encoder — integer with range
109
-
110
- ```ruby
111
- surface[:tempo].set(value: 120, range: [60, 200], message: "BPM")
112
-
113
- on :tempo do |payload|
114
- new_value = payload[:value].to_i
115
- surface[:tempo].value = new_value
116
- # ... apply tempo change ...
117
- end
118
- ```
119
-
120
- The encoder owns its `value` (an integer) and its `range` (min, max integers). State propagates back to the Stream Deck plugin so the key/dial repaints.
121
-
122
71
  ## Stop/Play semantics
123
72
 
124
73
  The server registers exactly one built-in callback on the transport:
@@ -145,11 +94,9 @@ What survives a Stop/Play cycle:
145
94
  | `surface[:event]` **handler blocks** (`on :event do … end`) | ❌ (wiped with `@event_handlers`) |
146
95
  | `at`, `every`, `play`, `move` | ❌ |
147
96
 
148
- **Asymmetry warning**: the Stream Deck button keeps painting after a Stop, but pressing it dispatches to a handler that is no longer registered — silence.
149
-
150
97
  ### Rehydration pattern
151
98
 
152
- Use `daw.transport.on_start` (exposed since v0.7.2 — see [musalce-server commit `fb8480f`](https://github.com/javier-sy/musalce-server/commit/fb8480f)) to re-install handlers and schedules on every Play:
99
+ Use `daw.transport.on_start` to re-install handlers and schedules on every Play:
153
100
 
154
101
  ```ruby
155
102
  daw.transport.on_start do
@@ -157,7 +104,17 @@ daw.transport.on_start do
157
104
  end
158
105
  ```
159
106
 
160
- `on_start` callbacks accumulate (append-only list), so you can register more from the REPL at any time. Use `before_begin` for callbacks that should run **only on the first Start of the session**, and `after_stop` for cleanup (e.g. `voices.panic`).
107
+ `on_start` callbacks accumulate (it's an append-only list), so you can register more from the REPL at any time. Use `before_begin` for callbacks that should run **only on the first Start of the session**, and `after_stop` for cleanup (e.g. `voices.panic`).
108
+
109
+ ## Accessing the Stream Deck (`on :event` and `surface[:event]`)
110
+
111
+ In Stream Deck Pulso Workflow plugin the user has several kinds of buttons and encoders that can trigger events on the user MusaDSL code (as MusaDSL Sequencer Events with parameters). This allows the user to control the behaviour of his MusaDSL code in realtime using an elgato Stream Deck device.
112
+
113
+ The buttons and encoders are identified with a `event` name. This `event` name is the one launched on the `musalce-server` **Sequencer** and the one the user can subscribe from his code with `on :event |parameters| do ... end` commands.
114
+
115
+ Also, the user can update the visible content on the buttons and encoders on the Stream Deck device using the `surface[:event].set parameter: value, parameter: value` commands.
116
+
117
+ Pulso Bridge is aware of MusaLCEforBitwig/Live through a pair of configurable OSC ports and both coordinate the bidirectional communication between Stream Deck and MusaDSL code in the user session.
161
118
 
162
119
  ## OSC handler protocol
163
120
 
@@ -202,41 +159,20 @@ Both ports are **hardcoded** on the server side (`musalce-server/lib/daw.rb`). T
202
159
  | ext → server | `/musalce4live/track/audio` | bulk (sliced 3) | Audio track metadata. |
203
160
  | ext → server | `/musalce4live/track/routings` | bulk (sliced 5) | Routing metadata. |
204
161
 
205
- ### `/live/*`inherited from AbletonOSC (Live only)
162
+ ## MusaLCE Surface protocol elgato Stream Deck via Pulso's MusaLCE integration (Bitwig only)
206
163
 
207
- MusaLCEforLive inherits the full `/live/*` surface from [ideoforms/AbletonOSC](https://github.com/ideoforms/AbletonOSC) — dozens of endpoints covering volume, pan, send, clip control, devices, etc. These are not MusaLCE-specific and are not documented here; see the upstream README for the full address list.
208
-
209
- ## Surface protocol — Stream Deck via Pulso (Bitwig only)
210
-
211
- The protocol carrying surface inventory, triggers and state between musalce-server, MusaLCEforBitwig (`MusaLCESurfaceRelay`) and the Pulso Bridge is documented end-to-end in [pulso/docs/osc-protocol.md → MusaLCE surface relay](https://github.com/javier-sy/pulso/blob/main/docs/osc-protocol.md#musalce-surface-relay).
212
-
213
- Quick summary of address space:
164
+ The MusaLCE Surface protocol carries surface inventory, triggers and state between **musalce-server**, **MusaLCEforBitwig** and **Pulso Bridge**.
214
165
 
215
166
  - `/musalce/surface/inventory/{begin,add,remove,end}` — surface inventory (Pulso → server)
216
167
  - `/musalce/surface/trigger event payload` — Pulso → server, dispatched to `on :event` via `@sequencer.launch`
217
168
  - `/musalce/surface/state/{message,enabled,value,range} event …` — server → Pulso, repaints the Stream Deck
218
169
  - `/musalce/surface/sync_request`, `/musalce/surface/state_request` — handshake messages
219
170
 
220
- In the suite the relay is implemented on the Bitwig side only (`MusaLCEforBitwig/.../MusaLCESurfaceRelay.java`). **There is no Live-side relay yet** — Stream Deck integration is Bitwig-only at the time of writing.
221
-
222
- ## Current versions
223
-
224
- | Component | Version |
225
- |---|---|
226
- | musa-dsl | 0.42.7+ |
227
- | musalce-server | 0.7.2 |
228
- | MusaLCEforBitwig | from `git describe` (typically `0.x`) |
229
- | MusaLCEforLive | (no semver published) |
230
- | MusaLCEClientForVSCode | 0.1.0 |
231
- | Pulso Bridge | 0.x (see pulso/docs/osc-protocol.md changelog) |
232
- | Pulso Workflow (Stream Deck plugin) | matches Bridge |
233
-
234
- Stay on the same release branch across components — pin musalce-server in your `Gemfile.lock`, build the matching `.bwextension`/Remote Script from the same point in time. There's no semantic compatibility matrix today; protocol changes are coordinated across components by commit (see e.g. the simultaneous `id → event` rename in musalce-server `346fe51` ↔ pulso `0c6536f` ↔ MusaLCEforBitwig `33e4d7c`).
235
-
236
171
  ## Where to go next
237
172
 
238
173
  - Reference the **standalone REPL** workflow: [musa-dsl/docs/subsystems/repl.md](https://github.com/javier-sy/musa-dsl/blob/master/docs/subsystems/repl.md).
239
174
  - Reference the **REPL commands** (`daw.*`, transport controls, sequencer DSL) of the suite: [musalce-server README](https://github.com/javier-sy/musalce-server#readme).
240
175
  - Configure the **DAW extensions**: [MusaLCEforBitwig README](https://github.com/javier-sy/MusaLCEforBitwig#readme), [MusaLCEforLive README](https://github.com/javier-sy/MusaLCEforLive#readme).
241
176
  - Wire the **VSCode editor**: [MusaLCEClientForVSCode README](https://github.com/javier-sy/MusaLCEClientForVSCode#readme).
242
- - Wire the **Stream Deck** (Bitwig only): [Pulso README](https://github.com/javier-sy/pulso#readme) + [OSC protocol](https://github.com/javier-sy/pulso/blob/main/docs/osc-protocol.md).
177
+ - Wire the **Stream Deck** (Bitwig only): pending Pulso's public release.
178
+
data/lib/midi-devices.rb CHANGED
@@ -32,18 +32,28 @@ module MusaLCEServer
32
32
  #
33
33
  # @return [void]
34
34
  def sync
35
- names = @low_level_devices.keys
35
+ # Without this, MIDICommunications answers from the list it built the
36
+ # first time it was asked, and nothing plugged in since would ever be
37
+ # seen -- which made the sentence above false.
38
+ MIDICommunications::Loader.refresh
39
+
40
+ missing = @low_level_devices.keys
36
41
 
37
42
  MIDICommunications::Output.all.each do |low_level_device|
38
- next if @low_level_devices.key?(low_level_device.name)
43
+ name = low_level_device.name
44
+
45
+ # Outside the guard below, deliberately: seeing a device is what marks
46
+ # it as still connected, whether or not it is one we already had.
47
+ missing.delete name
48
+
49
+ next if @low_level_devices.key?(name)
39
50
 
40
- @low_level_devices[low_level_device.name] = MIDIDevice.new(@sequencer, low_level_device)
41
- names.delete low_level_device.name
51
+ @low_level_devices[name] = MIDIDevice.new(@sequencer, low_level_device)
42
52
  end
43
53
 
44
54
  # remove disconnected devices
45
55
  #
46
- names.each do |name|
56
+ missing.each do |name|
47
57
  @low_level_devices.delete name
48
58
  end
49
59
  end
data/lib/version.rb CHANGED
@@ -11,5 +11,5 @@
11
11
  # @since 0.1.0
12
12
  module MusaLCEServer
13
13
  # Current version of the musalce-server gem.
14
- VERSION = '0.8.0'.freeze
14
+ VERSION = '0.8.2'.freeze
15
15
  end
@@ -3,7 +3,7 @@ require_relative 'lib/version'
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'musalce-server'
5
5
  s.version = MusaLCEServer::VERSION
6
- s.date = '2026-05-16'
6
+ s.date = '2026-09-06'
7
7
  s.summary = 'A Musa DSL live coding environment for Ableton Live 11 and Bitwig Studio 5'
8
8
  s.description = 'This package implements the Server part of the Musa DSL Live Coding Environment for Ableton Live and Bitwig Studio'
9
9
  s.authors = ['Javier Sánchez Yeste']
@@ -23,7 +23,7 @@ Gem::Specification.new do |s|
23
23
 
24
24
  s.add_runtime_dependency 'musa-dsl', '~> 0.40'
25
25
 
26
- s.add_runtime_dependency 'midi-communications', '~> 0.7'
26
+ s.add_runtime_dependency 'midi-communications', '~> 0.7', '>= 0.7.1'
27
27
  s.add_runtime_dependency 'midi-events', '~> 0.7'
28
28
  s.add_runtime_dependency 'midi-parser', '~> 0.5'
29
29
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: musalce-server
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Javier Sánchez Yeste
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-05-16 00:00:00.000000000 Z
10
+ date: 2026-09-06 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: musa-dsl
@@ -30,6 +30,9 @@ dependencies:
30
30
  - - "~>"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '0.7'
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: 0.7.1
33
36
  type: :runtime
34
37
  prerelease: false
35
38
  version_requirements: !ruby/object:Gem::Requirement
@@ -37,6 +40,9 @@ dependencies:
37
40
  - - "~>"
38
41
  - !ruby/object:Gem::Version
39
42
  version: '0.7'
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: 0.7.1
40
46
  - !ruby/object:Gem::Dependency
41
47
  name: midi-events
42
48
  requirement: !ruby/object:Gem::Requirement