livepilot 1.10.6 → 1.10.7

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.
Files changed (78) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/.mcp.json.disabled +9 -0
  3. package/.mcpbignore +3 -0
  4. package/AGENTS.md +3 -3
  5. package/BUGS.md +1570 -0
  6. package/CHANGELOG.md +42 -0
  7. package/CONTRIBUTING.md +1 -1
  8. package/README.md +7 -7
  9. package/bin/livepilot.js +28 -8
  10. package/livepilot/.Codex-plugin/plugin.json +2 -2
  11. package/livepilot/.claude-plugin/plugin.json +2 -2
  12. package/livepilot/skills/livepilot-core/SKILL.md +4 -4
  13. package/livepilot/skills/livepilot-core/references/overview.md +2 -2
  14. package/livepilot/skills/livepilot-release/SKILL.md +8 -8
  15. package/m4l_device/LivePilot_Analyzer.amxd +0 -0
  16. package/m4l_device/LivePilot_Analyzer.amxd.pre-presentation-backup +0 -0
  17. package/m4l_device/LivePilot_Analyzer.maxproj +53 -0
  18. package/m4l_device/livepilot_bridge.js +214 -2
  19. package/manifest.json +3 -3
  20. package/mcp_server/__init__.py +1 -1
  21. package/mcp_server/atlas/__init__.py +93 -26
  22. package/mcp_server/creative_constraints/tools.py +206 -33
  23. package/mcp_server/experiment/engine.py +7 -9
  24. package/mcp_server/hook_hunter/analyzer.py +62 -9
  25. package/mcp_server/hook_hunter/tools.py +60 -9
  26. package/mcp_server/m4l_bridge.py +21 -6
  27. package/mcp_server/musical_intelligence/detectors.py +32 -0
  28. package/mcp_server/performance_engine/tools.py +112 -29
  29. package/mcp_server/preview_studio/engine.py +89 -8
  30. package/mcp_server/preview_studio/tools.py +22 -6
  31. package/mcp_server/project_brain/automation_graph.py +71 -19
  32. package/mcp_server/project_brain/builder.py +2 -0
  33. package/mcp_server/project_brain/tools.py +55 -5
  34. package/mcp_server/reference_engine/profile_builder.py +129 -3
  35. package/mcp_server/reference_engine/tools.py +47 -6
  36. package/mcp_server/runtime/execution_router.py +50 -0
  37. package/mcp_server/runtime/mcp_dispatch.py +75 -3
  38. package/mcp_server/runtime/remote_commands.py +4 -2
  39. package/mcp_server/sample_engine/analyzer.py +131 -4
  40. package/mcp_server/sample_engine/critics.py +29 -8
  41. package/mcp_server/sample_engine/models.py +20 -1
  42. package/mcp_server/sample_engine/tools.py +48 -14
  43. package/mcp_server/semantic_moves/sound_design_compilers.py +22 -59
  44. package/mcp_server/semantic_moves/transition_compilers.py +12 -19
  45. package/mcp_server/server.py +68 -2
  46. package/mcp_server/session_continuity/models.py +4 -0
  47. package/mcp_server/session_continuity/tracker.py +14 -1
  48. package/mcp_server/song_brain/builder.py +110 -12
  49. package/mcp_server/song_brain/tools.py +77 -13
  50. package/mcp_server/sound_design/tools.py +112 -1
  51. package/mcp_server/stuckness_detector/detector.py +90 -0
  52. package/mcp_server/stuckness_detector/tools.py +41 -0
  53. package/mcp_server/tools/_agent_os_engine/critics.py +24 -0
  54. package/mcp_server/tools/_composition_engine/__init__.py +2 -2
  55. package/mcp_server/tools/_composition_engine/harmony.py +90 -0
  56. package/mcp_server/tools/_composition_engine/sections.py +47 -4
  57. package/mcp_server/tools/_harmony_engine.py +52 -8
  58. package/mcp_server/tools/_research_engine.py +98 -19
  59. package/mcp_server/tools/_theory_engine.py +138 -9
  60. package/mcp_server/tools/agent_os.py +20 -3
  61. package/mcp_server/tools/analyzer.py +98 -0
  62. package/mcp_server/tools/clips.py +45 -0
  63. package/mcp_server/tools/composition.py +66 -23
  64. package/mcp_server/tools/devices.py +22 -1
  65. package/mcp_server/tools/harmony.py +115 -14
  66. package/mcp_server/tools/midi_io.py +13 -1
  67. package/mcp_server/tools/mixing.py +35 -1
  68. package/mcp_server/tools/motif.py +49 -3
  69. package/mcp_server/tools/research.py +24 -0
  70. package/mcp_server/tools/theory.py +108 -16
  71. package/mcp_server/transition_engine/critics.py +18 -11
  72. package/package.json +2 -2
  73. package/remote_script/LivePilot/__init__.py +57 -2
  74. package/remote_script/LivePilot/clips.py +69 -0
  75. package/remote_script/LivePilot/mixing.py +117 -0
  76. package/remote_script/LivePilot/router.py +13 -1
  77. package/scripts/generate_tool_catalog.py +13 -38
  78. package/scripts/sync_metadata.py +231 -14
