RAM2118 commited on
Commit
61c48cb
Β·
verified Β·
1 Parent(s): 312ea17

Update CLAUDE.md with confirmed project decisions

Browse files
Files changed (1) hide show
  1. CLAUDE.md +43 -19
CLAUDE.md CHANGED
@@ -7,6 +7,15 @@ A JUCE-based VST3/AU plugin that:
7
  3. Provides real-time audio analysis (LUFS, FFT bands, stereo width)
8
  4. Any AI that speaks MCP (Claude Code, Codex CLI, Gemini CLI) can control any plugin
9
 
 
 
 
 
 
 
 
 
 
10
  ## Architecture (Single Plugin Host, Not a Graph)
11
  ```
12
  PluginBridgeProcessor (AudioProcessor β€” the outer VST3/AU shell)
@@ -24,7 +33,9 @@ PluginBridgeProcessor (AudioProcessor β€” the outer VST3/AU shell)
24
  - **cpp-httplib** β€” single header `libs/httplib.h` (MIT)
25
  - **nlohmann/json** β€” single header `libs/json.hpp` (MIT)
26
  - **LUFSMeter** β€” 4 files in `Source/LufsMeter/` (MIT, from klangfreund/LUFSMeter)
27
- - Targets: VST3 + AU, macOS (Xcode) + Windows (MSVC)
 
 
28
 
29
  ## MCP Protocol
30
  - Transport: Streamable HTTP (NOT stdio β€” we're inside a DAW process)
@@ -32,17 +43,21 @@ PluginBridgeProcessor (AudioProcessor β€” the outer VST3/AU shell)
32
  - Wire format: JSON-RPC 2.0
33
  - Handshake: `initialize` β†’ `notifications/initialized` β†’ then tools/list, tools/call
34
  - 5 tools only: `list_plugins`, `search_param`, `get_params`, `set_params`, `get_analysis`
 
 
35
 
36
- ## Key JUCE APIs (Correct, Verified)
37
  - `addDefaultFormatsToManager(formatManager)` β€” NOT deprecated `addDefaultFormats()`
38
- - `formatManager.createPluginInstanceAsync(desc, sr, bs, callback)` β€” ALWAYS async
39
  - `instance->enableAllBuses()` β€” MUST call before using
40
  - `plugin->getParameters()` β†’ `Array<AudioProcessorParameter*>`
41
- - Cast to `AudioPluginInstance::HostedParameter*` for `getParameterID()` (stable ID)
42
- - `param->beginChangeGesture()` / `setValueNotifyingHost(val)` / `endChangeGesture()`
43
  - `juce::dsp::FFT` for spectral analysis (NOT KissFFT, NOT Gist β€” those are GPL)
 
 
44
 
45
- ## Design Laws
46
  - Never return all parameters β€” search first, fetch by ID
47
  - Delta only after param changes
48
  - Single-line compact responses (numbers only)
@@ -55,10 +70,11 @@ PluginBridgeProcessor (AudioProcessor β€” the outer VST3/AU shell)
55
  - Use `std::atomic<float>` for analysis values queried by HTTP
56
  - Use `CriticalSection` / `ScopedLock` for plugin hot-swap
57
  - Never call `getValue()` directly from HTTP thread β€” read from atomic cache
 
58
  - `httplib::Server` lifecycle: constructor starts thread, destructor calls stop()+join()
59
 
60
  ## Sprint Order
61
- 1. **Sprint 1**: Empty plugin shell + httplib server responding to curl
62
  2. **Sprint 2**: Host Pro-Q 4, route audio, enumerate params
63
  3. **Sprint 3**: MCP JSON-RPC dispatch, all 5 tools working from Claude Code
64
  4. **Sprint 4**: Audio analysis (LUFS, FFT bands, stereo, True Peak)
@@ -67,27 +83,35 @@ PluginBridgeProcessor (AudioProcessor β€” the outer VST3/AU shell)
67
  - Don't use `AudioProcessorGraph` β€” we host ONE plugin, not a graph
68
  - Don't use `AudioPluginHost`'s settings file β€” use runtime file picker
69
  - Don't fork `getdunne/juce-plugin-wrapper` β€” dead, GPL, JUCE 6
70
- - Don't use Gist or Sound-Analyser code β€” GPL license
71
  - Don't use stdio MCP transport β€” plugin is inside DAW, not a subprocess
72
- - Don't use `getParameter(int)` / `setParameter(int, float)` β€” deprecated, asserts
 
 
73
 
74
- ## Questions Before Building (Ask Adi)
75
- 1. macOS only for now, or Windows too? (affects CMake targets + code signing)
76
- 2. Do you have a JUCE license, or are we building under GPL for now?
77
- 3. Where on your Mac should the built .vst3 be installed? (default: ~/Library/Audio/Plug-Ins/VST3/)
78
- 4. Which plugin should we test with first? (Pro-Q 4 assumed β€” confirm)
79
- 5. Your Xcode version? (need 14+ for JUCE 8)
 
 
 
 
 
 
80
 
81
  ## Repo Structure
82
  ```
