Commit History
-
Sprint 8: prefer port 16620 for first instance, fall back to any port if taken
Verified signatureNEXT PUSH: TASK: Fix port 16620 priority regression FILES CHANGING: Source/Plugin/McpServer.cpp (start() method only) FILES NOT TOUCHING: all locked files ✅ NEW FILES: none"e07a4f2 -
Sprint 7: wire param callbacks in loadInProcessPlugin, clear in unloadInProcessPlugin
Verified signatureWhen SAFE plugin loaded: searchParamCallback, getParamsCallback, setParamsCallback route directly to inProcessPlugin. When unloaded: cleared to nullptr (falls back to Helper). Pro-Q 4 GUI now updates instantly when AI sets parameters via MCP.4d61c1f -
Sprint 7: McpServer.cpp — use param callbacks with Helper IPC fallback
Verified signature95438a2 -
Sprint 7: Route MCP param ops through in-process plugin (fix EQ invisible in GUI)
Verified signatureAdds 3 param callbacks to McpServer. When SAFE plugin loaded in-process, search/get/set_params go directly to inProcessPlugin. When UNSAFE (callbacks null), falls back to Helper IPC. Pro-Q 4 GUI now updates when AI changes parameters."8ef64a9 -
fix: first instance always binds port 16620, fallback to auto-port
Sitar118 +1: Claude Sonnet 4.6Ensures Claude Code MCP registration (fixed at 16620) always works. Second+ instances get OS-assigned ports, discoverable via list_instances(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>19d5f13 -
feat: channel name dropdown in Editor (Sprint 6 Part 5)
Sitar118 +1: Claude Sonnet 4.6Two-row header: row 1 = existing controls, row 2 = channel ComboBox. 30 channel items grouped into Vocals/Drums/Bass/Keys/Synths/Strings/FX/Buses/Custom. Custom... opens AlertWindow for free-text entry. Selection calls processorRef.setChannelName() which updates registry + MCP. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>6b15202 -
Sprint 6: wire channelName, registry, and auto-port into Processor.cpp
Verified signatureChanges from v0.5.3: 1. Constructor: McpServer(helper) — no port, auto-assigned 2. After start(): wire channelNameCallback + register to registry 3. Destructor: unregister from registry 4. New method: setChannelName() 5. getStateInformation: save channelName 6. setStateInformation: restore channelName"225322d -
Sprint 6: add channelName + setChannelName to Processor header
Verified signature0a63fb2 -
Upload Source/Plugin/McpServer.cpp
Verified signature351c5a1 -
Upload Source/Plugin/McpServer.h
Verified signaturea87020c -
Upload Source/Plugin/InstanceRegistry.h
Verified signaturea02f9a6 -
Sprint 5: route audio through in-process plugin for SAFE plugins
Verified signatureNEXT PUSH: TASK: Pro-Q 4 spectrum analyzer fix — audio now flows through in-process instance FILES CHANGING: - PluginBridgeProcessor.cpp (processBlock routing + prepareToPlay in loadInProcessPlugin) FILES NOT TOUCHING: - PluginBridgeEditor.mm ✅ - PluginPickerComponent.mm ✅ - HelperPluginHost.mm ✅ - HelperConnection.cpp ✅ NEW FILES: none APIS USED: - inProcessPlugin->processBlock() — verified (AudioProcessor inheritance) - inProcessPlugin->prepareToPlay() — verified safe (only SAFE plugins reach here) Changes: 1. loadInProcessPlugin(): added prepareToPlay(currentSampleRate, currentBlockSize) after setBusesLayout(), before state restore + addListener() 2. processBlock(): named MidiBuffer param, added in-process audio path: if inProcessPlugin exists → processBlock directly (skips Helper shm) else → existing Helper shm path unchanged 3. AudioAnalyser runs on the output regardless of which path is used"2eb08b2 -
fix: restore v0.5.2 architecture + wire AudioAnalyser correctly
Sitar118 +1: Claude Sonnet 4.6- Restored PluginBridgeEditor.mm to v0.5.2 (in-process createEditor, TreeView picker) - Restored PluginBridgeProcessor.cpp to v0.5.2 (loadInProcessPlugin, safety scan, deduplication, manufacturer names, PBLOG) - Added PluginPickerComponent.mm to CMakeLists.txt (was never registered) - Wired AudioAnalyser into v0.5.2 processor (prepareToPlay, processBlock, getAnalysisCallback) - Fixed AudioAnalyser: FFT is now a stored member, not created per audio block - Updated MACHINE-CONTEXT.md: full scope rules, workflow, architecture lock, dead-end list Root cause of regression: ML Intern rewrote Editor+Processor to add AudioAnalyser, accidentally reverting to pre-v0.5.2 CALayerHost architecture (FAILED-APPROACHES #10). MACHINE-CONTEXT.md now has explicit scope rules to prevent this. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>fdc4e41 -
wire AudioAnalyser: prepareToPlay + processBlock + MCP callback (3 additions)
Verified signaturedf843ce -
Upload Source/Plugin/McpServer.cpp
Verified signature9836bb8 -
Upload Source/Plugin/McpServer.h
Verified signature9209b46 -
integrate AudioAnalyser into Processor + wire get_analysis in McpServer
Verified signatureProcessor: adds AudioAnalyser, calls processBlock after shared memory read McpServer: get_analysis now calls processor's getAnalysis() instead of returning 'silent'"abf507a -
Sprint 4: Add AudioAnalyser — LUFS, FFT bands, stereo width, centroid, true peak
Verified signatureRuns in processBlock (audio thread), stores results in atomics. MCP get_analysis reads atomics from HTTP thread — zero contention. Output format: "-14.2 LUFS | TP:-1.1 | sub:ok bass:+3 low:ok mid:ok hi:-2 brill:ok | W:0.72 | bright" Max ~60 tokens per call."f6aee3c
-
fix: replace CARemoteLayerServer with CAContext+CALayerHost for cross-process GUI
Sitar118Three bugs killed the GUI: 1. CARemoteLayerServer does not capture a hidden NSWindow's content cross-process. Replaced with CAContext (server) + CALayerHost (client) — the correct private-but-stable macOS API for cross-process layer embedding, stable from 10.10 through Sequoia. 2. NSWindow was never orderFront: — WindowServer never composited its content. Fixed: window positioned at (-32000,-32000) and orderFront: called. 3. NSMachBootstrapServer (deprecated on 13+) no longer needed. contextId (uint32_t) is sent directly over the existing IPC socket. New file: Source/Shared/PrivateCA.h — declares CAContext, CALayerHost, CGSMainConnectionID.0548359 -
Upload Source/Plugin/Blocklist.h
Verified signature2224b8a -
remove old files replaced by .mm versions + Blocklist (now in PluginBridgeProcessor.h)
Verified signature4ca2875 -
Upload Source/Plugin/McpServer.cpp
Verified signaturea4fe44e -
Upload Source/Plugin/McpServer.h
Verified signaturee5f329d -
Upload Source/Plugin/HelperConnection.cpp
Verified signature8335f9f -
Upload Source/Plugin/HelperConnection.h
Verified signature24a3c7f -
Upload Source/Plugin/PluginBridgeEditor.mm
Verified signature6063997 -
Upload Source/Plugin/PluginBridgeEditor.h
Verified signatured966811 -
Upload Source/Plugin/PluginBridgeProcessor.cpp
Verified signature3e55272 -
Upload Source/Plugin/PluginBridgeProcessor.h
Verified signature590be7d -
fix: Blocklist path corrected to ~/Library/PluginBridge/ (where JUCE actually writes)"
Verified signatureb1feaca -
fix: findHelperBinary looks for .app bundle, not bare executable
Verified signature9e02f23 -
implement Helper test-load: spawns Helper before in-process load, blocks crashy plugins
Verified signatureNow loadPlugin() does: 1. Check blocklist → skip if blocked 2. Spawn PluginBridgeHelper --test '/path' → wait for exit 3. Exit code 0 → safe → load in-process 4. Exit code != 0 or crash → add to blocklist → show error → Ableton stays alive This prevents Kickstart 2 / Ozone 12 / any crashy plugin from ever crashing Ableton. The Helper takes the hit instead.767fa15 -
fix: add showingError bool to editor header
Verified signature224d9fb -
fix: replace getColour() with bool flag (Label has no getColour in JUCE 8)
Verified signaturec0c12b8 -
fix: add TestResult enum to header (was in .cpp but missing from .h)
Verified signature1066aac -
Upload Source/Plugin/McpServer.cpp
Verified signaturebbd0e6f -
Upload Source/Plugin/McpServer.h
Verified signatureab55e95 -
Upload Source/Plugin/Blocklist.h
Verified signature377833b -
Upload Source/Plugin/PluginBridgeEditor.cpp
Verified signature01a8444 -
Upload Source/Plugin/PluginBridgeEditor.h
Verified signature9f7698e -
Upload Source/Plugin/PluginBridgeProcessor.cpp
Verified signature06d413f -
NEW ARCHITECTURE: In-process hosting + Helper as safety tester + embedded GUI
Verified signatureCOMPLETE REWRITE — new approach: - Plugin loads IN-PROCESS (inside Ableton) like SnappySnap - GUI shows inside PluginBridge's own editor (no separate window) - Helper process ONLY used to test if a plugin is safe before loading - Blocklist persists to disk — unsafe plugins greyed out - Shared memory / semaphores / audio routing via IPC all removed Files changed: - Source/Plugin/PluginBridgeProcessor.h (new: in-process hosting) - Source/Plugin/PluginBridgeProcessor.cpp (new: direct processBlock) - Source/Plugin/PluginBridgeEditor.h (new: embeds plugin GUI) - Source/Plugin/PluginBridgeEditor.cpp (new: resizable, embedded editor) - Source/Plugin/McpServer.h (simplified: talks to processor directly) - Source/Plugin/McpServer.cpp (simplified: no helper dependency) - Source/Plugin/Blocklist.h (NEW: persistent blocklist) - Source/Plugin/PluginTestRunner.h (NEW: spawns helper to test-load) - Source/Plugin/PluginTestRunner.cpp (NEW) - Source/Helper/main.cpp (simplified: test mode only) - Sourc…42bb859 -
Fix: Add hidePluginGui() implementation
Verified signature1dd0405 -
Fix: Add hidePluginGui() method to Processor
Verified signaturec27c0de -
Fix: GUI button toggles between Open GUI / Close GUI — sends hide_gui IPC command
Verified signature2de6888 -
Fix: GUI button toggles Open/Close — sends hide_gui when GUI is open, guaranteed to work"
Verified signatureac5992d -
Fix: Add juce_events include to HelperConnection.h (Timer lives there) + add juce_events to CMake Plugin target
Verified signature122bd54 -
Fix: Editor reload button uses getLastPluginPath() (retained after crash)
Verified signature54c3f6b -
Fix: Add getLastPluginPath() so reload works after crash, fix Editor reload button
Verified signature4a72dce -
Fix: PluginBridgeProcessor.cpp use flat include for IPCProtocol.h (Source/Shared in include dirs)
Verified signature9d2dc5e