package/CHANGELOG.md CHANGED
@@ -1,5 +1,47 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.10.7 — npm .amxd parity + domain-count consistency (April 18 2026)
4
+
5
+ Shipping release. Brings npm's tarball back in line with the fresh `.amxd`
6
+ freeze that landed on `main` after v1.10.6 tagged, and unifies the three
7
+ formerly-disagreeing sources of the domain count.
8
+
9
+ ### Fixed
10
+
11
+ - **npm tarball parity with the GitHub release.** v1.10.6's npm publish
12
+ predated commit `b0463ea` (the real fat `.amxd` freeze with matching ping
13
+ bytes), so `npm install livepilot@1.10.6` shipped the stale Batch-22
14
+ `.amxd` and `simpler_set_warp` silently no-op'd. v1.10.7 republishes with
15
+ the fresh `.amxd` already present in the GitHub release assets.
16
+ - **Domain count unified at 45.** Three formerly-disagreeing sources: prose
17
+ docs claimed "43 domains", `generate_tool_catalog.py` inferred "36" (via
18
+ a hand-maintained whitelist that silently dropped ~10 domains —
19
+ `atlas`, `composer`, `creative_constraints`, `device_forge`,
20
+ `hook_hunter`, `preview_studio`, `sample_engine`, `session_continuity`,
21
+ `song_brain`, `stuckness_detector`, `wonder_mode` — into an "Other"
22
+ bucket), runtime module layout has 45. All three now agree.
23
+ - **Inline domain lists completed.** `CLAUDE.md:31` was missing
24
+ `experiment`, `musical_intelligence`, and `semantic_moves`;
25
+ `livepilot/skills/livepilot-release/SKILL.md:63` was missing
26
+ `semantic_moves`.
27
+
28
+ ### Infra
29
+
30
+ - **`scripts/sync_metadata.py` extended** with `check_domain_count()` and
31
+ `check_domain_list()` that derive truth from `mcp_server` module paths.
32
+ `--fix` mode now auto-corrects stale tool/domain counts and appends
33
+ missing inline-list entries; extra entries are never auto-removed so a
34
+ pattern miss can't silently delete a legitimate domain.
35
+ - **`scripts/generate_tool_catalog.py`** now uses the same module-layout
36
+ rule (`mcp_server.<X>` / `mcp_server.tools.<Y>`) as `sync_metadata.py`
37
+ so the two tools can't disagree on the domain set again.
38
+ - **`.mcpbignore`** excludes `m4l_device/*.pre-*-backup` rollback artifacts
39
+ from the packaged `.mcpb`, keeping release bundles pristine across
40
+ future freeze cycles.
41
+ - **`CLAUDE.md` gains `## Domain Count` section** documenting the drift
42
+ enforcer alongside the existing `## Tool Count` and `## Version Bump`
43
+ sections.
44
+
3
45
  ## 1.10.6 — Debuggability + Engine Modularization (April 17 2026)
4
46
 
5
47
  Defensive-programming release. Zero behavior change for users; substantial
package/CONTRIBUTING.md CHANGED
@@ -98,7 +98,7 @@ Prefix with `fix:`, `feat:`, `docs:`, `refactor:`, `test:`, or `chore:`.
98
98
 
99
99
  ## Tool Count Discipline
100
100
 
101
- Currently **320 tools**. If you add or remove a `@mcp.tool()` decorator, update all of these files:
101
+ Currently **323 tools**. If you add or remove a `@mcp.tool()` decorator, update all of these files:
102
102
 
103
103
  - `README.md`
104
104
  - `CLAUDE.md`
package/README.md CHANGED
@@ -17,7 +17,7 @@
17
17
 
18
18
  <p align="center">
19
19
  An agentic production system for Ableton Live 12.<br>
20
- 320 tools. 43 domains. Device atlas. Splice integration. Auto-composition. Spectral perception. Technique memory.
20
+ 323 tools. 45 domains. Device atlas. Splice integration. Auto-composition. Spectral perception. Technique memory.
21
21
  </p>
22
22
 
23
23
  <br>
@@ -79,8 +79,8 @@ Most MCP servers are tool collections — they execute commands. LivePilot is an
79
79
  │ └─────────────────┼──────────────────┘ │
80
80
  │ ▼ │
81
81
  │ ┌─────────────────┐ │
82
- │ │ 320 MCP Tools │ │
83
- │ │ 43 domains │ │
82
+ │ │ 323 MCP Tools │ │
83
+ │ │ 45 domains │ │
84
84
  │ └────────┬────────┘ │
85
85
  │ │ │
86
86
  │ Remote Script ──┤── TCP 9878 │
@@ -120,7 +120,7 @@ Most MCP servers are tool collections — they execute commands. LivePilot is an
120
120
 
121
121
  ## The Intelligence Layer
122
122
 
123
- 12 engines sit on top of the 320 tools. They give the AI musical judgment, not just musical execution.
123
+ 12 engines sit on top of the 323 tools. They give the AI musical judgment, not just musical execution.
124
124
 