83
  pluginbridge/
84
  β”œβ”€β”€ CLAUDE.md ← this file (Claude Code reads automatically)
85
  β”œβ”€β”€ ROADMAP.md ← full technical roadmap with code samples
86
- β”œβ”€β”€ CMakeLists.txt ← (to be created)
87
- β”œβ”€β”€ JUCE/ ← git submodule (to be added locally)
88
  β”œβ”€β”€ libs/
89
- β”‚ β”œβ”€β”€ httplib.h
90
- β”‚ └── json.hpp
91
  └── Source/
92
  β”œβ”€β”€ PluginBridgeProcessor.h/.cpp
93
  β”œβ”€β”€ PluginBridgeEditor.h/.cpp
 
7
  3. Provides real-time audio analysis (LUFS, FFT bands, stereo width)
8
  4. Any AI that speaks MCP (Claude Code, Codex CLI, Gemini CLI) can control any plugin
9
 
10
+ ## Project Decisions (Confirmed)
11
+ - **Platform:** macOS only (for now)
12
+ - **License:** GPL (JUCE GPL mode β€” no commercial license needed)
13
+ - **VST3 install path:** `~/Library/Audio/Plug-Ins/VST3/`
14
+ - **AU install path:** `~/Library/Audio/Plug-Ins/Components/`
15
+ - **Test plugins:** FabFilter Pro-Q 4 (EQ, many params), LA-2A compressor (fewer params)
16
+ - **Xcode:** 14+ required (user should verify with `xcode-select --version`)
17
+ - **DAW:** Ableton Live (primary), Logic Pro (secondary AU test)
18
+
19
  ## Architecture (Single Plugin Host, Not a Graph)
