Add WavGang JUCE plugin with Vue WebView, AGPL bridge, and FriendNet layout - #1
Merged
Merged
Conversation
…layout. Introduce PluginTemplate-based build (VST3, CLAP, Standalone), bun-built UI, wavgang-bridge Go service, packaging AGPL notices, and CI. Submodule pins include JUCE, cmake helpers (test WebKit/CURL fixes), and CLAP JUCE 8 API fix. Made-with: Cursor
Upstream sudara/cmake-includes and free-audio/clap-juce-extensions could not fetch the pinned commits (local-only fixes). Mirrors under SeamusMullan carry the same SHAs; JUCE develop and other submodules were already at remote tips. Made-with: Cursor
Nested clap-libs paths are not registered in the top-level repo; --recursive on modules/clap-juce-extensions already checks them out. Made-with: Cursor
Use actions/checkout recursive init like Chasm instead of manual git submodule commands; drop shallow fetch-depth for submodule parity. Made-with: Cursor
Made-with: Cursor
Made-with: Cursor
- Use (secrets.PAT && PAT) || github.token so fork PRs never pass an empty token to checkout v5. - Apply project .clang-format to satisfy the format-check job. Made-with: Cursor
…ble Go cache - Bump cmake submodule: pkg-config tries webkit2gtk-4.1 then 4.0 for Tests/Benchmarks (Ubuntu 22.04). - Move WavGang bus layout PP logic out of the member initializer for consistent clang-format on CI. - setup-go: cache false (bridge has no go.sum). Made-with: Cursor
…es is protected) Made-with: Cursor
Made-with: Cursor
…race) Made-with: Cursor
Made-with: Cursor
Made-with: Cursor
There was a problem hiding this comment.
Pull request overview
Introduces the initial WavGang JUCE plugin scaffold, including a bundled Vue 3 WebView UI, a localhost “bridge” companion process, and a baseline DSP + preset/state/test infrastructure to support future FriendNet integration.
Changes:
- Added a Vue 3 UI (Vite + Pinia) rendered inside JUCE WebBrowserComponent, with a minimal JS↔native contract to discover the bridge base URL.
- Added a Go-based
wavgang-bridge(AGPL) exposing a small localhost HTTP API plus packaging/license materials and docs. - Added JUCE plugin core/editor, preset manager, DSP utilities, tests/benchmarks, and CMake/module/CI scaffolding.
Reviewed changes
Copilot reviewed 74 out of 82 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| VERSION | Adds repo version marker. |
| ui/vitest.config.ts | Adds Vitest config for UI tests. |
| ui/vite.config.ts | Adds Vite build config for UI bundling. |
| ui/tsconfig.node.json | TS config for node-side tooling files. |
| ui/tsconfig.json | TS config for Vue app sources. |
| ui/src/vite-env.d.ts | Declares window.__JUCE__ typing for native bridge. |
| ui/src/stores/bridge.ts | Pinia store to fetch/display bridge status. |
| ui/src/nativeBridge.ts | JS helper to get bridge base URL (native or fallback). |
| ui/src/nativeBridge.spec.ts | Vitest coverage for native bridge helper. |
| ui/src/main.ts | Vue app bootstrap + Pinia install. |
| ui/src/App.vue | Minimal UI to display bridge status. |
| ui/package.json | UI dependencies and scripts (vite/vitest/bun). |
| ui/index.html | UI entry HTML for Vite. |
| ui/bun.lock | Bun lockfile for deterministic UI deps. |
| tests/safety/AudioSafetyTests.cpp | Adds NaN/Inf/denormal/buffer-size/samplerate safety tests. |
| tests/PluginBasics.cpp | Adds basic plugin instance/state tests. |
| tests/helpers/TestSignalGenerators.h | Adds reusable DSP test signal generation. |
| tests/helpers/test_helpers.h | Adds helper to run tests with an editor instance. |
| tests/helpers/DSPTestHelpers.h | Adds buffer utilities + safety helpers for tests. |
| tests/daw/StatePersistenceTests.cpp | Adds state save/restore robustness tests. |
| source/WebUiRoot.h | Declares Web UI root resolver. |
| source/WebUiRoot.cpp | Resolves on-disk ui/dist/bundle web UI root. |
| source/Service/PresetManager.h | Declares preset manager w/ categories + dirty tracking. |
| source/Service/PresetManager.cpp | Implements preset storage/menu/category ops. |
| source/PluginProcessor.h | Defines plugin processor API + APVTS/state schema version. |
| source/PluginProcessor.cpp | Implements processing, parameters, state serialize/deserialize. |
| source/PluginEditor.h | Defines editor that can host WebView or fallback label. |
| source/PluginEditor.cpp | Implements WebView resource provider + native function bridge. |
| source/HostLauncher.h | Declares bridge auto-launch helper. |
| source/HostLauncher.cpp | Implements best-effort bridge reachability check + launch. |
| source/DSP/Utils/ParameterSmoother.h | Adds exponential parameter smoothing utility. |
| source/DSP/Utils/MeteringFIFO.h | Adds lock-free SPSC FIFO for metering snapshots. |
| source/DSP/Utils/DSPUtils.h | Adds basic DSP helper functions (dB, clip, lerp, etc.). |
| source/DSP/Core/ProcessorCore.h | Adds DSP processing scaffold (wet/dry, smoothing, bypass, metering). |
| source/BridgeClient.h | Declares simple HTTP client to wavgang-bridge. |
| source/BridgeClient.cpp | Implements sync status fetch to check bridge availability. |
| scripts/setup.sh | Adds setup script to init required submodules. |
| scripts/setup.ps1 | Windows setup script for submodules. |
| scripts/build.sh | Adds convenience build script (CMake). |
| scripts/build.ps1 | Windows convenience build script. |
| README.md | Updates project overview, build instructions, licensing notes. |
| project.toml | Adds TOML-based project config consumed by CMake. |
| plugins/.gitkeep | Keeps plugins dir in VCS. |
| packaging/icon.png | Adds application/plugin icon asset. |
| packaging/agpl/SOURCE_OFFER.txt | Adds AGPL source offer text for distribution. |
| packaging/agpl/FriendNet-LICENSE.txt | Vendors AGPL license text for FriendNet packaging. |
| packaging/.gitkeep | Keeps packaging dir in VCS. |
| modules.toml | Adds module registry metadata (for template/module system). |
| docs/JS_BRIDGE.md | Documents JUCE native function bridge contract. |
| docs/BRIDGE_API.md | Documents bridge HTTP API endpoints. |
| common/PluginDescriptor.h | Adds common-layer runtime plugin descriptor type. |
| common/PluginBus.h | Adds common-layer pub/sub bus for inter-plugin comms. |
| common/IPluginUI.h | Adds common-layer UI embedding interface. |
| common/IPluginState.h | Adds common-layer state serialization interface. |
| common/IPluginProcessor.h | Adds common-layer DSP processing interface. |
| common/CMakeLists.txt | Adds common-layer interface library target. |
| CMakePresets.json | Adds configure/build/test presets incl. ASan/TSan. |
| CMakeLists.txt | Adds main build, modules, web UI integration, tests/benchmarks wiring. |
| cmake-local/WebUI.cmake | Adds bun-driven UI build target and WVG_WEBUI_ROOT wiring. |
| cmake-local/Sanitizers.cmake | Adds ASan/TSan toggles and flags. |
| cmake-local/ReadProjectConfig.cmake | Adds TOML-to-CMake config reader. |
| cmake-local/PedalMoonbase.cmake | Adds per-plugin moonbase isolation helper (template). |
| cmake-local/Packaging.cmake | Adds basic CPack packaging setup. |
| cmake-local/options.cmake | Adds generated module option defaults. |
| cmake-local/MultiPlugin.cmake | Adds helpers for multi-plugin builds. |
| cmake-local/ModuleSystem.cmake | Adds conditional submodule/module inclusion logic. |
| bridge/README.md | Documents the Go bridge purpose and usage. |
| bridge/main.go | Implements minimal localhost REST bridge (status/version). |
| bridge/LICENSE | Adds AGPL-3.0 license notice for bridge. |
| bridge/go.mod | Defines bridge Go module. |
| benchmarks/Benchmarks.cpp | Adds Catch2 benchmarks for processBlock. |
| assets/.gitkeep | Keeps assets dir in VCS. |
| .gitmodules | Adds/updates submodules (JUCE, cmake, modules, friendnet). |
| .gitignore | Ignores build artifacts, UI outputs, bridge binaries, etc. |
| .github/workflows/build_and_test.yml | Adds CI build/test across Linux/macOS/Windows + format/sanitizer jobs. |
| .clang-tidy | Adds clang-tidy config focused on JUCE/plugin concerns. |
| .clang-format | Adds clang-format config aligned with JUCE style. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+12
to
+21
| add_custom_command( | ||
| OUTPUT "${WVG_WEBUI_DIST}/index.html" | ||
| COMMAND ${WVG_BUN_EXECUTABLE} install | ||
| COMMAND ${WVG_BUN_EXECUTABLE} run build | ||
| WORKING_DIRECTORY "${WVG_WEBUI_SOURCE_DIR}" | ||
| DEPENDS | ||
| "${WVG_WEBUI_SOURCE_DIR}/package.json" | ||
| "${WVG_WEBUI_SOURCE_DIR}/vite.config.ts" | ||
| "${WVG_WEBUI_SOURCE_DIR}/index.html" | ||
| COMMENT "Building WavGang Vue UI (bun)" |
Comment on lines
+1
to
+8
| #pragma once | ||
|
|
||
| #include <cmath> | ||
| #include <juce_audio_basics/juce_audio_basics.h> | ||
| #include <juce_dsp/juce_dsp.h> | ||
| #include <limits> | ||
| #include <random> | ||
|
|
Comment on lines
+190
to
+195
| inline float getRandomFloat (float min, float max, unsigned int seed = 42) | ||
| { | ||
| static std::mt19937 engine (seed); | ||
| std::uniform_real_distribution<float> dist (min, max); | ||
| return dist (engine); | ||
| } |
Comment on lines
+46
to
+52
| const juce::ScopedLock sl (lock); | ||
| auto it = channels.find (channel); | ||
| if (it != channels.end()) | ||
| { | ||
| for (auto& sub : it->second) | ||
| sub.handler (message); | ||
| } |
Comment on lines
+5
to
+13
| /** Best-effort launcher for the AGPL wavgang-bridge binary next to the host or on PATH. */ | ||
| class HostLauncher | ||
| { | ||
| public: | ||
| /** If bridge is not already listening, try to start it. Safe to call from message thread. */ | ||
| static void ensureBridgeRunning (const juce::String& baseUrl = "http://127.0.0.1:17890"); | ||
|
|
||
| private: | ||
| static juce::File findBridgeExecutable(); |
Comment on lines
+4
to
+18
| describe("getBridgeBaseUrl", () => { | ||
| it("falls back when JUCE is absent", async () => { | ||
| const u = await getBridgeBaseUrl(); | ||
| expect(u).toBe("http://127.0.0.1:17890"); | ||
| }); | ||
|
|
||
| it("uses native function when present", async () => { | ||
| window.__JUCE__ = { | ||
| backend: { | ||
| getNativeFunction: vi.fn(() => async () => "http://example.test:9999"), | ||
| }, | ||
| }; | ||
| const u = await getBridgeBaseUrl(); | ||
| expect(u).toBe("http://example.test:9999"); | ||
| }); |
Comment on lines
+23
to
+28
| /** | ||
| * Preset manager with category support, dirty state detection, and menu building. | ||
| * | ||
| * Stores presets as XML files in: | ||
| * [CommonDocuments]/DirektDSP/[PluginName]/Presets/ | ||
| * |
Comment on lines
+17
to
+28
| PresetManager::PresetManager (juce::AudioProcessorValueTreeState& apvts) | ||
| : valueTreeState (apvts) | ||
| { | ||
| if (!defaultDirectory.exists()) | ||
| { | ||
| const auto result = defaultDirectory.createDirectory(); | ||
| if (result.failed()) | ||
| { | ||
| DBG ("Could not create preset directory: " + result.getErrorMessage()); | ||
| jassertfalse; | ||
| } | ||
| } |
Comment on lines
+11
to
+14
| version = "0.1.0" | ||
| formats = ["VST3", "AU", "CLAP", "Standalone"] | ||
| clap_features = "instrument" | ||
| multi_plugin = false |
Comment on lines
+1
to
+7
| #pragma once | ||
|
|
||
| #include <juce_core/juce_core.h> | ||
| #include <functional> | ||
| #include <unordered_map> | ||
| #include <vector> | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Introduces the WavGang JUCE plugin with Vue WebView UI, AGPL bridge, and FriendNet layout. Draft for review.
Made with Cursor