125
125
  ### SongBrain — What the Song Is
126
126
 
@@ -172,7 +172,7 @@ Every engine follows: **measure before → act → measure after → compare**.
172
172
 
173
173
  ## Tools
174
174
 
175
- 320 tools across 43 domains. Highlights below — [full catalog here](docs/manual/tool-catalog.md).
175
+ 323 tools across 45 domains. Highlights below — [full catalog here](docs/manual/tool-catalog.md).
176
176
 
177
177
  <br>
178
178
 
@@ -360,7 +360,7 @@ The V2 intelligence layer. These tools analyze, diagnose, plan, evaluate, and le
360
360
  | Creative Constraints | 5 | constraint activation, reference-inspired variants |
361
361
  | Preview Studio | 5 | variant creation, preview rendering, comparison, commit |
362
362
 
363
- > **[View all 320 tools →](docs/manual/tool-catalog.md)**
363
+ > **[View all 323 tools →](docs/manual/tool-catalog.md)**
364
364
 
365
365
  <br>
366
366
 
@@ -585,7 +585,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for architecture details, code guidelines
585
585
 
586
586
  | Document | What's inside |
587
587
  |----------|---------------|
588
- | [Manual](docs/manual/index.md) | Complete reference: architecture, all 320 tools, workflows |
588
+ | [Manual](docs/manual/index.md) | Complete reference: architecture, all 323 tools, workflows |
589
589
  | [Intelligence Layer](docs/manual/intelligence.md) | How the 12 engines connect — conductor, moves, preview, evaluation |
590
590
  | [Device Atlas](docs/manual/device-atlas.md) | 1305 devices indexed — search, suggest, chain building |
591
591
  | [Samples & Slicing](docs/manual/samples.md) | 3-source search, fitness critics, slice workflows |
