livepilot 1.9.7 → 1.9.9

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.
@@ -10,7 +10,7 @@
10
10
  {
11
11
  "name": "livepilot",
12
12
  "description": "Agentic production system for Ableton Live 12 — 178 tools, 17 domains, device atlas, spectral perception, technique memory, neo-Riemannian harmony, Euclidean rhythm, species counterpoint, MIDI I/O",
13
- "version": "1.9.7",
13
+ "version": "1.9.9",
14
14
  "author": {
15
15
  "name": "Pilot Studio"
16
16
  },
package/AGENTS.md CHANGED
@@ -1,4 +1,4 @@
1
- # LivePilot v1.9.7 — Ableton Live 12
1
+ # LivePilot v1.9.9 — Ableton Live 12
2
2
 
3
3
  ## Project
4
4
  - **Repo:** This directory (LivePilot)
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "livepilot",
3
- "version": "1.9.7",
3
+ "version": "1.9.9",
4
4
  "description": "Agentic production system for Ableton Live 12 — 178 tools, 17 domains, device atlas, spectral perception, technique memory, neo-Riemannian harmony, Euclidean rhythm, species counterpoint, MIDI I/O",
5
5
  "author": {
6
6
  "name": "Pilot Studio"
@@ -1,4 +1,4 @@
1
- # LivePilot v1.9.7 — Architecture & Tool Reference
1
+ # LivePilot v1.9.9 — Architecture & Tool Reference
2
2
 
3
3
  Agentic production system for Ableton Live 12. 178 tools across 17 domains. Device atlas (280+ devices), spectral perception (M4L analyzer), technique memory, automation intelligence (16 curve types, 15 recipes), music theory (Krumhansl-Schmuckler, species counterpoint), generative algorithms (Euclidean rhythm, tintinnabuli, phase shift, additive process), neo-Riemannian harmony (PRL transforms, Tonnetz), MIDI file I/O.
4
4
 
@@ -83,7 +83,7 @@ function anything() {
83
83
  function dispatch(cmd, args) {
84
84
  switch(cmd) {
85
85
  case "ping":
86
- send_response({"ok": true, "version": "1.9.7"});
86
+ send_response({"ok": true, "version": "1.9.9"});
87
87
  break;
88
88
  case "get_params":
89
89
  cmd_get_params(args);
@@ -1,2 +1,2 @@
1
1
  """LivePilot MCP Server — bridges MCP protocol to Ableton Live."""
2
- __version__ = "1.9.7"
2
+ __version__ = "1.9.9"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "livepilot",
3
- "version": "1.9.7",
3
+ "version": "1.9.9",
4
4
  "mcpName": "io.github.dreamrec/livepilot",
5
5
  "description": "Agentic production system for Ableton Live 12 — 178 tools, 17 domains, device atlas, spectral perception, technique memory, neo-Riemannian harmony, Euclidean rhythm, species counterpoint, MIDI I/O",
6
6
  "author": "Pilot Studio",
@@ -5,7 +5,7 @@ Entry point for the ControlSurface. Ableton calls create_instance(c_instance)
5
5
  when this script is selected in Preferences > Link, Tempo & MIDI.
6
6
  """
7
7
 
8
- __version__ = "1.9.7"
8
+ __version__ = "1.9.9"
9
9
 
10
10
  from _Framework.ControlSurface import ControlSurface
11
11
  from .server import LivePilotServer
@@ -298,13 +298,28 @@ def freeze_track(song, params):
298
298
  "is_frozen": True,
299
299
  "note": "Track is already frozen",
300
300
  }
301
- # In Live 12, freeze is a track method accessible from ControlSurface
301
+ # Try track.freeze() first (available in some Live versions),
302
+ # then fall back to song-level freeze API
303
+ frozen = False
302
304
  try:
303
305
  track.freeze()
306
+ frozen = True
304
307
  except AttributeError:
308
+ pass
309
+
310
+ if not frozen:
311
+ # Song-level API: freeze by track index
312
+ try:
313
+ song.freeze_track(track_index)
314
+ frozen = True
315
+ except AttributeError:
316
+ pass
317
+
318
+ if not frozen:
305
319
  raise ValueError(
306
- "freeze() not available on this track type. "
307
- "Only MIDI and audio tracks with devices can be frozen."
320
+ "freeze() not available via ControlSurface API. "
321
+ "Use Ableton's Freeze Track command (Cmd+F) manually, "
322
+ "or use the M4L bridge for programmatic freeze."
308
323
  )
309
324
  return {
310
325
  "track_index": track_index,
@@ -329,8 +344,23 @@ def flatten_track(song, params):
329
344
  )
330
345
  song.begin_undo_step()
331
346
  try:
332
- # flatten() is a method on the track, not the song
333
- track.flatten()
347
+ flattened = False
348
+ try:
349
+ track.flatten()
350
+ flattened = True
351
+ except AttributeError:
352
+ pass
353
+ if not flattened:
354
+ try:
355
+ song.flatten_track(track_index)
356
+ flattened = True
357
+ except AttributeError:
358
+ pass
359
+ if not flattened:
360
+ raise ValueError(
361
+ "flatten() not available via ControlSurface API. "
362
+ "Use Ableton's Flatten command manually."
363
+ )
334
364
  finally:
335
365
  song.end_undo_step()
336
366
  return {