livepilot 1.8.1 → 1.8.2
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 +21 -0
- package/CHANGELOG.md +8 -0
- package/livepilot/.claude-plugin/plugin.json +8 -0
- package/{plugin → livepilot}/skills/livepilot-release/SKILL.md +6 -6
- package/m4l_device/LivePilot_Analyzer.amxd +0 -0
- package/m4l_device/LivePilot_Analyzer.maxpat +172 -16
- package/m4l_device/livepilot_bridge.js +1 -1
- package/mcp_server/__init__.py +1 -1
- package/mcp_server/m4l_bridge.py +8 -6
- package/mcp_server/server.py +48 -2
- package/package.json +1 -1
- package/remote_script/LivePilot/__init__.py +1 -1
- package/plugin/plugin.json +0 -20
- /package/{plugin → livepilot}/agents/livepilot-producer/AGENT.md +0 -0
- /package/{plugin → livepilot}/commands/beat.md +0 -0
- /package/{plugin → livepilot}/commands/memory.md +0 -0
- /package/{plugin → livepilot}/commands/mix.md +0 -0
- /package/{plugin → livepilot}/commands/session.md +0 -0
- /package/{plugin → livepilot}/commands/sounddesign.md +0 -0
- /package/{plugin → livepilot}/skills/livepilot-core/SKILL.md +0 -0
- /package/{plugin → livepilot}/skills/livepilot-core/references/ableton-workflow-patterns.md +0 -0
- /package/{plugin → livepilot}/skills/livepilot-core/references/automation-atlas.md +0 -0
- /package/{plugin → livepilot}/skills/livepilot-core/references/device-atlas/00-index.md +0 -0
- /package/{plugin → livepilot}/skills/livepilot-core/references/device-atlas/distortion-and-character.md +0 -0
- /package/{plugin → livepilot}/skills/livepilot-core/references/device-atlas/drums-and-percussion.md +0 -0
- /package/{plugin → livepilot}/skills/livepilot-core/references/device-atlas/dynamics-and-punch.md +0 -0
- /package/{plugin → livepilot}/skills/livepilot-core/references/device-atlas/eq-and-filtering.md +0 -0
- /package/{plugin → livepilot}/skills/livepilot-core/references/device-atlas/midi-tools.md +0 -0
- /package/{plugin → livepilot}/skills/livepilot-core/references/device-atlas/movement-and-modulation.md +0 -0
- /package/{plugin → livepilot}/skills/livepilot-core/references/device-atlas/space-and-depth.md +0 -0
- /package/{plugin → livepilot}/skills/livepilot-core/references/device-atlas/spectral-and-weird.md +0 -0
- /package/{plugin → livepilot}/skills/livepilot-core/references/device-atlas/synths-native.md +0 -0
- /package/{plugin → livepilot}/skills/livepilot-core/references/m4l-devices.md +0 -0
- /package/{plugin → livepilot}/skills/livepilot-core/references/memory-guide.md +0 -0
- /package/{plugin → livepilot}/skills/livepilot-core/references/midi-recipes.md +0 -0
- /package/{plugin → livepilot}/skills/livepilot-core/references/mixing-patterns.md +0 -0
- /package/{plugin → livepilot}/skills/livepilot-core/references/overview.md +0 -0
- /package/{plugin → livepilot}/skills/livepilot-core/references/sound-design.md +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
|
|
3
|
+
"name": "dreamrec-LivePilot",
|
|
4
|
+
"description": "Agentic MCP production system for Ableton Live 12 — 168 tools, 17 domains",
|
|
5
|
+
"owner": {
|
|
6
|
+
"name": "dreamrec",
|
|
7
|
+
"email": "dreamrec@users.noreply.github.com"
|
|
8
|
+
},
|
|
9
|
+
"plugins": [
|
|
10
|
+
{
|
|
11
|
+
"name": "livepilot",
|
|
12
|
+
"description": "Agentic production system for Ableton Live 12 — 168 tools, 17 domains, device atlas, spectral perception, technique memory, neo-Riemannian harmony, Euclidean rhythm, species counterpoint, MIDI I/O",
|
|
13
|
+
"version": "1.8.1",
|
|
14
|
+
"author": {
|
|
15
|
+
"name": "Pilot Studio"
|
|
16
|
+
},
|
|
17
|
+
"source": "./livepilot",
|
|
18
|
+
"category": "integration"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.8.2 — FluCoMa Wiring + Analyzer Fix (March 2026)
|
|
4
|
+
|
|
5
|
+
- Fix: wire 6 FluCoMa DSP objects into LivePilot_Analyzer.maxpat (spectral shape, mel bands, chroma, loudness, onset, novelty)
|
|
6
|
+
- Fix: onset/novelty Python handlers now accept 1 arg (fluid.onsetfeature~/noveltyfeature~ output single float)
|
|
7
|
+
- Fix: rebuild .amxd with FluCoMa objects + binary patch openinpresentation
|
|
8
|
+
- FluCoMa perception tools now fully functional when FluCoMa package is installed
|
|
9
|
+
|
|
3
10
|
## 1.8.1 — Patch (March 2026)
|
|
4
11
|
|
|
5
12
|
- Fix: `parse_key()` now accepts shorthand key notation ("Am", "C#m", "Bbm") in addition to "A minor" / "C# major"
|
|
6
13
|
- Fix: re-freeze LivePilot_Analyzer.amxd with v1.8.0 bridge + patch openinpresentation
|
|
7
14
|
- Fix: address audit findings from fresh v1.8 code review
|
|
8
15
|
- Fix: update bridge version string
|
|
16
|
+
- Fix: restructure plugin directory for Claude Code marketplace compatibility (`plugin/` → `livepilot/.claude-plugin/`)
|
|
9
17
|
|
|
10
18
|
## 1.8.0 — Perception Layer (March 2026)
|
|
11
19
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "livepilot",
|
|
3
|
+
"version": "1.8.2",
|
|
4
|
+
"description": "Agentic production system for Ableton Live 12 — 168 tools, 17 domains, device atlas, spectral perception, technique memory, neo-Riemannian harmony, Euclidean rhythm, species counterpoint, MIDI I/O",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Pilot Studio"
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -12,24 +12,24 @@ Run this checklist EVERY time the user says "update everything", "push", "releas
|
|
|
12
12
|
- [ ] `package.json` → `"version"`
|
|
13
13
|
- [ ] `package-lock.json` → `"version"` (run `npm install --package-lock-only` if stale)
|
|
14
14
|
- [ ] `server.json` → `"version"` (TWO locations: top-level and package)
|
|
15
|
-
- [ ] `plugin/plugin.json` → `"version"`
|
|
15
|
+
- [ ] `livepilot/.claude-plugin/plugin.json` → `"version"`
|
|
16
16
|
- [ ] `mcp_server/__init__.py` → `__version__`
|
|
17
17
|
- [ ] `remote_script/LivePilot/__init__.py` → version in log message
|
|
18
18
|
- [ ] `m4l_device/livepilot_bridge.js` → version in ping response
|
|
19
19
|
- [ ] `CHANGELOG.md` → latest version header
|
|
20
20
|
- [ ] `docs/social-banner.html` → version display
|
|
21
21
|
|
|
22
|
-
**How to check:** `grep -rn "1\.[0-9]\.[0-9]" package.json server.json plugin/plugin.json mcp_server/__init__.py remote_script/LivePilot/__init__.py m4l_device/livepilot_bridge.js CHANGELOG.md docs/social-banner.html`
|
|
22
|
+
**How to check:** `grep -rn "1\.[0-9]\.[0-9]" package.json server.json livepilot/.claude-plugin/plugin.json mcp_server/__init__.py remote_script/LivePilot/__init__.py m4l_device/livepilot_bridge.js CHANGELOG.md docs/social-banner.html`
|
|
23
23
|
|
|
24
24
|
## 2. Tool Count (must ALL match)
|
|
25
25
|
|
|
26
26
|
- [ ] `README.md` — every occurrence
|
|
27
27
|
- [ ] `package.json` → `"description"`
|
|
28
28
|
- [ ] `server.json` → `"description"`
|
|
29
|
-
- [ ] `plugin/plugin.json` → `"description"`
|
|
29
|
+
- [ ] `livepilot/.claude-plugin/plugin.json` → `"description"`
|
|
30
30
|
- [ ] `CLAUDE.md`
|
|
31
|
-
- [ ] `
|
|
32
|
-
- [ ] `
|
|
31
|
+
- [ ] `livepilot/skills/livepilot-core/SKILL.md` — header and domain breakdown
|
|
32
|
+
- [ ] `livepilot/skills/livepilot-core/references/overview.md`
|
|
33
33
|
- [ ] `docs/manual/index.md`
|
|
34
34
|
- [ ] `docs/manual/tool-reference.md`
|
|
35
35
|
- [ ] `docs/TOOL_REFERENCE.md`
|
|
@@ -97,5 +97,5 @@ Run this checklist EVERY time the user says "update everything", "push", "releas
|
|
|
97
97
|
|
|
98
98
|
Run this one-liner to catch most issues:
|
|
99
99
|
```bash
|
|
100
|
-
echo "=== Versions ===" && grep -h '"version"' package.json server.json plugin/plugin.json | head -5 && grep __version__ mcp_server/__init__.py && echo "=== Tool count ===" && grep -rc "@mcp.tool" mcp_server/tools/ | tail -1 && echo "=== npm ===" && npm view livepilot version 2>/dev/null && echo "=== GitHub release ===" && gh release list --limit 1 && echo "=== Tags ===" && git tag -l
|
|
100
|
+
echo "=== Versions ===" && grep -h '"version"' package.json server.json livepilot/.claude-plugin/plugin.json | head -5 && grep __version__ mcp_server/__init__.py && echo "=== Tool count ===" && grep -rc "@mcp.tool" mcp_server/tools/ | tail -1 && echo "=== npm ===" && npm view livepilot version 2>/dev/null && echo "=== GitHub release ===" && gh release list --limit 1 && echo "=== Tags ===" && git tag -l
|
|
101
101
|
```
|
|
Binary file
|
|
@@ -37,6 +37,20 @@
|
|
|
37
37
|
"subpatcher_template": "",
|
|
38
38
|
"assistshowspatchername": 0,
|
|
39
39
|
"boxes": [
|
|
40
|
+
{
|
|
41
|
+
"box": {
|
|
42
|
+
"id": "obj-panel",
|
|
43
|
+
"maxclass": "panel",
|
|
44
|
+
"numinlets": 1,
|
|
45
|
+
"numoutlets": 0,
|
|
46
|
+
"patching_rect": [50.0, 790.0, 350.0, 82.0],
|
|
47
|
+
"presentation": 1,
|
|
48
|
+
"presentation_rect": [0.0, 0.0, 350.0, 170.0],
|
|
49
|
+
"bgcolor": [0.12, 0.12, 0.12, 1.0],
|
|
50
|
+
"bordercolor": [0.2, 0.2, 0.2, 1.0],
|
|
51
|
+
"border": 1
|
|
52
|
+
}
|
|
53
|
+
},
|
|
40
54
|
{
|
|
41
55
|
"box": {
|
|
42
56
|
"id": "obj-1",
|
|
@@ -415,7 +429,7 @@
|
|
|
415
429
|
"id": "obj-js",
|
|
416
430
|
"maxclass": "newobj",
|
|
417
431
|
"text": "js livepilot_bridge.js",
|
|
418
|
-
"numinlets":
|
|
432
|
+
"numinlets": 2,
|
|
419
433
|
"numoutlets": 2,
|
|
420
434
|
"outlettype": ["", ""],
|
|
421
435
|
"patching_rect": [500.0, 550.0, 130.0, 22.0]
|
|
@@ -443,20 +457,6 @@
|
|
|
443
457
|
"patching_rect": [700.0, 500.0, 95.0, 22.0]
|
|
444
458
|
}
|
|
445
459
|
},
|
|
446
|
-
{
|
|
447
|
-
"box": {
|
|
448
|
-
"id": "obj-panel",
|
|
449
|
-
"maxclass": "panel",
|
|
450
|
-
"numinlets": 1,
|
|
451
|
-
"numoutlets": 0,
|
|
452
|
-
"patching_rect": [50.0, 790.0, 350.0, 82.0],
|
|
453
|
-
"presentation": 1,
|
|
454
|
-
"presentation_rect": [0.0, 0.0, 350.0, 170.0],
|
|
455
|
-
"bgcolor": [0.12, 0.12, 0.12, 1.0],
|
|
456
|
-
"bordercolor": [0.2, 0.2, 0.2, 1.0],
|
|
457
|
-
"border": 1
|
|
458
|
-
}
|
|
459
|
-
},
|
|
460
460
|
{
|
|
461
461
|
"box": {
|
|
462
462
|
"id": "obj-multislider",
|
|
@@ -592,6 +592,138 @@
|
|
|
592
592
|
"outlettype": [""],
|
|
593
593
|
"patching_rect": [810.0, 620.0, 72.0, 22.0]
|
|
594
594
|
}
|
|
595
|
+
},
|
|
596
|
+
{
|
|
597
|
+
"box": {
|
|
598
|
+
"id": "obj-fc-spectralshape",
|
|
599
|
+
"maxclass": "newobj",
|
|
600
|
+
"text": "fluid.spectralshape~ @fftsettings 2048 512",
|
|
601
|
+
"numinlets": 1,
|
|
602
|
+
"numoutlets": 2,
|
|
603
|
+
"outlettype": ["", ""],
|
|
604
|
+
"patching_rect": [50.0, 880.0, 260.0, 22.0]
|
|
605
|
+
}
|
|
606
|
+
},
|
|
607
|
+
{
|
|
608
|
+
"box": {
|
|
609
|
+
"id": "obj-fc-prepend-spectralshape",
|
|
610
|
+
"maxclass": "newobj",
|
|
611
|
+
"text": "prepend /spectral_shape",
|
|
612
|
+
"numinlets": 1,
|
|
613
|
+
"numoutlets": 1,
|
|
614
|
+
"outlettype": [""],
|
|
615
|
+
"patching_rect": [50.0, 920.0, 140.0, 22.0]
|
|
616
|
+
}
|
|
617
|
+
},
|
|
618
|
+
{
|
|
619
|
+
"box": {
|
|
620
|
+
"id": "obj-fc-melbands",
|
|
621
|
+
"maxclass": "newobj",
|
|
622
|
+
"text": "fluid.melbands~ 40 @fftsettings 2048 512",
|
|
623
|
+
"numinlets": 1,
|
|
624
|
+
"numoutlets": 2,
|
|
625
|
+
"outlettype": ["", ""],
|
|
626
|
+
"patching_rect": [320.0, 880.0, 250.0, 22.0]
|
|
627
|
+
}
|
|
628
|
+
},
|
|
629
|
+
{
|
|
630
|
+
"box": {
|
|
631
|
+
"id": "obj-fc-prepend-melbands",
|
|
632
|
+
"maxclass": "newobj",
|
|
633
|
+
"text": "prepend /mel_bands",
|
|
634
|
+
"numinlets": 1,
|
|
635
|
+
"numoutlets": 1,
|
|
636
|
+
"outlettype": [""],
|
|
637
|
+
"patching_rect": [320.0, 920.0, 115.0, 22.0]
|
|
638
|
+
}
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
"box": {
|
|
642
|
+
"id": "obj-fc-chroma",
|
|
643
|
+
"maxclass": "newobj",
|
|
644
|
+
"text": "fluid.chroma~ @fftsettings 4096 1024",
|
|
645
|
+
"numinlets": 1,
|
|
646
|
+
"numoutlets": 2,
|
|
647
|
+
"outlettype": ["", ""],
|
|
648
|
+
"patching_rect": [580.0, 880.0, 230.0, 22.0]
|
|
649
|
+
}
|
|
650
|
+
},
|
|
651
|
+
{
|
|
652
|
+
"box": {
|
|
653
|
+
"id": "obj-fc-prepend-chroma",
|
|
654
|
+
"maxclass": "newobj",
|
|
655
|
+
"text": "prepend /chroma",
|
|
656
|
+
"numinlets": 1,
|
|
657
|
+
"numoutlets": 1,
|
|
658
|
+
"outlettype": [""],
|
|
659
|
+
"patching_rect": [580.0, 920.0, 100.0, 22.0]
|
|
660
|
+
}
|
|
661
|
+
},
|
|
662
|
+
{
|
|
663
|
+
"box": {
|
|
664
|
+
"id": "obj-fc-loudness",
|
|
665
|
+
"maxclass": "newobj",
|
|
666
|
+
"text": "fluid.loudness~ @kweighting 1 @truepeak 1",
|
|
667
|
+
"numinlets": 1,
|
|
668
|
+
"numoutlets": 2,
|
|
669
|
+
"outlettype": ["", ""],
|
|
670
|
+
"patching_rect": [820.0, 880.0, 260.0, 22.0]
|
|
671
|
+
}
|
|
672
|
+
},
|
|
673
|
+
{
|
|
674
|
+
"box": {
|
|
675
|
+
"id": "obj-fc-prepend-loudness",
|
|
676
|
+
"maxclass": "newobj",
|
|
677
|
+
"text": "prepend /loudness",
|
|
678
|
+
"numinlets": 1,
|
|
679
|
+
"numoutlets": 1,
|
|
680
|
+
"outlettype": [""],
|
|
681
|
+
"patching_rect": [820.0, 920.0, 108.0, 22.0]
|
|
682
|
+
}
|
|
683
|
+
},
|
|
684
|
+
{
|
|
685
|
+
"box": {
|
|
686
|
+
"id": "obj-fc-onsetfeature",
|
|
687
|
+
"maxclass": "newobj",
|
|
688
|
+
"text": "fluid.onsetfeature~",
|
|
689
|
+
"numinlets": 1,
|
|
690
|
+
"numoutlets": 2,
|
|
691
|
+
"outlettype": ["", ""],
|
|
692
|
+
"patching_rect": [50.0, 960.0, 120.0, 22.0]
|
|
693
|
+
}
|
|
694
|
+
},
|
|
695
|
+
{
|
|
696
|
+
"box": {
|
|
697
|
+
"id": "obj-fc-prepend-onset",
|
|
698
|
+
"maxclass": "newobj",
|
|
699
|
+
"text": "prepend /onset",
|
|
700
|
+
"numinlets": 1,
|
|
701
|
+
"numoutlets": 1,
|
|
702
|
+
"outlettype": [""],
|
|
703
|
+
"patching_rect": [50.0, 1000.0, 90.0, 22.0]
|
|
704
|
+
}
|
|
705
|
+
},
|
|
706
|
+
{
|
|
707
|
+
"box": {
|
|
708
|
+
"id": "obj-fc-noveltyfeature",
|
|
709
|
+
"maxclass": "newobj",
|
|
710
|
+
"text": "fluid.noveltyfeature~ @kernelsize 21",
|
|
711
|
+
"numinlets": 1,
|
|
712
|
+
"numoutlets": 2,
|
|
713
|
+
"outlettype": ["", ""],
|
|
714
|
+
"patching_rect": [320.0, 960.0, 220.0, 22.0]
|
|
715
|
+
}
|
|
716
|
+
},
|
|
717
|
+
{
|
|
718
|
+
"box": {
|
|
719
|
+
"id": "obj-fc-prepend-novelty",
|
|
720
|
+
"maxclass": "newobj",
|
|
721
|
+
"text": "prepend /novelty",
|
|
722
|
+
"numinlets": 1,
|
|
723
|
+
"numoutlets": 1,
|
|
724
|
+
"outlettype": [""],
|
|
725
|
+
"patching_rect": [320.0, 1000.0, 100.0, 22.0]
|
|
726
|
+
}
|
|
595
727
|
}
|
|
596
728
|
],
|
|
597
729
|
"lines": [
|
|
@@ -665,7 +797,31 @@
|
|
|
665
797
|
{"patchline": {"source": ["obj-route-status", 0], "destination": ["obj-set-status", 0]}},
|
|
666
798
|
{"patchline": {"source": ["obj-set-status", 0], "destination": ["obj-status", 0]}},
|
|
667
799
|
{"patchline": {"source": ["obj-route-status", 1], "destination": ["obj-set-key", 0]}},
|
|
668
|
-
{"patchline": {"source": ["obj-set-key", 0], "destination": ["obj-key-display", 0]}}
|
|
800
|
+
{"patchline": {"source": ["obj-set-key", 0], "destination": ["obj-key-display", 0]}},
|
|
801
|
+
|
|
802
|
+
{"patchline": {"source": ["obj-4", 0], "destination": ["obj-fc-spectralshape", 0]}},
|
|
803
|
+
{"patchline": {"source": ["obj-fc-spectralshape", 0], "destination": ["obj-fc-prepend-spectralshape", 0]}},
|
|
804
|
+
{"patchline": {"source": ["obj-fc-prepend-spectralshape", 0], "destination": ["obj-udpsend", 0]}},
|
|
805
|
+
|
|
806
|
+
{"patchline": {"source": ["obj-4", 0], "destination": ["obj-fc-melbands", 0]}},
|
|
807
|
+
{"patchline": {"source": ["obj-fc-melbands", 0], "destination": ["obj-fc-prepend-melbands", 0]}},
|
|
808
|
+
{"patchline": {"source": ["obj-fc-prepend-melbands", 0], "destination": ["obj-udpsend", 0]}},
|
|
809
|
+
|
|
810
|
+
{"patchline": {"source": ["obj-4", 0], "destination": ["obj-fc-chroma", 0]}},
|
|
811
|
+
{"patchline": {"source": ["obj-fc-chroma", 0], "destination": ["obj-fc-prepend-chroma", 0]}},
|
|
812
|
+
{"patchline": {"source": ["obj-fc-prepend-chroma", 0], "destination": ["obj-udpsend", 0]}},
|
|
813
|
+
|
|
814
|
+
{"patchline": {"source": ["obj-4", 0], "destination": ["obj-fc-loudness", 0]}},
|
|
815
|
+
{"patchline": {"source": ["obj-fc-loudness", 0], "destination": ["obj-fc-prepend-loudness", 0]}},
|
|
816
|
+
{"patchline": {"source": ["obj-fc-prepend-loudness", 0], "destination": ["obj-udpsend", 0]}},
|
|
817
|
+
|
|
818
|
+
{"patchline": {"source": ["obj-4", 0], "destination": ["obj-fc-onsetfeature", 0]}},
|
|
819
|
+
{"patchline": {"source": ["obj-fc-onsetfeature", 0], "destination": ["obj-fc-prepend-onset", 0]}},
|
|
820
|
+
{"patchline": {"source": ["obj-fc-prepend-onset", 0], "destination": ["obj-udpsend", 0]}},
|
|
821
|
+
|
|
822
|
+
{"patchline": {"source": ["obj-4", 0], "destination": ["obj-fc-noveltyfeature", 0]}},
|
|
823
|
+
{"patchline": {"source": ["obj-fc-noveltyfeature", 0], "destination": ["obj-fc-prepend-novelty", 0]}},
|
|
824
|
+
{"patchline": {"source": ["obj-fc-prepend-novelty", 0], "destination": ["obj-udpsend", 0]}}
|
|
669
825
|
],
|
|
670
826
|
"dependency_cache": [
|
|
671
827
|
{
|
package/mcp_server/__init__.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""LivePilot MCP Server — bridges MCP protocol to Ableton Live."""
|
|
2
|
-
__version__ = "1.8.
|
|
2
|
+
__version__ = "1.8.2"
|
package/mcp_server/m4l_bridge.py
CHANGED
|
@@ -189,16 +189,18 @@ class SpectralReceiver(asyncio.DatagramProtocol):
|
|
|
189
189
|
elif address == "/chroma" and len(args) >= 12:
|
|
190
190
|
self.cache.update("chroma", [round(float(a), 4) for a in args[:12]])
|
|
191
191
|
|
|
192
|
-
elif address == "/onset" and len(args) >=
|
|
192
|
+
elif address == "/onset" and len(args) >= 1:
|
|
193
|
+
strength = round(float(args[0]), 4)
|
|
193
194
|
self.cache.update("onset", {
|
|
194
|
-
"detected":
|
|
195
|
-
"strength":
|
|
195
|
+
"detected": strength > 0.5,
|
|
196
|
+
"strength": strength,
|
|
196
197
|
})
|
|
197
198
|
|
|
198
|
-
elif address == "/novelty" and len(args) >=
|
|
199
|
+
elif address == "/novelty" and len(args) >= 1:
|
|
200
|
+
score = round(float(args[0]), 4)
|
|
199
201
|
self.cache.update("novelty", {
|
|
200
|
-
"score":
|
|
201
|
-
"boundary":
|
|
202
|
+
"score": score,
|
|
203
|
+
"boundary": score > 0.5,
|
|
202
204
|
})
|
|
203
205
|
|
|
204
206
|
elif address == "/loudness" and len(args) >= 2:
|
package/mcp_server/server.py
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
from contextlib import asynccontextmanager
|
|
4
4
|
import asyncio
|
|
5
|
+
import os
|
|
6
|
+
import signal
|
|
7
|
+
import subprocess
|
|
5
8
|
|
|
6
9
|
from fastmcp import FastMCP, Context # noqa: F401
|
|
7
10
|
|
|
@@ -9,6 +12,28 @@ from .connection import AbletonConnection
|
|
|
9
12
|
from .m4l_bridge import SpectralCache, SpectralReceiver, M4LBridge
|
|
10
13
|
|
|
11
14
|
|
|
15
|
+
def _kill_port_holder(port: int) -> None:
|
|
16
|
+
"""Kill whichever process holds the given UDP port.
|
|
17
|
+
|
|
18
|
+
Used to reclaim port 9880 when a stale duplicate server instance
|
|
19
|
+
is hogging it (common when both project .mcp.json and plugin
|
|
20
|
+
.mcp.json launch the server).
|
|
21
|
+
"""
|
|
22
|
+
try:
|
|
23
|
+
out = subprocess.check_output(
|
|
24
|
+
["lsof", "-t", "-i", f"UDP:{port}"],
|
|
25
|
+
text=True,
|
|
26
|
+
timeout=3,
|
|
27
|
+
).strip()
|
|
28
|
+
my_pid = os.getpid()
|
|
29
|
+
for pid_str in out.splitlines():
|
|
30
|
+
pid = int(pid_str)
|
|
31
|
+
if pid != my_pid:
|
|
32
|
+
os.kill(pid, signal.SIGTERM)
|
|
33
|
+
except (subprocess.CalledProcessError, FileNotFoundError, ValueError):
|
|
34
|
+
pass # lsof not found or no process — nothing to kill
|
|
35
|
+
|
|
36
|
+
|
|
12
37
|
@asynccontextmanager
|
|
13
38
|
async def lifespan(server):
|
|
14
39
|
"""Create and yield the shared AbletonConnection + M4L bridge."""
|
|
@@ -19,14 +44,35 @@ async def lifespan(server):
|
|
|
19
44
|
|
|
20
45
|
# Start UDP listener for incoming M4L spectral data (port 9880)
|
|
21
46
|
loop = asyncio.get_running_loop()
|
|
47
|
+
transport = None
|
|
22
48
|
try:
|
|
23
49
|
transport, _ = await loop.create_datagram_endpoint(
|
|
24
50
|
lambda: receiver,
|
|
25
51
|
local_addr=('127.0.0.1', 9880),
|
|
26
52
|
)
|
|
27
53
|
except OSError:
|
|
28
|
-
# Port
|
|
29
|
-
|
|
54
|
+
# Port 9880 already bound — likely a duplicate server instance
|
|
55
|
+
# (project .mcp.json + plugin .mcp.json both launching).
|
|
56
|
+
# Kill the stale holder so this instance gets the port.
|
|
57
|
+
import sys
|
|
58
|
+
print(
|
|
59
|
+
"LivePilot: UDP port 9880 in use — reclaiming from stale instance",
|
|
60
|
+
file=sys.stderr,
|
|
61
|
+
)
|
|
62
|
+
_kill_port_holder(9880)
|
|
63
|
+
await asyncio.sleep(0.3)
|
|
64
|
+
try:
|
|
65
|
+
transport, _ = await loop.create_datagram_endpoint(
|
|
66
|
+
lambda: receiver,
|
|
67
|
+
local_addr=('127.0.0.1', 9880),
|
|
68
|
+
)
|
|
69
|
+
except OSError:
|
|
70
|
+
print(
|
|
71
|
+
"LivePilot: WARNING — could not bind UDP 9880, "
|
|
72
|
+
"analyzer tools will be unavailable",
|
|
73
|
+
file=sys.stderr,
|
|
74
|
+
)
|
|
75
|
+
transport = None
|
|
30
76
|
|
|
31
77
|
try:
|
|
32
78
|
yield {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "livepilot",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.2",
|
|
4
4
|
"mcpName": "io.github.dreamrec/livepilot",
|
|
5
5
|
"description": "Agentic production system for Ableton Live 12 — 168 tools, 17 domains, device atlas, spectral perception, technique memory, neo-Riemannian harmony, Euclidean rhythm, species counterpoint, MIDI I/O",
|
|
6
6
|
"author": "Pilot Studio",
|
|
@@ -5,7 +5,7 @@ Entry point for the ControlSurface. Ableton calls create_instance(c_instance)
|
|
|
5
5
|
when this script is selected in Preferences > Link, Tempo & MIDI.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
__version__ = "1.8.
|
|
8
|
+
__version__ = "1.8.2"
|
|
9
9
|
|
|
10
10
|
from _Framework.ControlSurface import ControlSurface
|
|
11
11
|
from .server import LivePilotServer
|
package/plugin/plugin.json
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "livepilot",
|
|
3
|
-
"version": "1.8.1",
|
|
4
|
-
"description": "Agentic production system for Ableton Live 12 — 168 tools, 17 domains, device atlas, spectral perception, technique memory, neo-Riemannian harmony, Euclidean rhythm, species counterpoint, MIDI I/O",
|
|
5
|
-
"author": "Pilot Studio",
|
|
6
|
-
"skills": [
|
|
7
|
-
"skills/livepilot-core",
|
|
8
|
-
"skills/livepilot-release"
|
|
9
|
-
],
|
|
10
|
-
"commands": [
|
|
11
|
-
"commands/session.md",
|
|
12
|
-
"commands/beat.md",
|
|
13
|
-
"commands/mix.md",
|
|
14
|
-
"commands/sounddesign.md",
|
|
15
|
-
"commands/memory.md"
|
|
16
|
-
],
|
|
17
|
-
"agents": [
|
|
18
|
-
"agents/livepilot-producer"
|
|
19
|
-
]
|
|
20
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/{plugin → livepilot}/skills/livepilot-core/references/device-atlas/drums-and-percussion.md
RENAMED
|
File without changes
|
/package/{plugin → livepilot}/skills/livepilot-core/references/device-atlas/dynamics-and-punch.md
RENAMED
|
File without changes
|
/package/{plugin → livepilot}/skills/livepilot-core/references/device-atlas/eq-and-filtering.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/{plugin → livepilot}/skills/livepilot-core/references/device-atlas/space-and-depth.md
RENAMED
|
File without changes
|
/package/{plugin → livepilot}/skills/livepilot-core/references/device-atlas/spectral-and-weird.md
RENAMED
|
File without changes
|
/package/{plugin → livepilot}/skills/livepilot-core/references/device-atlas/synths-native.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|