livepilot 1.21.3 → 1.22.0
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/CHANGELOG.md +210 -0
- package/README.md +1 -1
- package/m4l_device/LivePilot_Analyzer.amxd +0 -0
- package/mcp_server/__init__.py +1 -1
- package/mcp_server/atlas/__init__.py +52 -5
- package/mcp_server/atlas/tools.py +8 -2
- package/package.json +1 -1
- package/remote_script/LivePilot/__init__.py +1 -1
- package/server.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,215 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.22.0 — User atlas separation: ~/.livepilot/atlas/ (April 25 2026)
|
|
4
|
+
|
|
5
|
+
First v1.22 release. Splits the device atlas into two files that serve
|
|
6
|
+
different roles — a long-standing ambiguity that finally bit hard enough
|
|
7
|
+
to be worth fixing at minor-version scope.
|
|
8
|
+
|
|
9
|
+
### What changed
|
|
10
|
+
|
|
11
|
+
**New: `~/.livepilot/atlas/device_atlas.json`** — the **user atlas**.
|
|
12
|
+
Written by `scan_full_library` on your machine. Reflects YOUR installed
|
|
13
|
+
packs, User Library, and plugins. Lives in the user-data directory
|
|
14
|
+
(same convention as `~/.livepilot/memory/`) so `npm install livepilot`
|
|
15
|
+
upgrades can't blow it away.
|
|
16
|
+
|
|
17
|
+
**Unchanged: `mcp_server/atlas/device_atlas.json`** — the **bundled
|
|
18
|
+
baseline**. Ships with the package (still 5264 devices, 120 enriched
|
|
19
|
+
— stock Ableton 12 Suite inventory). Gives fresh installs a functional
|
|
20
|
+
atlas before any personalized scan has run.
|
|
21
|
+
|
|
22
|
+
**Resolution** at load time: user atlas wins if present, else bundled
|
|
23
|
+
baseline falls through. Writes **always** go to the user path; the
|
|
24
|
+
bundled path is read-only from the scanner's perspective.
|
|
25
|
+
|
|
26
|
+
### Why this matters
|
|
27
|
+
|
|
28
|
+
Prior to v1.22.0, the single `mcp_server/atlas/device_atlas.json` file
|
|
29
|
+
served three conflicting roles — repo seed, personal scan cache, and
|
|
30
|
+
runtime index. Three bugs resulted:
|
|
31
|
+
|
|
32
|
+
1. **`npm install livepilot` wiped personal scans.** Every package
|
|
33
|
+
update overwrote the installed atlas with the bundled baseline. Users
|
|
34
|
+
who had carefully scanned their library (30-90 seconds per scan) lost
|
|
35
|
+
that work on every upgrade with no warning.
|
|
36
|
+
2. **Dev installs polluted the repo.** Contributors running
|
|
37
|
+
LivePilot from a git checkout would scan their library (to test atlas
|
|
38
|
+
tools against live Ableton) and accidentally commit their personal
|
|
39
|
+
scan — pack names, user-library previews — to the public repo. This
|
|
40
|
+
happened once in the v1.21.x cycle and was the proximate trigger for
|
|
41
|
+
v1.22.
|
|
42
|
+
3. **The "enriched" count ambiguity.** A single atlas file couldn't
|
|
43
|
+
honestly answer "how many devices are enriched?" — the right number
|
|
44
|
+
differed depending on whether you meant the bundled baseline (87 per
|
|
45
|
+
the scanner's last truncated pass), YAML files authored on disk (120),
|
|
46
|
+
or runtime coverage including native/M4L duplicates (137+ on a
|
|
47
|
+
fully-scanned install). The user/bundled split clarifies this by
|
|
48
|
+
letting each file carry its own honest count.
|
|
49
|
+
|
|
50
|
+
### Migration for existing users
|
|
51
|
+
|
|
52
|
+
Users with a personalized scan in `mcp_server/atlas/device_atlas.json`
|
|
53
|
+
(most dev-install contributors) can migrate in one command:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
mkdir -p ~/.livepilot/atlas
|
|
57
|
+
cp "$(python3 -c 'import mcp_server.atlas; print(mcp_server.atlas.BUNDLED_ATLAS_PATH)')" \
|
|
58
|
+
~/.livepilot/atlas/device_atlas.json
|
|
59
|
+
# Then optionally restore the bundled baseline to its shipped state:
|
|
60
|
+
git -C $(python3 -c 'import mcp_server.atlas, pathlib; print(pathlib.Path(mcp_server.atlas.__file__).parents[2])') \
|
|
61
|
+
checkout mcp_server/atlas/device_atlas.json
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Users on the npm-installed path (no personalized scan yet) need nothing
|
|
65
|
+
— the next `scan_full_library` call will write to the new user path
|
|
66
|
+
automatically.
|
|
67
|
+
|
|
68
|
+
### Code changes
|
|
69
|
+
|
|
70
|
+
- `mcp_server/atlas/__init__.py` — new module-level constants
|
|
71
|
+
`BUNDLED_ATLAS_PATH`, `USER_ATLAS_DIR`, `USER_ATLAS_PATH`, and
|
|
72
|
+
function `_resolve_atlas_path()`. Existing `ATLAS_PATH` kept as a
|
|
73
|
+
backward-compat alias pointing at the resolved value.
|
|
74
|
+
- `mcp_server/atlas/tools.py::scan_full_library` — writes to
|
|
75
|
+
`USER_ATLAS_PATH` and creates the user-data directory on demand.
|
|
76
|
+
Enrichments still read from the bundled package (they're authored
|
|
77
|
+
in-repo under `mcp_server/atlas/enrichments/`).
|
|
78
|
+
|
|
79
|
+
### Tests
|
|
80
|
+
|
|
81
|
+
8 new TDD regression tests in `tests/test_atlas_user_override.py`:
|
|
82
|
+
|
|
83
|
+
- `test_bundled_path_is_in_package_dir`
|
|
84
|
+
- `test_user_path_is_in_home_dir`
|
|
85
|
+
- `test_resolver_returns_user_path_when_present`
|
|
86
|
+
- `test_resolver_falls_back_to_bundled_when_user_atlas_missing`
|
|
87
|
+
- `test_atlas_manager_loads_from_user_path_when_present`
|
|
88
|
+
- `test_atlas_manager_falls_back_to_bundled_when_user_atlas_missing`
|
|
89
|
+
- `test_scan_full_library_writes_to_user_path`
|
|
90
|
+
- `test_user_atlas_dir_created_if_missing`
|
|
91
|
+
|
|
92
|
+
Full suite: 3136 pass (3128 prior + 8 new), 1 skipped.
|
|
93
|
+
|
|
94
|
+
### Documentation
|
|
95
|
+
|
|
96
|
+
- `docs/manual/getting-started.md` — new "Step 5 (optional): Personalize
|
|
97
|
+
the device atlas" section.
|
|
98
|
+
- `docs/manual/dev-install.md` — new "3a. User atlas vs bundled atlas"
|
|
99
|
+
subsection, critical for contributors.
|
|
100
|
+
- `docs/manual/device-atlas.md` — header callout on the two-file split.
|
|
101
|
+
- `CLAUDE.md` + `README.md` — short pointers to the new resolver.
|
|
102
|
+
|
|
103
|
+
### Carried to future releases
|
|
104
|
+
|
|
105
|
+
The atlas schema-canonicalization originally deferred from the v1.21.2
|
|
106
|
+
audit is now **partially closed**: the user/bundled split makes the
|
|
107
|
+
"which number counts as enriched?" question honest per-file, but the
|
|
108
|
+
sync_metadata gate for `stats.enriched_devices` vs YAML file count
|
|
109
|
+
hasn't been added. Deferred to a future patch because it's orthogonal
|
|
110
|
+
to the user-atlas split.
|
|
111
|
+
|
|
112
|
+
## 1.21.4 — v1.21.2 audit carry-over: slashed-compound filler + dev-install runbook (April 25 2026)
|
|
113
|
+
|
|
114
|
+
Ships two items the v1.21.2 audit #2 deferred to v1.22 but that turned
|
|
115
|
+
out to be safer to close in a patch cycle than to carry forward:
|
|
116
|
+
|
|
117
|
+
1. **`check_prose_claim` regex widen for slashed/chained compound fillers** —
|
|
118
|
+
`"38 spectral/analyzer tools"` drift across 3 docs silently passed
|
|
119
|
+
`sync_metadata --check` because the filler group required trailing
|
|
120
|
+
whitespace. Now caught.
|
|
121
|
+
2. **Dev-install runbook** (`docs/manual/dev-install.md`) — documented
|
|
122
|
+
path for contributors to run LivePilot from a local checkout without
|
|
123
|
+
publishing to npm. Previously every contributor had to reverse-engineer
|
|
124
|
+
this from `bin/livepilot.js` + `mcp_server/__main__.py`.
|
|
125
|
+
|
|
126
|
+
No API changes. No user-observable behavior change at runtime. Four new
|
|
127
|
+
TDD regression tests for the regex widening; ~180 lines of new
|
|
128
|
+
documentation. `sync_metadata --check` now catches an entire class of
|
|
129
|
+
compound-form drift that would otherwise have shipped untracked.
|
|
130
|
+
|
|
131
|
+
### 1. `sync_metadata` slashed/chained compound filler
|
|
132
|
+
|
|
133
|
+
All 4 regex patterns in `scripts/sync_metadata.py` (`check_tool_count`,
|
|
134
|
+
`check_prose_claim`, `fix_tool_count`, `_fix_count`) had an optional
|
|
135
|
+
filler group that required trailing whitespace —
|
|
136
|
+
`[A-Za-z]+\s+` — and matched at most once (`?` quantifier). Slashed
|
|
137
|
+
compounds like `"spectral/analyzer"` were rejected because `/` is not
|
|
138
|
+
whitespace; chained compounds like `"spectral/MCP tools"` (two filler
|
|
139
|
+
segments) were rejected because of the single-match quantifier.
|
|
140
|
+
|
|
141
|
+
v1.21.4 widens the filler to two branches, iterable 0+ times:
|
|
142
|
+
|
|
143
|
+
| Branch | Pattern | Matches |
|
|
144
|
+
|---|---|---|
|
|
145
|
+
| (a) Space-joined, uppercase-anchored | `[A-Z][A-Za-z\-]*\s+` | `"MCP "` in `"430 MCP Tools"` |
|
|
146
|
+
| (b) Slash-joined, any-case | `[A-Za-z][A-Za-z\-]*/` | `"spectral/"` in `"38 spectral/analyzer tools"` |
|
|
147
|
+
|
|
148
|
+
The uppercase anchor on branch (a) is preserved deliberately — without
|
|
149
|
+
it, lowercase English articles ("the tool") would false-positive on
|
|
150
|
+
prose like "released in 2020 the tool was first previewed." The slash
|
|
151
|
+
on branch (b) is itself an unambiguous compound marker that doesn't
|
|
152
|
+
appear in normal English, so any-case there is safe. The `*` quantifier
|
|
153
|
+
lets branches chain: `"300 spectral/MCP tools"` now parses as
|
|
154
|
+
`(b)"spectral/"` + `(a)"MCP "` + `"tools"`.
|
|
155
|
+
|
|
156
|
+
For `check_prose_claim` + its paired `_fix_count`, the filler is a
|
|
157
|
+
simpler single-branch `[A-Za-z][A-Za-z\-]*(?:/|\s+)` — these don't need
|
|
158
|
+
the uppercase anchor (prose-claim nouns predate the v1.21.4 cycle and
|
|
159
|
+
already allowed lowercase-start fillers).
|
|
160
|
+
|
|
161
|
+
**Concrete effect**: `sync_metadata --check` now flags drift in all 3
|
|
162
|
+
real surfaces that previously escaped:
|
|
163
|
+
|
|
164
|
+
- `README.md` — `"38 spectral/analyzer tools"` × 2
|
|
165
|
+
- `docs/manual/getting-started.md` — `"38 spectral/analyzer tools"` × 1
|
|
166
|
+
- `livepilot/skills/livepilot-release/SKILL.md` — `"38 spectral/analyzer tools"` × 1
|
|
167
|
+
|
|
168
|
+
(Today these say "38" and the count is 38, so no drift reported — but
|
|
169
|
+
the next time the analyzer module gains or loses a `@mcp.tool`, CI will
|
|
170
|
+
fail loudly instead of silently drifting.)
|
|
171
|
+
|
|
172
|
+
Tests added to `tests/test_claim_consistency.py` (4):
|
|
173
|
+
|
|
174
|
+
- `test_prose_claim_catches_slashed_compound` — drift detection
|
|
175
|
+
- `test_fix_count_rewrites_slashed_compound` — `--fix` preserves the adjective
|
|
176
|
+
- `test_tool_count_catches_slashed_compound` — chained filler (`"300 spectral/MCP tools"`)
|
|
177
|
+
- `test_tool_count_no_false_positive_on_year_prose` — uppercase anchor guard
|
|
178
|
+
|
|
179
|
+
### 2. Dev-install runbook
|
|
180
|
+
|
|
181
|
+
New file `docs/manual/dev-install.md` (~180 lines) documents the
|
|
182
|
+
bare-python local-checkout workflow for contributors:
|
|
183
|
+
|
|
184
|
+
1. **venv setup** — `python3 -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt`
|
|
185
|
+
2. **Local Remote Script install** — `node bin/livepilot.js --install` (NOT `npx livepilot --install`, which resolves to the registry and silently discards local edits)
|
|
186
|
+
3. **MCP client config pointing at `python -m mcp_server`** — per-client examples for Claude Desktop, Claude Code, Cursor/VS Code
|
|
187
|
+
4. **Iterate loop** — client restart for `mcp_server/` edits; `node bin/livepilot.js --install` + `reload_handlers` tool for `remote_script/` edits
|
|
188
|
+
5. **Test suite** — `python -m pytest tests/ -q` (3128 tests as of v1.21.4)
|
|
189
|
+
6. **`sync_metadata` drift check** — `python scripts/sync_metadata.py --check` / `--fix`
|
|
190
|
+
7. **Going back to published** — remove the dev MCP entry or stop using it
|
|
191
|
+
|
|
192
|
+
Plus a troubleshooting section for the 4 most common first-run failures:
|
|
193
|
+
`ModuleNotFoundError: No module named 'mcp_server'`, `Another client is
|
|
194
|
+
already connected` on port 9878, stale `__pycache__` shadowing edits, and
|
|
195
|
+
module-level constants not reloading via `reload_handlers` (full Ableton
|
|
196
|
+
restart required).
|
|
197
|
+
|
|
198
|
+
Cross-links added:
|
|
199
|
+
|
|
200
|
+
- `docs/manual/getting-started.md` — callout at top routing contributors to dev-install before they commit to the npm path
|
|
201
|
+
- `docs/manual/index.md` — new "Contributing" section in the Chapters TOC
|
|
202
|
+
- `CLAUDE.md` — pointer in the Project section
|
|
203
|
+
|
|
204
|
+
### Carried forward to v1.22
|
|
205
|
+
|
|
206
|
+
Still deferred from the v1.21.2 audit:
|
|
207
|
+
|
|
208
|
+
- Atlas `.enriched` schema canonicalization (`stats.enriched_devices = 87`
|
|
209
|
+
vs 120 YAML files vs 135 historical claim — pick one and derive the
|
|
210
|
+
others at build time; add a sync_metadata gate matching JSON stats to
|
|
211
|
+
YAML file count)
|
|
212
|
+
|
|
3
213
|
## 1.21.3 — Third audit-response: manual-docs drift + sync_metadata file-list widening + unicode-escape regex fix (April 24 2026)
|
|
4
214
|
|
|
5
215
|
Fourth same-day patch in 48 hours, third audit-response in 24 hours.
|
package/README.md
CHANGED
|
@@ -105,7 +105,7 @@ Most MCP servers are tool collections — they execute commands. LivePilot is an
|
|
|
105
105
|
|
|
106
106
|
**M4L Bridge** (`m4l_device/`) — Optional Max for Live Audio Effect on the master track. Provides deep LOM access through Max's LiveAPI that the ControlSurface API can't reach. UDP 9880 (M4L to server) carries spectral data and LiveAPI responses. OSC 9881 (server to M4L) sends commands. The 38 spectral/analyzer tools strictly require the bridge; device and sample tools that call the bridge also have graceful fallbacks, so core functionality works without it. Backed by 31 bridge commands for hidden parameters, Simpler internals, warp markers, display values, and Simpler warp / Compressor sidechain writes that live on child objects Python can't reach.
|
|
107
107
|
|
|
108
|
-
**Device Atlas** (`mcp_server/atlas/`) — In-memory indexed JSON database. 5264 devices with browser URIs, 120 enriched with YAML sonic intelligence profiles (mood, genre, texture, recommended chains). 7 indexes: by_id, by_name, by_uri, by_category, by_tag, by_genre, by_pack. Reverse-index `device_techniques_index.json` powers `atlas_techniques_for_device` (146 cross-references across 58 devices). The AI never hallucinates a device name or preset — it always resolves against the atlas first.
|
|
108
|
+
**Device Atlas** (`mcp_server/atlas/`) — In-memory indexed JSON database. 5264 devices with browser URIs (bundled baseline), 120 enriched with YAML sonic intelligence profiles (mood, genre, texture, recommended chains). 7 indexes: by_id, by_name, by_uri, by_category, by_tag, by_genre, by_pack. Reverse-index `device_techniques_index.json` powers `atlas_techniques_for_device` (146 cross-references across 58 devices). The AI never hallucinates a device name or preset — it always resolves against the atlas first. **v1.22.0+**: run `scan_full_library` after install to index YOUR packs + User Library + plugins into `~/.livepilot/atlas/device_atlas.json` — your personal atlas overrides the baseline and survives npm updates.
|
|
109
109
|
|
|
110
110
|
**Sample Engine** (`mcp_server/sample_engine/`) — Searches three sources simultaneously: BrowserSource (Ableton's library), SpliceSource (local Splice catalog via SQLite), FilesystemSource (user directories). Every result passes through a 6-critic fitness battery (key, tempo, spectral, genre, mood, technical). 29 processing techniques (Surgeon precision vs. Alchemist experimentation). Builds complete sample processing plans with warp, slice, and effect recommendations.
|
|
111
111
|
|
|
Binary file
|
package/mcp_server/__init__.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""LivePilot MCP Server — bridges MCP protocol to Ableton Live."""
|
|
2
|
-
__version__ = "1.
|
|
2
|
+
__version__ = "1.22.0"
|
|
@@ -519,28 +519,75 @@ class AtlasManager:
|
|
|
519
519
|
from pathlib import Path
|
|
520
520
|
from ..services.singletons import Singleton
|
|
521
521
|
|
|
522
|
-
|
|
522
|
+
# v1.22.0: the atlas now has TWO possible homes —
|
|
523
|
+
#
|
|
524
|
+
# BUNDLED_ATLAS_PATH — mcp_server/atlas/device_atlas.json
|
|
525
|
+
# Ships with the package. Gives fresh installs a functional
|
|
526
|
+
# baseline device index before any personalized scan has run.
|
|
527
|
+
# Updated only when the repo's canonical baseline is regenerated.
|
|
528
|
+
#
|
|
529
|
+
# USER_ATLAS_PATH — ~/.livepilot/atlas/device_atlas.json
|
|
530
|
+
# Written by scan_full_library on the user's machine. Reflects
|
|
531
|
+
# their actual installed packs, User Library, and plugins. Lives
|
|
532
|
+
# in the user-data directory (same convention as
|
|
533
|
+
# ~/.livepilot/memory/) so npm updates can't blow it away.
|
|
534
|
+
#
|
|
535
|
+
# Resolution order at load time: user atlas wins if present, else
|
|
536
|
+
# bundled baseline. Written scans ALWAYS go to the user path — never
|
|
537
|
+
# the bundled path — so the repo/npm package stays clean regardless of
|
|
538
|
+
# where a user runs scan_full_library from. This split lands in v1.22.0
|
|
539
|
+
# and solves three prior issues (see tests/test_atlas_user_override.py
|
|
540
|
+
# for the full rationale).
|
|
541
|
+
BUNDLED_ATLAS_PATH = Path(__file__).parent / "device_atlas.json"
|
|
542
|
+
USER_ATLAS_DIR = Path.home() / ".livepilot" / "atlas"
|
|
543
|
+
USER_ATLAS_PATH = USER_ATLAS_DIR / "device_atlas.json"
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
def _resolve_atlas_path() -> Path:
|
|
547
|
+
"""Return the effective atlas path — user if present, bundled if not.
|
|
548
|
+
|
|
549
|
+
Called from _build_atlas and get_atlas. Kept as a module-level
|
|
550
|
+
function (rather than inlined) so tests can monkeypatch HOME and
|
|
551
|
+
reimport the module to re-evaluate USER_ATLAS_PATH cleanly.
|
|
552
|
+
"""
|
|
553
|
+
if USER_ATLAS_PATH.exists():
|
|
554
|
+
return USER_ATLAS_PATH
|
|
555
|
+
return BUNDLED_ATLAS_PATH
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
# Backward-compat alias. External code that imported ATLAS_PATH before
|
|
559
|
+
# v1.22.0 (e.g. pre-existing scripts outside this repo) gets the
|
|
560
|
+
# resolved path. Internal code should call _resolve_atlas_path() so the
|
|
561
|
+
# value is re-evaluated after the user first runs scan_full_library.
|
|
562
|
+
ATLAS_PATH = _resolve_atlas_path()
|
|
523
563
|
|
|
524
564
|
_atlas_instance: Optional[AtlasManager] = None # kept for legacy imports
|
|
525
565
|
|
|
526
566
|
|
|
527
567
|
def _build_atlas() -> AtlasManager:
|
|
528
|
-
return AtlasManager(str(
|
|
568
|
+
return AtlasManager(str(_resolve_atlas_path()))
|
|
529
569
|
|
|
530
570
|
|
|
531
571
|
_atlas_holder = Singleton(_build_atlas)
|
|
532
572
|
|
|
533
573
|
|
|
534
574
|
def get_atlas() -> AtlasManager:
|
|
535
|
-
"""Thread-safe accessor. Re-reads
|
|
575
|
+
"""Thread-safe accessor. Re-reads the resolved atlas path if its
|
|
576
|
+
mtime advanced. Uses the resolver, so if the user's first
|
|
577
|
+
scan_full_library call runs mid-session, the next get_atlas()
|
|
578
|
+
picks up the new user path (via invalidate_atlas, which
|
|
579
|
+
scan_full_library already calls on success)."""
|
|
536
580
|
global _atlas_instance
|
|
537
|
-
instance = _atlas_holder.get(reload_if_newer=
|
|
581
|
+
instance = _atlas_holder.get(reload_if_newer=_resolve_atlas_path())
|
|
538
582
|
_atlas_instance = instance # keep legacy attribute in sync
|
|
539
583
|
return instance
|
|
540
584
|
|
|
541
585
|
|
|
542
586
|
def invalidate_atlas() -> None:
|
|
543
|
-
"""Force the next get_atlas() to re-read
|
|
587
|
+
"""Force the next get_atlas() to re-read the resolved atlas path
|
|
588
|
+
from disk. Called by scan_full_library after writing a fresh
|
|
589
|
+
user atlas so subsequent tool calls see the new data without
|
|
590
|
+
an MCP server restart."""
|
|
544
591
|
global _atlas_instance
|
|
545
592
|
_atlas_holder.invalidate()
|
|
546
593
|
_atlas_instance = None
|
|
@@ -466,11 +466,17 @@ def scan_full_library(
|
|
|
466
466
|
"""
|
|
467
467
|
from .scanner import normalize_scan_results
|
|
468
468
|
from .enrichments import load_enrichments, merge_enrichments
|
|
469
|
-
from . import AtlasManager
|
|
469
|
+
from . import AtlasManager, USER_ATLAS_DIR, USER_ATLAS_PATH
|
|
470
470
|
|
|
471
|
+
# v1.22.0: scans always write to the user atlas path, never the
|
|
472
|
+
# bundled baseline. The user-data directory is created on demand
|
|
473
|
+
# so a brand-new install (no ~/.livepilot/ at all) still works.
|
|
474
|
+
# Enrichments are read from the bundled package (same as before —
|
|
475
|
+
# they're authored in-repo).
|
|
471
476
|
atlas_dir = os.path.dirname(os.path.abspath(__file__))
|
|
472
|
-
atlas_path = os.path.join(atlas_dir, "device_atlas.json")
|
|
473
477
|
enrichments_dir = os.path.join(atlas_dir, "enrichments")
|
|
478
|
+
USER_ATLAS_DIR.mkdir(parents=True, exist_ok=True)
|
|
479
|
+
atlas_path = str(USER_ATLAS_PATH)
|
|
474
480
|
|
|
475
481
|
if not force and os.path.exists(atlas_path):
|
|
476
482
|
age = time.time() - os.path.getmtime(atlas_path)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "livepilot",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.22.0",
|
|
4
4
|
"mcpName": "io.github.dreamrec/livepilot",
|
|
5
5
|
"description": "Agentic production system for Ableton Live 12 — 430 tools, 53 domains, 44 semantic moves. Device atlas (5264 devices, 120 enriched, 7 indexes), Splice intelligence (gRPC + GraphQL describe-a-sound + preview + collections + presets), 9-band spectral perception auto-loaded via ensure_analyzer_on_master, Creative Director skill, technique memory, 12 creative intelligence engines",
|
|
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.
|
|
8
|
+
__version__ = "1.22.0"
|
|
9
9
|
|
|
10
10
|
from _Framework.ControlSurface import ControlSurface
|
|
11
11
|
from . import router
|
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/dreamrec/LivePilot",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "1.
|
|
9
|
+
"version": "1.22.0",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "livepilot",
|
|
14
|
-
"version": "1.
|
|
14
|
+
"version": "1.22.0",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
}
|