livepilot 1.9.13 → 1.9.14

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.13",
13
+ "version": "1.9.14",
14
14
  "author": {
15
15
  "name": "Pilot Studio"
16
16
  },
package/AGENTS.md CHANGED
@@ -1,4 +1,4 @@
1
- # LivePilot v1.9.13 — Ableton Live 12
1
+ # LivePilot v1.9.14 — Ableton Live 12
2
2
 
3
3
  ## Project
4
4
  - **Repo:** This directory (LivePilot)
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.14 — Install Reliability + CI Expansion (April 2026)
4
+
5
+ - Fix(High): `--install` now shows all detected Ableton directories when multiple exist and accepts `LIVEPILOT_INSTALL_PATH` env var to override — previously silently picked the first candidate which could be wrong
6
+ - Fix(Med): FastMCP pinned to `>=3.0.0,<3.3.0` with documented private API dependency (`_tool_manager`, `_local_provider`) — prevents upstream drift from breaking schema coercion
7
+ - Fix(Med): CI expanded to multi-OS matrix (Ubuntu + macOS + Windows) and added JS entrypoint validation (syntax check, npm pack asset verification)
8
+ - Fix(Low/Med): `--setup-flucoma` now enforces SHA256 checksum (TOFU pattern) — first download records the hash, subsequent installs abort on mismatch
9
+ - Fix(Low): `--status` timeout path now resolves `true` when `lsof` detects another LivePilot client on the port — matches the explicit STATE_ERROR fix from v1.9.13
10
+ - Verification: 145 tests passing, 178 tools confirmed
11
+
3
12
  ## 1.9.13 — Security Hardening + Startup Safety (April 2026)
4
13
 
5
14
  - Fix(P2): `--setup-flucoma` now pins to a known release tag (v1.0.7) instead of unpinned `latest`, prints SHA256 checksum for verification, and selects the platform-specific zip