20
  ```
21
  PluginBridgeProcessor (AudioProcessor β€” the outer VST3/AU shell)
 
33
  - **cpp-httplib** β€” single header `libs/httplib.h` (MIT)
34
  - **nlohmann/json** β€” single header `libs/json.hpp` (MIT)
35
  - **LUFSMeter** β€” 4 files in `Source/LufsMeter/` (MIT, from klangfreund/LUFSMeter)
36
+ - **Target formats:** VST3 + AU (macOS only)
37
+ - **Build:** `mkdir build && cd build && cmake .. && cmake --build .`
38
+ - **Install:** `COPY_PLUGIN_AFTER_BUILD=TRUE` in CMake copies to system plugin dirs
39
 
40
  ## MCP Protocol
41
  - Transport: Streamable HTTP (NOT stdio β€” we're inside a DAW process)
 
43
  - Wire format: JSON-RPC 2.0
44
  - Handshake: `initialize` β†’ `notifications/initialized` β†’ then tools/list, tools/call
45
  - 5 tools only: `list_plugins`, `search_param`, `get_params`, `set_params`, `get_analysis`
46
+ - Session: Server returns `Mcp-Session-Id` header on init, client echoes it back
47
+ - Security: bind 127.0.0.1 only, validate Origin header
48
 
49
+ ## Key JUCE APIs (Correct, Verified Against JUCE 8 Source)
50
  - `addDefaultFormatsToManager(formatManager)` β€” NOT deprecated `addDefaultFormats()`
51
+ - `formatManager.createPluginInstanceAsync(desc, sr, bs, callback)` β€” ALWAYS async (AU requires it)
52
  - `instance->enableAllBuses()` β€” MUST call before using
53
  - `plugin->getParameters()` β†’ `Array<AudioProcessorParameter*>`
54
+ - Cast to `AudioPluginInstance::HostedParameter*` for `getParameterID()` (stable string ID)
55
+ - `param->beginChangeGesture()` / `setValueNotifyingHost(val)` / `endChangeGesture()` β€” for DAW automation
56
  - `juce::dsp::FFT` for spectral analysis (NOT KissFFT, NOT Gist β€” those are GPL)
57
+ - `juce::dsp::Oversampling<float>` for True Peak measurement (4Γ— oversample)
58
+ - `juce::dsp::WindowingFunction<float>::hann` for FFT windowing
59
 
60
+ ## Design Laws (Non-Negotiable)
61
  - Never return all parameters β€” search first, fetch by ID
62
  - Delta only after param changes
63
  - Single-line compact responses (numbers only)
 
70
  - Use `std::atomic<float>` for analysis values queried by HTTP
71
  - Use `CriticalSection` / `ScopedLock` for plugin hot-swap
72
  - Never call `getValue()` directly from HTTP thread β€” read from atomic cache
73
+ - Cap httplib thread pool to 2-4 threads (reduce OS pressure in plugin host)
74
  - `httplib::Server` lifecycle: constructor starts thread, destructor calls stop()+join()
75
 
76
  ## Sprint Order
77
+ 1. **Sprint 1**: Empty plugin shell + httplib server responding to curl ← START HERE
78
  2. **Sprint 2**: Host Pro-Q 4, route audio, enumerate params
79
  3. **Sprint 3**: MCP JSON-RPC dispatch, all 5 tools working from Claude Code
80
  4. **Sprint 4**: Audio analysis (LUFS, FFT bands, stereo, True Peak)
 
83
  - Don't use `AudioProcessorGraph` β€” we host ONE plugin, not a graph
84
  - Don't use `AudioPluginHost`'s settings file β€” use runtime file picker
85
  - Don't fork `getdunne/juce-plugin-wrapper` β€” dead, GPL, JUCE 6
86
+ - Don't use Gist or Sound-Analyser code β€” GPL license conflict (we're already GPL but want MIT deps)
87
  - Don't use stdio MCP transport β€” plugin is inside DAW, not a subprocess
88
+ - Don't use `getParameter(int)` / `setParameter(int, float)` β€” deprecated, asserts in debug
89
+ - Don't target Windows yet β€” macOS only for now
90
+ - Don't scan system plugins on load β€” use file picker for explicit selection
91
 
92
+ ## First Steps for Claude Code
93
+ 1. Run `xcode-select --version` to verify Xcode 14+
94
+ 2. Run `cmake --version` to verify CMake 3.22+
95
+ 3. Clone JUCE 8 as submodule: `git submodule add https://github.com/juce-framework/JUCE.git`
96
+ 4. Download `httplib.h` from yhirose/cpp-httplib into `libs/`
97
+ 5. Download `json.hpp` from nlohmann/json into `libs/`
98
+ 6. Create CMakeLists.txt (see ROADMAP.md for skeleton)
99
+ 7. Create Source/ files (empty stubs first)
100
+ 8. Build: `mkdir build && cd build && cmake .. -G Xcode && cmake --build . --config Release`
101
+ 9. Verify plugin appears in `~/Library/Audio/Plug-Ins/VST3/`
102
+ 10. Load in Ableton β†’ verify audio passthrough
103
+ 11. Verify `curl -X POST http://localhost:16620/mcp -d '{}'` gets a response
104
 
105
  ## Repo Structure
106
  ```
107
  pluginbridge/
108
  β”œβ”€β”€ CLAUDE.md ← this file (Claude Code reads automatically)
109
  β”œβ”€β”€ ROADMAP.md ← full technical roadmap with code samples
110
+ β”œβ”€β”€ CMakeLists.txt
111
+ β”œβ”€β”€ JUCE/ ← git submodule
112
  β”œβ”€β”€ libs/
113
+ β”‚ β”œβ”€β”€ httplib.h ← cpp-httplib (yhirose/cpp-httplib)
114
+ β”‚ └── json.hpp ← nlohmann/json
115
  └── Source/
116
  β”œβ”€β”€ PluginBridgeProcessor.h/.cpp
117
  β”œβ”€β”€ PluginBridgeEditor.h/.cpp