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.
- package/.claude-plugin/marketplace.json +3 -3
- package/.mcp.json.disabled +9 -0
- package/.mcpbignore +3 -0
- package/AGENTS.md +3 -3
- package/BUGS.md +1570 -0
- package/CHANGELOG.md +42 -0
- package/CONTRIBUTING.md +1 -1
- package/README.md +7 -7
- package/bin/livepilot.js +28 -8
- package/livepilot/.Codex-plugin/plugin.json +2 -2
- package/livepilot/.claude-plugin/plugin.json +2 -2
- package/livepilot/skills/livepilot-core/SKILL.md +4 -4
- package/livepilot/skills/livepilot-core/references/overview.md +2 -2
- package/livepilot/skills/livepilot-release/SKILL.md +8 -8
- package/m4l_device/LivePilot_Analyzer.amxd +0 -0
- package/m4l_device/LivePilot_Analyzer.amxd.pre-presentation-backup +0 -0
- package/m4l_device/LivePilot_Analyzer.maxproj +53 -0
- package/m4l_device/livepilot_bridge.js +214 -2
- package/manifest.json +3 -3
- package/mcp_server/__init__.py +1 -1
- package/mcp_server/atlas/__init__.py +93 -26
- package/mcp_server/creative_constraints/tools.py +206 -33
- package/mcp_server/experiment/engine.py +7 -9
- package/mcp_server/hook_hunter/analyzer.py +62 -9
- package/mcp_server/hook_hunter/tools.py +60 -9
- package/mcp_server/m4l_bridge.py +21 -6
- package/mcp_server/musical_intelligence/detectors.py +32 -0
- package/mcp_server/performance_engine/tools.py +112 -29
- package/mcp_server/preview_studio/engine.py +89 -8
- package/mcp_server/preview_studio/tools.py +22 -6
- package/mcp_server/project_brain/automation_graph.py +71 -19
- package/mcp_server/project_brain/builder.py +2 -0
- package/mcp_server/project_brain/tools.py +55 -5
- package/mcp_server/reference_engine/profile_builder.py +129 -3
- package/mcp_server/reference_engine/tools.py +47 -6
- package/mcp_server/runtime/execution_router.py +50 -0
- package/mcp_server/runtime/mcp_dispatch.py +75 -3
- package/mcp_server/runtime/remote_commands.py +4 -2
- package/mcp_server/sample_engine/analyzer.py +131 -4
- package/mcp_server/sample_engine/critics.py +29 -8
- package/mcp_server/sample_engine/models.py +20 -1
- package/mcp_server/sample_engine/tools.py +48 -14
- package/mcp_server/semantic_moves/sound_design_compilers.py +22 -59
- package/mcp_server/semantic_moves/transition_compilers.py +12 -19
- package/mcp_server/server.py +68 -2
- package/mcp_server/session_continuity/models.py +4 -0
- package/mcp_server/session_continuity/tracker.py +14 -1
- package/mcp_server/song_brain/builder.py +110 -12
- package/mcp_server/song_brain/tools.py +77 -13
- package/mcp_server/sound_design/tools.py +112 -1
- package/mcp_server/stuckness_detector/detector.py +90 -0
- package/mcp_server/stuckness_detector/tools.py +41 -0
- package/mcp_server/tools/_agent_os_engine/critics.py +24 -0
- package/mcp_server/tools/_composition_engine/__init__.py +2 -2
- package/mcp_server/tools/_composition_engine/harmony.py +90 -0
- package/mcp_server/tools/_composition_engine/sections.py +47 -4
- package/mcp_server/tools/_harmony_engine.py +52 -8
- package/mcp_server/tools/_research_engine.py +98 -19
- package/mcp_server/tools/_theory_engine.py +138 -9
- package/mcp_server/tools/agent_os.py +20 -3
- package/mcp_server/tools/analyzer.py +98 -0
- package/mcp_server/tools/clips.py +45 -0
- package/mcp_server/tools/composition.py +66 -23
- package/mcp_server/tools/devices.py +22 -1
- package/mcp_server/tools/harmony.py +115 -14
- package/mcp_server/tools/midi_io.py +13 -1
- package/mcp_server/tools/mixing.py +35 -1
- package/mcp_server/tools/motif.py +49 -3
- package/mcp_server/tools/research.py +24 -0
- package/mcp_server/tools/theory.py +108 -16
- package/mcp_server/transition_engine/critics.py +18 -11
- package/package.json +2 -2
- package/remote_script/LivePilot/__init__.py +57 -2
- package/remote_script/LivePilot/clips.py +69 -0
- package/remote_script/LivePilot/mixing.py +117 -0
- package/remote_script/LivePilot/router.py +13 -1
- package/scripts/generate_tool_catalog.py +13 -38
- 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 **
|
|
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
|
-
|
|
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
|
-
│ │
|
|
83
|
-
│ │
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
412
|
-
|
|
413
|
-
|
|
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",
|
|
435
|
+
console.log("Location: %s", candidateDir);
|
|
419
436
|
return;
|
|
420
437
|
} catch {}
|
|
421
438
|
}
|
|
422
|
-
console.log("FluCoMa already installed at %s",
|
|
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.
|
|
4
|
-
"description": "Agentic production system for Ableton Live 12 —
|
|
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.
|
|
4
|
-
"description": "Agentic production system for Ableton Live 12 —
|
|
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.
|
|
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.
|
|
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
|
|
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
|
|
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.
|
|
1
|
+
# LivePilot v1.10.7 — Architecture & Tool Reference
|
|
2
2
|
|
|
3
|
-
Agentic production system for Ableton Live 12.
|
|
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: **
|
|
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 ("
|
|
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` → "
|
|
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: **
|
|
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 "
|
|
66
|
-
- [ ] Domain lists include ALL
|
|
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
|
|
97
|
-
- [ ] `docs/TOOL_REFERENCE.md` — all
|
|
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
|
|
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
|
-
|
|
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
|
-
"description": "Agentic production system for Ableton Live 12. Make beats, mix tracks, design sounds, and arrange songs with
|
|
7
|
-
"long_description": "LivePilot is an agentic production system for Ableton Live 12.
|
|
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"
|
package/mcp_server/__init__.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""LivePilot MCP Server — bridges MCP protocol to Ableton Live."""
|
|
2
|
-
__version__ = "1.10.
|
|
2
|
+
__version__ = "1.10.7"
|