package/bin/livepilot.js CHANGED
@@ -402,27 +402,47 @@ async function setupFlucoma() {
402
402
  const https = require("https");
403
403
 
404
404
  const home = os.homedir();
405
- const packagesDir = process.platform === "darwin"
406
- ? path.join(home, "Documents", "Max 8", "Packages")
407
- : path.join(process.env.USERPROFILE || home, "Documents", "Max 8", "Packages");
408
405
 
406
+ // Max 9 is the current release (the Ableton Live 12.3+ default); Max 8 is
407
+ // the legacy path. Check both — if FluCoMa is already installed in either,
408
+ // Max will find it via its package search path. For fresh installs, prefer
409
+ // Max 9. Users still on Max 8 get the legacy path.
410
+ const docsBase = process.platform === "darwin"
411
+ ? path.join(home, "Documents")
412
+ : path.join(process.env.USERPROFILE || home, "Documents");
413
+
414
+ const max9PackagesDir = path.join(docsBase, "Max 9", "Packages");
415
+ const max8PackagesDir = path.join(docsBase, "Max 8", "Packages");
416
+
417
+ // Prefer Max 9 if that directory exists, else Max 8
418
+ const packagesDir = fs.existsSync(max9PackagesDir) ? max9PackagesDir : max8PackagesDir;
409
419
  const flucomaDir = path.join(packagesDir, "FluidCorpusManipulation");
410
420
 
411
- if (fs.existsSync(flucomaDir)) {
412
- // Check version
413
- const pkgInfo = path.join(flucomaDir, "package-info.json");
421
+ // Check BOTH locations for an existing install — a user may have Max 8
422
+ // FluCoMa from a prior install that still works
423
+ const altFlucomaDir = path.join(
424
+ packagesDir === max9PackagesDir ? max8PackagesDir : max9PackagesDir,
425
+ "FluidCorpusManipulation"
426
+ );
427
+
428
+ for (const candidateDir of [flucomaDir, altFlucomaDir]) {
429
+ if (!fs.existsSync(candidateDir)) continue;
430
+ const pkgInfo = path.join(candidateDir, "package-info.json");
414
431
  if (fs.existsSync(pkgInfo)) {
415
432
  try {
416
433
  const info = JSON.parse(fs.readFileSync(pkgInfo, "utf-8"));
417
434
  console.log("FluCoMa already installed: v%s", info.version || "unknown");
418
- console.log("Location: %s", flucomaDir);
435
+ console.log("Location: %s", candidateDir);
419
436
  return;
420
437
  } catch {}
421
438
  }
422
- console.log("FluCoMa already installed at %s", flucomaDir);
439
+ console.log("FluCoMa already installed at %s", candidateDir);
423
440
  return;
424
441
  }
425
442
 
443
+ // Ensure the parent Packages directory exists for the install target
444
+ fs.mkdirSync(packagesDir, { recursive: true });
445
+
426
446
  console.log("FluCoMa not found. Downloading from GitHub...");
427
447
  const crypto = require("crypto");
428
448
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "livepilot",
3
- "version": "1.10.6",
4
- "description": "Agentic production system for Ableton Live 12 — 320 tools, 43 domains, device atlas, sample intelligence, auto-composition, spectral perception, technique memory, neo-Riemannian harmony, Euclidean rhythm, species counterpoint, MIDI I/O",
3
+ "version": "1.10.7",
4
+ "description": "Agentic production system for Ableton Live 12 — 323 tools, 45 domains, device atlas, sample intelligence, auto-composition, spectral perception, technique memory, neo-Riemannian harmony, Euclidean rhythm, species counterpoint, MIDI I/O",
5
5
  "author": {
6
6
  "name": "Pilot Studio"
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "livepilot",
3
- "version": "1.10.6",
4
- "description": "Agentic production system for Ableton Live 12 — 320 tools, 43 domains, device atlas, sample intelligence, auto-composition, spectral perception, technique memory, neo-Riemannian harmony, Euclidean rhythm, species counterpoint, MIDI I/O",
3
+ "version": "1.10.7",
4
+ "description": "Agentic production system for Ableton Live 12 — 323 tools, 45 domains, device atlas, sample intelligence, auto-composition, spectral perception, technique memory, neo-Riemannian harmony, Euclidean rhythm, species counterpoint, MIDI I/O",
5
5
  "author": {
6
6
  "name": "Pilot Studio"
7
7
  }
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: livepilot-core
3
- description: Core discipline for LivePilot — agentic production system for Ableton Live 12. 320 tools across 43 domains. This skill should be used whenever working with Ableton Live through MCP tools. Provides golden rules, tool speed tiers, error handling protocol, and pointers to domain and engine skills.
3
+ description: Core discipline for LivePilot — agentic production system for Ableton Live 12. 323 tools across 45 domains. This skill should be used whenever working with Ableton Live through MCP tools. Provides golden rules, tool speed tiers, error handling protocol, and pointers to domain and engine skills.
4
4
  ---
5
5
 
6
6
  # LivePilot Core — Ableton Live 12
7
7
 
8
- Agentic production system for Ableton Live 12. 320 tools across 43 domains, three layers:
8
+ Agentic production system for Ableton Live 12. 323 tools across 45 domains, three layers:
9
9
 
10
10
  - **Device Atlas** — 1305 devices indexed (81 enriched with sonic intelligence, 683 drum kits). Consult `atlas_search` or `atlas_suggest` before loading any device. Never guess a device name.
11
11
  - **M4L Analyzer** — Real-time audio analysis on the master bus (8-band spectrum, RMS/peak, key detection). Optional — all core tools work without it.
@@ -39,7 +39,7 @@ Agentic production system for Ableton Live 12. 320 tools across 43 domains, thre
39
39
  ## Tool Speed Tiers
40
40
 
41
41
  ### Instant (<1s) — Use freely
42
- All 320 tools plus M4L perception tools.
42
+ All 323 tools plus M4L perception tools.
43
43
 
44
44
  ### Fast (1-5s) — Use freely
45
45
  `analyze_loudness` · `analyze_mix` · `analyze_sound_design`
@@ -128,7 +128,7 @@ Deep production knowledge in `references/`:
128
128
 
129
129
  | File | Content |
130
130
  |------|---------|
131
- | `references/overview.md` | All 320 tools with params and ranges |
131
+ | `references/overview.md` | All 323 tools with params and ranges |
132
132
  | `references/device-atlas/` | 280+ device corpus with URIs and presets |
133
133
  | `references/midi-recipes.md` | Drum patterns, chord voicings, humanization |
134
134
  | `references/sound-design.md` | Synth recipes, device chain patterns |
@@ -1,6 +1,6 @@
1
- # LivePilot v1.10.6 — Architecture & Tool Reference
1
+ # LivePilot v1.10.7 — Architecture & Tool Reference
2
2
 
3
- Agentic production system for Ableton Live 12. 320 tools across 43 domains. Device atlas (1305 devices, 81 enriched), 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, Splice online catalog search and download via gRPC (v1.10.6 unblocked 19,690+ catalog hits previously inaccessible).
3
+ Agentic production system for Ableton Live 12. 323 tools across 45 domains. Device atlas (1305 devices, 81 enriched), 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, Splice online catalog search and download via gRPC (v1.10.6 unblocked 19,690+ catalog hits previously inaccessible).
4
4
 
5
5
  ## Architecture
6
6
 
@@ -28,20 +28,20 @@ Run this checklist EVERY time the user says "update everything", "push", "releas
28
28
 
29
29
  ## 2. Tool Count (must ALL match)
30
30
 
31
- Current: **320 tools across 43 domains**.
31
+ Current: **323 tools across 45 domains**.
32
32
  Core (no M4L): **289**. Bridge (M4L): **30** (backed by 28 bridge commands).
33
33
 
34
34
  Verify: `grep -rc "@mcp.tool" mcp_server/tools/ | grep -v ":0" | awk -F: '{sum+=$2} END{print sum}'`
35
35
 
36
36
  Files that reference tool count:
37
- - [ ] `README.md` — header ("320 tools. 43 domains"), bridge section ("281 core...36 bridge")
37
+ - [ ] `README.md` — header ("323 tools. 45 domains"), bridge section ("281 core...36 bridge")
38
38
  - [ ] `package.json` → `"description"`
39
39
  - [ ] `server.json` → `"description"`
40
40
  - [ ] `manifest.json` → `"description"`
41
41
  - [ ] `livepilot/.Codex-plugin/plugin.json` → `"description"` (primary Codex manifest)
42
42
  - [ ] `livepilot/.claude-plugin/plugin.json` → `"description"` (must match Codex plugin)
43
43
  - [ ] `.claude-plugin/marketplace.json` → `"description"`
44
- - [ ] `CLAUDE.md` → "320 tools across 43 domains"
44
+ - [ ] `CLAUDE.md` → "323 tools across 45 domains"
45
45
  - [ ] `CONTRIBUTING.md` → tool count in intro
46
46
  - [ ] `livepilot/skills/livepilot-core/SKILL.md` — tool/domain count
47
47
  - [ ] `livepilot/skills/livepilot-core/references/overview.md` — tool/domain count
@@ -60,10 +60,10 @@ Files that reference tool count:
60
60
 
61
61
  ## 3. Domain Count
62
62
 
63
- Current: **43 domains**: transport, tracks, clips, notes, devices, scenes, mixing, browser, arrangement, memory, analyzer, automation, theory, generative, harmony, midi_io, perception, agent_os, composition, motif, research, planner, project_brain, runtime, evaluation, mix_engine, sound_design, transition_engine, reference_engine, translation_engine, performance_engine, song_brain, preview_studio, hook_hunter, stuckness_detector, wonder_mode, session_continuity, creative_constraints, device_forge, sample_engine, atlas, composer, experiment, musical_intelligence.
63
+ Current: **45 domains**: transport, tracks, clips, notes, devices, scenes, mixing, browser, arrangement, memory, analyzer, automation, theory, generative, harmony, midi_io, perception, agent_os, composition, motif, research, planner, project_brain, runtime, evaluation, mix_engine, sound_design, transition_engine, reference_engine, translation_engine, performance_engine, song_brain, preview_studio, hook_hunter, stuckness_detector, wonder_mode, session_continuity, creative_constraints, device_forge, sample_engine, atlas, composer, experiment, musical_intelligence, semantic_moves.
64
64
 
65
- - [ ] All files that mention domain count say "43 domains"
66
- - [ ] Domain lists include ALL 43 (especially newer domains — they're the most often omitted)
65
+ - [ ] All files that mention domain count say "45 domains"
66
+ - [ ] Domain lists include ALL 45 (especially newer domains — they're the most often omitted)
67
67
 
68
68
  ## 4. npm Registry
69
69
 
@@ -93,8 +93,8 @@ Current: **43 domains**: transport, tracks, clips, notes, devices, scenes, mixin
93
93
 
94
94
  - [ ] `README.md` — features match current capabilities, "Coming" section is accurate
95
95
  - [ ] `docs/manual/getting-started.md` — install instructions current
96
- - [ ] `docs/manual/tool-reference.md` — all 43 domains listed, all 320 tools present
97
- - [ ] `docs/TOOL_REFERENCE.md` — all 43 domains present with correct counts
96
+ - [ ] `docs/manual/tool-reference.md` — all 45 domains listed, all 323 tools present
97
+ - [ ] `docs/TOOL_REFERENCE.md` — all 45 domains present with correct counts
98
98
  - [ ] `docs/M4L_BRIDGE.md` — architecture accurate, core/bridge counts correct
99
99
 
100
100
  ## 9. Derived Artifacts
Binary file
@@ -0,0 +1,53 @@
1
+ {
2
+ "name" : "LivePilot_Analyzer",
3
+ "version" : 1,
4
+ "creationdate" : 3923452800,
5
+ "modificationdate" : 3923452800,
6
+ "viewrect" : [ 100.0, 100.0, 300.0, 500.0 ],
7
+ "autoorganize" : 0,
8
+ "hideprojectwindow" : 0,
9
+ "showdependencies" : 1,
10
+ "autolocalize" : 0,
11
+ "contents" : {
12
+ "patchers" : {
13
+ "LivePilot_Analyzer.maxpat" : {
14
+ "kind" : "patcher",
15
+ "local" : 1,
16
+ "toplevel" : 1
17
+ }
18
+ },
19
+ "code" : {
20
+ "livepilot_bridge.js" : {
21
+ "kind" : "javascript",
22
+ "local" : 1
23
+ }
24
+ },
25
+ "externals" : {
26
+ "fluid.chroma~.mxo" : { "kind" : "maxext_darwin", "local" : 1 },
27
+ "fluid.chroma~.mxe64" : { "kind" : "maxext_win_64", "local" : 1 },
28
+ "fluid.loudness~.mxo" : { "kind" : "maxext_darwin", "local" : 1 },
29
+ "fluid.loudness~.mxe64" : { "kind" : "maxext_win_64", "local" : 1 },
30
+ "fluid.melbands~.mxo" : { "kind" : "maxext_darwin", "local" : 1 },
31
+ "fluid.melbands~.mxe64" : { "kind" : "maxext_win_64", "local" : 1 },
32
+ "fluid.noveltyfeature~.mxo" : { "kind" : "maxext_darwin", "local" : 1 },
33
+ "fluid.noveltyfeature~.mxe64" : { "kind" : "maxext_win_64", "local" : 1 },
34
+ "fluid.onsetfeature~.mxo" : { "kind" : "maxext_darwin", "local" : 1 },
35
+ "fluid.onsetfeature~.mxe64" : { "kind" : "maxext_win_64", "local" : 1 },
36
+ "fluid.spectralshape~.mxo" : { "kind" : "maxext_darwin", "local" : 1 },
37
+ "fluid.spectralshape~.mxe64" : { "kind" : "maxext_win_64", "local" : 1 }
38
+ }
39
+ },
40
+ "layout" : {
41
+
42
+ },
43
+ "searchpath" : {
44
+
45
+ },
46
+ "detailsvisible" : 0,
47
+ "amxdtype" : 1627865200,
48
+ "readonly" : 0,
49
+ "devpathtype" : 0,
50
+ "devpath" : ".",
51
+ "sortmode" : 0,
52
+ "viewmode" : 0
53
+ }
@@ -183,6 +183,13 @@ function dispatch(cmd, args) {
183
183
  case "get_plugin_presets":
184
184
  cmd_get_plugin_presets(args);
185
185
  break;
186
+ // ── BUG-A2 / A3: deep-LOM properties not on the automatable surface ──
187
+ case "simpler_set_warp":
188
+ cmd_simpler_set_warp(args);
189
+ break;
190
+ case "compressor_set_sidechain":
191
+ cmd_compressor_set_sidechain(args);
192
+ break;
186
193
  default:
187
194
  send_response({"error": "Unknown command: " + cmd});
188
195
  }
@@ -641,8 +648,13 @@ function detect_key() {
641
648
  detected_key = note_names[best_key];
642
649
  detected_scale = best_scale;
643
650
 
644
- // Send to UI
645
- outlet(1, "key", detected_key + " " + detected_scale);
651
+ // Send to UI — use abbreviated scale ("min"/"maj") so text fits in the
652
+ // 72-pixel presentation widget, and pass a SINGLE symbol so Max's
653
+ // [route] + [prepend set] chain doesn't split atoms on the internal
654
+ // space. Max's [comment] displays whatever the `set` message carries.
655
+ var scale_abbr = (detected_scale === "minor") ? "min" : "maj";
656
+ var display = detected_key + " " + scale_abbr; // e.g., "D min"
657
+ outlet(1, "key", display);
646
658
  }
647
659
 
648
660
  function correlate(a, b) {
@@ -991,6 +1003,206 @@ function cmd_simpler_warp(args) {
991
1003
  }
992
1004
  }
993
1005
 
1006
+ // ── BUG-A2: Simpler warping property + warp_mode ─────────────────────
1007
+ //
1008
+ // Python's Remote Script ControlSurface API only exposes automatable
1009
+ // parameters. Simpler's `warping` and `warp_mode` live on the sample
1010
+ // child object (SimplerDevice.sample.*) — unreachable from the Python
1011
+ // side. Max JS LiveAPI can step INTO the sample child, so we do the
1012
+ // property write here and surface the result to the MCP server.
1013
+ //
1014
+ // args: [track_index, device_index, warp_on (0/1), warp_mode (-1 = leave alone, 0..6)]
1015
+ // warp_mode: 0=Beats, 1=Tones, 2=Texture, 3=Re-Pitch, 4=Complex, 6=Complex Pro
1016
+ //
1017
+ // Returns: {ok, warping, warp_mode} on success, {error} otherwise.
1018
+ function cmd_simpler_set_warp(args) {
1019
+ var track_idx = parseInt(args[0]);
1020
+ var device_idx = parseInt(args[1]);
1021
+ var warp_on = parseInt(args[2]);
1022
+ var warp_mode = args.length > 3 ? parseInt(args[3]) : -1;
1023
+
1024
+ var device_path = build_device_path(track_idx, device_idx);
1025
+ cursor_a.goto(device_path);
1026
+ if (cursor_a.id === 0) {
1027
+ send_response({"error": "Device not found at track " + track_idx + ", device " + device_idx});
1028
+ return;
1029
+ }
1030
+ if (cursor_a.get("class_name").toString() !== "OriginalSimpler") {
1031
+ send_response({"error": "Not a Simpler device (class is " + cursor_a.get("class_name") + ")"});
1032
+ return;
1033
+ }
1034
+
1035
+ // Step into the sample child — warping + warp_mode live there, not on
1036
+ // the device itself.
1037
+ try {
1038
+ cursor_a.goto(device_path + " sample");
1039
+ if (cursor_a.id === 0) {
1040
+ send_response({"error": "Simpler has no sample loaded (warping not applicable)"});
1041
+ return;
1042
+ }
1043
+ cursor_a.set("warping", warp_on ? 1 : 0);
1044
+ if (warp_on && warp_mode >= 0) {
1045
+ cursor_a.set("warp_mode", warp_mode);
1046
+ }
1047
+ // Read back so the caller can confirm the write landed
1048
+ var read_warping = parseInt(cursor_a.get("warping"));
1049
+ var read_warp_mode = parseInt(cursor_a.get("warp_mode"));
1050
+ send_response({
1051
+ "ok": true,
1052
+ "track_index": track_idx,
1053
+ "device_index": device_idx,
1054
+ "warping": read_warping,
1055
+ "warp_mode": read_warp_mode,
1056
+ });
1057
+ } catch(e) {
1058
+ send_response({"error": "simpler_set_warp failed: " + e.message});
1059
+ }
1060
+ }
1061
+
1062
+ // ── BUG-A3: Compressor sidechain input routing ───────────────────────
1063
+ //
1064
+ // Sidechain INPUT ROUTING is exposed as LiveAPI properties on the
1065
+ // Compressor device in Live 11+: sidechain_input_routing_type and
1066
+ // sidechain_input_routing_channel. They don't appear in the automatable
1067
+ // parameter list so the Python Remote Script can't reach them; Max JS
1068
+ // LiveAPI can.
1069
+ //
1070
+ // args: [track_index, device_index, routing_type, routing_channel]
1071
+ // routing_type: string — e.g. "1-Audio From" / track name / "Ext. In"
1072
+ // routing_channel: string — "Post FX" / "Pre FX" / "Post Mixer" / ...
1073
+ //
1074
+ // Returns: {ok, sidechain: {type, channel}} on success.
1075
+ // Older Live versions without these properties return a clean error.
1076
+ function cmd_compressor_set_sidechain(args) {
1077
+ var track_idx = parseInt(args[0]);
1078
+ var device_idx = parseInt(args[1]);
1079
+ var routing_type = String(args[2] || "");
1080
+ var routing_channel = String(args[3] || "");
1081
+
1082
+ var path = build_device_path(track_idx, device_idx);
1083
+ cursor_a.goto(path);
1084
+ if (cursor_a.id === 0) {
1085
+ send_response({"error": "Device not found at track " + track_idx + ", device " + device_idx});
1086
+ return;
1087
+ }
1088
+ var class_name = String(cursor_a.get("class_name"));
1089
+ if (class_name !== "Compressor2" && class_name !== "Compressor") {
1090
+ send_response({"error": "Not a Compressor device (class is " + class_name + ")"});
1091
+ return;
1092
+ }
1093
+
1094
+ // Helper: read a LiveAPI property that returns a JSON-serialized dict
1095
+ // or list. Max's `get()` wraps results in a single-element array,
1096
+ // and complex properties come back as JSON strings.
1097
+ function read_json_prop(name) {
1098
+ try {
1099
+ var raw = cursor_a.get(name);
1100
+ if (raw === null || raw === undefined) return null;
1101
+ if (Object.prototype.toString.call(raw) === "[object Array]" && raw.length === 1) {
1102
+ raw = raw[0];
1103
+ }
1104
+ if (typeof raw === "string") {
1105
+ try { return JSON.parse(raw); } catch(e) { return raw; }
1106
+ }
1107
+ return raw;
1108
+ } catch(e) {
1109
+ return null;
1110
+ }
1111
+ }
1112
+
1113
+ function find_by_name(list, name) {
1114
+ if (!list || !list.length || !name) return null;
1115
+ for (var i = 0; i < list.length; i++) {
1116
+ var entry = list[i];
1117
+ if (!entry) continue;
1118
+ var n = entry.display_name || entry.name;
1119
+ if (n === name) return entry;
1120
+ }
1121
+ return null;
1122
+ }
1123
+
1124
+ try {
1125
+ // Enable sidechain first — Live rejects routing writes on a
1126
+ // compressor with the sidechain disabled. Property is available
1127
+ // on Live 10+. Try/catch for legacy builds.
1128
+ try { cursor_a.set("sidechain_enabled", 1); } catch(e) {}
1129
+
1130
+ var debug = {};
1131
+
1132
+ // --- Routing TYPE (the source: "1-DRUMS", "Ext. In", "No Input", …)
1133
+ if (routing_type) {
1134
+ var types = read_json_prop("available_sidechain_input_routing_types");
1135
+ debug.requested_type = routing_type;
1136
+ debug.type_count = types && types.length ? types.length : 0;
1137
+ var t_match = find_by_name(types, routing_type);
1138
+ if (t_match && t_match.identifier !== undefined) {
1139
+ // LOM expects a RoutingType object; Max JS accepts a
1140
+ // JSON-encoded {identifier: N} for the `set`.
1141
+ cursor_a.set(
1142
+ "sidechain_input_routing_type",
1143
+ JSON.stringify({identifier: t_match.identifier})
1144
+ );
1145
+ debug.set_type = "ok (identifier=" + t_match.identifier + ")";
1146
+ } else {
1147
+ debug.set_type = "FAIL: no matching type";
1148
+ if (types) {
1149
+ debug.available_types = [];
1150
+ for (var i = 0; i < types.length; i++) {
1151
+ debug.available_types.push(types[i].display_name || types[i].name || "?");
1152
+ }
1153
+ }
1154
+ }
1155
+ }
1156
+
1157
+ // --- Routing CHANNEL (the tap point: "Post FX", "Pre FX", …)
1158
+ if (routing_channel) {
1159
+ var channels = read_json_prop("available_sidechain_input_routing_channels");
1160
+ debug.requested_channel = routing_channel;
1161
+ debug.channel_count = channels && channels.length ? channels.length : 0;
1162
+ var c_match = find_by_name(channels, routing_channel);
1163
+ if (c_match && c_match.identifier !== undefined) {
1164
+ cursor_a.set(
1165
+ "sidechain_input_routing_channel",
1166
+ JSON.stringify({identifier: c_match.identifier})
1167
+ );
1168
+ debug.set_channel = "ok (identifier=" + c_match.identifier + ")";
1169
+ } else {
1170
+ debug.set_channel = "FAIL: no matching channel";
1171
+ if (channels) {
1172
+ debug.available_channels = [];
1173
+ for (var j = 0; j < channels.length; j++) {
1174
+ debug.available_channels.push(channels[j].display_name || channels[j].name || "?");
1175
+ }
1176
+ }
1177
+ }
1178
+ }
1179
+
1180
+ // Read back canonical display_name for confirmation
1181
+ var cur_type = read_json_prop("sidechain_input_routing_type");
1182
+ var cur_channel = read_json_prop("sidechain_input_routing_channel");
1183
+ var read_type_name = (cur_type && cur_type.display_name) || "";
1184
+ var read_channel_name = (cur_channel && cur_channel.display_name) || "";
1185
+
1186
+ send_response({
1187
+ "ok": true,
1188
+ "track_index": track_idx,
1189
+ "device_index": device_idx,
1190
+ "sidechain": {
1191
+ "type": read_type_name,
1192
+ "channel": read_channel_name,
1193
+ "enabled": 1
1194
+ },
1195
+ "debug": debug
1196
+ });
1197
+ } catch(e) {
1198
+ send_response({
1199
+ "error": "compressor_set_sidechain failed: " + e.message
1200
+ + " (this Live build may not expose sidechain_input_routing_* —"
1201
+ + " user must set routing manually)"
1202
+ });
1203
+ }
1204
+ }
1205
+
994
1206
  // ── Phase 2: Warp Markers ─────────────────────────────────────────────
995
1207
 
996
1208
  function cmd_get_warp_markers(args) {
package/manifest.json CHANGED
@@ -2,9 +2,9 @@
2
2
  "manifest_version": "0.3",
3
3
  "name": "livepilot",
4
4
  "display_name": "LivePilot — AI for Ableton Live",
5
- "version": "1.10.6",
6
- "description": "Agentic production system for Ableton Live 12. Make beats, mix tracks, design sounds, and arrange songs with 320 AI-powered tools.",
7
- "long_description": "LivePilot is an agentic production system for Ableton Live 12. 320 tools across 43 domains — device atlas (1305 devices), sample intelligence (Splice + browser + filesystem), auto-composition, spectral perception, technique memory, and 12 creative engines.\n\n**What it does:**\n- Creates MIDI clips with notes, chords, and rhythms\n- Loads instruments and effects via Device Atlas (1305 devices indexed)\n- Searches samples across Splice, Ableton browser, and filesystem\n- Plans compositions from text prompts with genre-aware layering\n- Slices samples with intent-based MIDI generation\n- Mixes with volume, panning, sends, and automation\n- Analyzes your mix with real-time spectral data (M4L bridge)\n- Diagnoses stuck sessions and generates creative rescue variants\n- Remembers your production style across sessions\n\n**How it works:**\nLivePilot installs a Remote Script in Ableton that communicates with the AI over a local TCP connection. Everything runs on your machine — no audio leaves your computer.",
5
+ "version": "1.10.7",
6
+ "description": "Agentic production system for Ableton Live 12. Make beats, mix tracks, design sounds, and arrange songs with 323 AI-powered tools.",
7
+ "long_description": "LivePilot is an agentic production system for Ableton Live 12. 323 tools across 45 domains — device atlas (1305 devices), sample intelligence (Splice + browser + filesystem), auto-composition, spectral perception, technique memory, and 12 creative engines.\n\n**What it does:**\n- Creates MIDI clips with notes, chords, and rhythms\n- Loads instruments and effects via Device Atlas (1305 devices indexed)\n- Searches samples across Splice, Ableton browser, and filesystem\n- Plans compositions from text prompts with genre-aware layering\n- Slices samples with intent-based MIDI generation\n- Mixes with volume, panning, sends, and automation\n- Analyzes your mix with real-time spectral data (M4L bridge)\n- Diagnoses stuck sessions and generates creative rescue variants\n- Remembers your production style across sessions\n\n**How it works:**\nLivePilot installs a Remote Script in Ableton that communicates with the AI over a local TCP connection. Everything runs on your machine — no audio leaves your computer.",
8
8
  "author": {
9
9
  "name": "Pilot Studio",
10
10
  "url": "https://github.com/dreamrec/LivePilot"
@@ -1,2 +1,2 @@
1
1
  """LivePilot MCP Server — bridges MCP protocol to Ableton Live."""
2
- __version__ = "1.10.6"
2
+ __version__ = "1.10.7"