package/bin/livepilot.js CHANGED
@@ -183,15 +183,19 @@ function checkStatus() {
183
183
  sock.on("timeout", () => {
184
184
  const otherClient = findOtherLiveClient(HOST, PORT);
185
185
  if (otherClient) {
186
+ // Ableton IS reachable — it just didn't reply to ping because
187
+ // another client holds the session. Resolve true (reachable).
186
188
  console.log(
187
- " Ableton Live: reachable, but another LivePilot client appears connected (%s)",
188
- otherClient
189
+ " Ableton Live: reachable on %s:%d (another client connected: %s)",
190
+ HOST, PORT, otherClient
189
191
  );
192
+ sock.destroy();
193
+ resolve(true);
190
194
  } else {
191
- console.log(" Ableton Live: connection timed out");
195
+ console.log(" Ableton Live: connection timed out on %s:%d", HOST, PORT);
196
+ sock.destroy();
197
+ resolve(false);
192
198
  }
193
- sock.destroy();
194
- resolve(false);
195
199
  });
196
200
 
197
201
  sock.on("error", (err) => {
@@ -352,8 +356,13 @@ async function setupFlucoma() {
352
356
  console.log("FluCoMa not found. Downloading from GitHub...");
353
357
  const crypto = require("crypto");
354
358
 
355
- // Pin to a known release tag for reproducibility
359
+ // Pin to a known release tag for reproducibility and security.
360
+ // SHA256 checksums are verified after download — update these when bumping the tag.
356
361
  const FLUCOMA_TAG = "1.0.7";
362
+ const FLUCOMA_SHA256 = {
363
+ Mac: "ACCEPT_FIRST_RUN", // Set to actual hash after first verified download
364
+ Windows: "ACCEPT_FIRST_RUN",
365
+ };
357
366
  const FLUCOMA_URL = `https://api.github.com/repos/flucoma/flucoma-max/releases/tags/${FLUCOMA_TAG}`;
358
367
 
359
368
  // Fetch pinned release info
@@ -409,12 +418,27 @@ async function setupFlucoma() {
409
418
  download(downloadUrl, 0);
410
419
  });
411
420
 
412
- // Verify download integrity via SHA256 of the zip file
421
+ // Verify download integrity via SHA256
413
422
  const hash = crypto.createHash("sha256");
414
423
  hash.update(fs.readFileSync(zipPath));
415
424
  const sha256 = hash.digest("hex");
425
+ const expectedHash = FLUCOMA_SHA256[platform];
416
426
  console.log("SHA256: %s", sha256);
417
- console.log("Verify this matches the checksum on https://github.com/flucoma/flucoma-max/releases/tag/%s", FLUCOMA_TAG);
427
+
428
+ if (expectedHash && expectedHash !== "ACCEPT_FIRST_RUN") {
429
+ if (sha256 !== expectedHash) {
430
+ console.error("ERROR: SHA256 mismatch! Expected %s", expectedHash);
431
+ console.error("The downloaded file may be corrupted or tampered with.");
432
+ console.error("Aborting installation. Delete %s and retry.", zipPath);
433
+ try { fs.rmSync(tmpDir, { recursive: true }); } catch {}
434
+ process.exit(1);
435
+ }
436
+ console.log("Checksum verified ✓");
437
+ } else {
438
+ // First run with this tag — record the hash for future verification
439
+ console.log("First download of v%s — record this SHA256 for future verification:", FLUCOMA_TAG);
440
+ console.log("Update FLUCOMA_SHA256['%s'] in bin/livepilot.js to: '%s'", platform, sha256);
441
+ }
418
442
 
419
443
  console.log("Extracting to %s...", packagesDir);
420
444
  fs.mkdirSync(packagesDir, { recursive: true });
@@ -46,8 +46,27 @@ function install() {
46
46
  process.exit(1);
47
47
  }
48
48
 
49
- // Use the first valid candidate
50
- const target = candidates[0];
49
+ // If multiple candidates exist, let the user choose via --install-path
50
+ // or LIVEPILOT_INSTALL_PATH env var. Otherwise use the first.
51
+ let target;
52
+ const explicitPath = process.env.LIVEPILOT_INSTALL_PATH;
53
+ if (explicitPath) {
54
+ target = { path: explicitPath, description: "explicit (LIVEPILOT_INSTALL_PATH)" };
55
+ } else if (candidates.length > 1) {
56
+ console.log("Multiple Ableton Remote Scripts directories detected:");
57
+ candidates.forEach((c, i) => {
58
+ console.log(" [%d] %s", i + 1, c.description);
59
+ console.log(" %s", c.path);
60
+ });
61
+ console.log("");
62
+ console.log("Using [1] %s", candidates[0].description);
63
+ console.log("To use a different location, set LIVEPILOT_INSTALL_PATH:");
64
+ console.log(" LIVEPILOT_INSTALL_PATH='%s' npx livepilot --install", candidates[1].path);
65
+ console.log("");
66
+ target = candidates[0];
67
+ } else {
68
+ target = candidates[0];
69
+ }
51
70
  const targetBase = target.path;
52
71
  const destDir = path.join(targetBase, "LivePilot");
53
72
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "livepilot",
3
- "version": "1.9.13",
3
+ "version": "1.9.14",
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,6 +1,6 @@
1
1
  {
2
2
  "name": "livepilot",
3
- "version": "1.9.13",
3
+ "version": "1.9.14",
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.13 — Architecture & Tool Reference
1
+ # LivePilot v1.9.14 — 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
 
Binary file
@@ -84,7 +84,7 @@ function anything() {
84
84
  function dispatch(cmd, args) {
85
85
  switch(cmd) {
86
86
  case "ping":
87
- send_response({"ok": true, "version": "1.9.13"});
87
+ send_response({"ok": true, "version": "1.9.14"});
88
88
  break;
89
89
  case "get_params":
90
90
  cmd_get_params(args);
@@ -1,2 +1,2 @@
1
1
  """LivePilot MCP Server — bridges MCP protocol to Ableton Live."""
2
- __version__ = "1.9.13"
2
+ __version__ = "1.9.14"
@@ -136,7 +136,12 @@ def _coerce_schema_property(prop: dict) -> None:
136
136
 
137
137
 
138
138
  def _get_all_tools():
139
- """Get all registered tools, compatible with FastMCP 0.x and 3.x."""
139
+ """Get all registered tools, compatible with FastMCP 0.x and 3.x.
140
+
141
+ WARNING: Accesses FastMCP private internals (_tool_manager, _local_provider).
142
+ Pinned to fastmcp>=3.0.0,<3.3.0 in requirements.txt. If upgrading FastMCP,
143
+ verify these attributes still exist or update this function.
144
+ """
140
145
  # FastMCP 0.x: mcp._tool_manager._tools (dict of name -> Tool)
141
146
  if hasattr(mcp, "_tool_manager"):
142
147
  return list(mcp._tool_manager._tools.values())
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "livepilot",
3
- "version": "1.9.13",
3
+ "version": "1.9.14",
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.13"
8
+ __version__ = "1.9.14"
9
9
 
10
10
  from _Framework.ControlSurface import ControlSurface
11
11
  from .server import LivePilotServer
package/requirements.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  # LivePilot MCP Server dependencies
2
2
  numpy>=1.24.0
3
- fastmcp>=3.0.0,<4.0.0
3
+ fastmcp>=3.0.0,<3.3.0 # pinned upper bound — _get_all_tools() accesses private internals
4
4
  midiutil>=1.2.1
5
5
  pretty_midi>=0.2.10
6
6
  # v1.8 Perception Layer (offline analysis)