-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinfo.json
More file actions
300 lines (300 loc) · 26.8 KB
/
Copy pathinfo.json
File metadata and controls
300 lines (300 loc) · 26.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
{
"build": [
"iPlug2 project-file builds are format-specific. Build only the targets the user actually needs instead of trying to build everything.",
"Common targets are APP, AU/AUv3, VST2, VST3, CLAP, and AAX. On Windows you normally build the `.sln`; on macOS you normally build the generated Xcode project.",
"If the change adds source/header files, use `ifact include <plugin/tool name> <path to file>` before building so all VS projects stay in sync."
],
"build configs": [
"Use Debug for iteration and investigation, Release for packaging or final validation.",
"The iPlug2 skill also mentions a `Tracer` config on macOS project builds when extra tracing is useful.",
"Confirm artifact location by format after the build. For example macOS APP goes to `~/Applications`, while common plugin formats land in the standard user plugin folders."
],
"build targets": [
"Map user intent to concrete format targets. If they asked for VST3, build VST3; do not assume AU/CLAP/AAX also matter.",
"Project-file target names are the format names directly. CMake target names typically use suffixes like `-app`, `-vst3`, `-clap`, `-aax`, and `-au`.",
"Avoid all-target builds unless explicitly requested. Missing SDKs commonly break unrelated formats and waste time."
],
"build troubleshooting": [
"First classify the failure: dependency/setup, missing file/project membership, compile error, or link/package error.",
"If a newly added file is missing from one VS target, suspect project membership first and re-check `ifact include` coverage.",
"If only one format fails, treat it as a format-specific dependency or packaging issue before touching shared DSP/UI code."
],
"build-cmake": [
"CMake is a separate workflow from the generated project files. Treat configure and build as distinct steps so failures stay localized.",
"Ninja is the simplest fast path, Xcode is useful for Apple debugging, and Visual Studio generators are the native Windows multi-config option.",
"CMake outputs normally go under `build/out/`, so report results from there instead of assuming the project-file install locations."
],
"build-cmake configure": [
"Create a dedicated `build/` directory, configure once, then rebuild from it until the toolchain or major options change.",
"Be explicit about generator and architecture. Examples from the skills are `-G Ninja`, `-G Xcode`, or `-G \"Visual Studio 17 2022\" -A x64`.",
"If dependencies, backend, or platform options change and CMake starts behaving strangely, reconfigure instead of layering hacks onto a stale cache."
],
"build-cmake targets": [
"Use `cmake --build . --config <Config> --target <Name-suffix>` to build only the required format.",
"The skill lists suffixes such as `-app`, `-vst2`, `-vst3`, `-clap`, `-aax`, and `-au`.",
"Prefer single-target builds first. They surface the relevant failure faster and avoid unrelated SDK breakage."
],
"build-cmake troubleshooting": [
"Separate configure failures from compile failures. Configure errors usually point to missing SDKs, generator issues, or toolchain paths, not plugin code.",
"After dependency changes, rerun configure before assuming the source is wrong.",
"If one target fails while others pass, inspect that target's format dependency chain first."
],
"doxygen": [
"Use this for API discovery and symbol lookup with lower context cost than raw source scanning.",
"Prefer `ifact doxy find <library> \"<regex>\"` for discovery and `ifact doxy lookup <library> <symbol> [feature]` for focused details.",
"If docs are unavailable, guide the user to install/generate via Addons when required."
],
"doxygen generate": [
"Use this when documentation is missing/stale for a supported library.",
"Generation prerequisites vary by library/addon; check install state first.",
"Skia docs are addon-driven because iPlug2 ships prebuilt binaries, not full Skia source."
],
"doxygen query": [
"Use this for minimal-context API lookup during implementation.",
"Start with narrow regex and type/limit filters before broad searches.",
"Use `Class::Method` lookup to avoid scanning unrelated symbols."
],
"doxygen troubleshooting": [
"Use this when lookup/find fails or returns incomplete results.",
"Differentiate missing-addon/missing-docs issues from query-quality issues.",
"Give users precise addon/install steps when generation requires addon workflows."
],
"dsp": [
"Audio runs in `void <Your Plugin>::ProcessBlock(sample** inputs, sample** outputs, int nFrames)` where `sample` is a typedef for double/float depending on the project config.",
"Useful helpers include `NInChansConnected()` `NOutChansConnected()` and `GetSampleRate()`.",
"Report processing latency (e.g. for lookahead) with `SetLatency(int samples)`, so the host compensates correctly.",
"Cache values that the DSP hot path reuses. Avoid repeated queries and allocate buffers outside realtime processing.",
"The eDSP library can be used for more advanced DSP like FFT and Hilbert transforms. If `/eDSP` is not present and advanced DSP is needed, suggest the user install it through the Addons menu in iFactory.",
"eDSP also uses Doxygen and you can use all your usual `ifact doxy` commands but by specifying eDSP instead of iPlug2.",
"You will need to use your include command to add the relevant header/source files from eDSP to the solution."
],
"example": [
"Use this when creating a plugin from an existing iPlug2 example rather than from a clean template.",
"The upstream duplication flow is `Examples/duplicate.py <SourceExample> <NewPluginName> <ManufacturerName>` and it renames the generated project files for you.",
"After duplication, audit `config.h`, identifiers, resources, and build outputs before treating it as a clean new plugin."
],
"example cleanup": [
"After duplication, remove leftover branding, unused assets, and example-specific code paths so the new plugin has one clear identity.",
"Recheck `PLUG_UNIQUE_ID`, `PLUG_MFR_ID`, names, URLs, copyright, and any copied preset/state assumptions.",
"Do not casually change bundle-name style identifiers without understanding the matching plist/project metadata."
],
"example duplicate": [
"Recommended source examples from the skills are `IPlugEffect` for effects, `IPlugInstrument` for instruments, `IPlugControls` for control demos, and `IPlugWebUI` or `IPlugSvelteUI` for WebView-based UIs.",
"Keep the new plugin name code-safe: no spaces or special characters. Manufacturer defaults must also be checked rather than blindly accepted.",
"After duplication, run a targeted build quickly to catch any missed rename or resource path issues."
],
"include": [
"Use `ifact include <plugin/tool name> <path to file>` to add headers/sources to project files.",
"For multi-target Visual Studio solutions, inclusion should propagate to all projects in the solution.",
"Use this instead of manual project-file edits to avoid target drift."
],
"include solution": [
"Use this when adding files in solutions that contain multiple format projects.",
"Ensure includes are present for each relevant target project, not only one project node.",
"After include operations, run at least one representative build to verify propagation."
],
"include validation": [
"Use this when debugging missing-file compile errors after include operations.",
"Verify path correctness and confirm the file was added to the intended plugin/tool item.",
"If failures are target-specific, inspect project membership for that target first."
],
"manage": [
"You can use `ifact list` to list the tools and plugins within the current project.",
"You can use `ifact templates` to list the available plugin templates provided by iPlug2.",
"You can create a new plugin within the project by using `ifact create <template> <name>`. The name is the internal code name so it may not contain spaces or special characters."
],
"manage addons": [
"Use this when a dependency or docs tool has an iFactory-managed install path instead of manual setup.",
"Prefer Project Manager -> Addons for supported libraries and docs packages so install/remove state stays visible to the user.",
"If a command fails because an addon is missing, tell the user the exact addon name to install rather than giving generic setup advice."
],
"manage create": [
"Run `ifact templates` first so the template choice is deliberate instead of assumed.",
"Use `ifact create <template> <name>` to create a plugin. `<name>` is the internal code name, so keep it filesystem-safe with no spaces.",
"If the user wants a heavily example-based starting point rather than a standard template, use the example/duplicate flow instead."
],
"manage vcs": [
"Some addon installs depend on whether the project is already a git repo. In repo projects, supported dependencies may be added as submodules.",
"If submodules are not appropriate or git is unavailable, fall back to clone or zip flows as implemented by iFactory.",
"Do not assume auth or token state. Use the workflow that works for the current project and report the resulting install state clearly."
],
"parameter": [
"Define parameters as an enum in the plugin header and pass `kNumParams` into `MakeConfig(...)`. Access them with `GetParam(idx)`.",
"Prefer the most specific init method: `InitGain`, `InitFrequency`, `InitPercentage`, `InitBool`, `InitEnum`, and friends set better defaults than a raw `InitDouble`.",
"Use groups when parameters belong together. They help with host organization and unlock batch operations like group reset/copy/randomize.",
"Use shapes intentionally. `ShapePowCurve(3.)` is useful for finer low-end control, while frequency-like controls often want logarithmic behavior.",
"Use `SetDisplayText()` or a display lambda when value text needs custom wording such as `-inf`, kHz formatting, or enum-like text on numeric params.",
"In DSP code, read parameters in a realtime-safe way and cache derived values. For gain params, `DBToAmp()` is usually what you want instead of raw `Value()`.",
"Use `OnParamChange(...)` for fast DSP-side state updates and `OnParamChangeUI(...)` for UI-thread changes such as hide/show logic.",
"For bulk parameter work, the skills also highlight `InitParamRange`, `CloneParamRange`, `ForParamInGroup`, `RandomiseParamValues`, and `DefaultParamValues`."
],
"preset": [
"Create factory presets in the constructor after parameter initialization.",
"Use `MakePreset(...)` only when positional parameter order is stable and obvious. It requires values in enum order for every parameter.",
"Prefer `MakePresetFromNamedParams(...)` when you want safer preset definitions that survive reordering better because each value is tied to a specific param index.",
"Use plain/display values, not normalized 0-1 values. Enums use ints, toggles use bool-like values, and continuous params use their normal units such as Hz, dB, %, or seconds.",
"For complex non-parameter state, the skills also point to `MakePresetFromChunk(...)` and `MakePresetFromBlob(...)`."
],
"screenshot": [
"Use the standalone APP target for screenshot automation rather than opening a DAW just to capture the UI.",
"The skill describes a CLI screenshot flow where the built app launches, waits briefly for the UI to render, captures a PNG, then exits.",
"This is useful for docs, QA, and repeatable visual checks because the capture path is scriptable."
],
"screenshot capture": [
"Build the standalone APP first, then run the app binary with `--screenshot <output.png>`.",
"The skill notes that screenshot mode implicitly disables audio/MIDI I/O and waits around 500 ms before capture so the UI has time to settle.",
"Capture from a known UI state and write to a predictable path if the image will be reused by docs or CI."
],
"screenshot staging": [
"Keep generated screenshots separate from hand-edited marketing assets so automated outputs stay reproducible.",
"Use stable naming tied to plugin name, state, and scale when multiple captures are expected.",
"If screenshots are part of a workflow, document which APP build and command produced them."
],
"screenshot troubleshooting": [
"If a capture is blank or wrong, first confirm the APP target was rebuilt and the UI is not still rendering when capture occurs.",
"Reduce moving parts: fixed size, deterministic preset/state, and no unnecessary live animation while debugging capture issues.",
"Treat graphics-backend quirks as a second step after lifecycle timing has been ruled out."
],
"serialize": [
"By default `SerializeState()` and `UnserializeState()` just serialize parameter values in enum order via `SerializeParams()` and `UnserializeParams()`.",
"That default is fragile: if you reorder parameters or insert new ones in the middle, old projects can load the wrong values into the wrong params.",
"For simple plugins, only append new parameters at the end if you want to keep default serialization safe enough.",
"For anything more complex, override state serialization and write a version tag first, then custom data, then parameter data if needed.",
"Use `IByteChunk` helpers such as `Put`, `PutStr`, `Get`, and `GetStr` for custom state.",
"After restore, iPlug2 will push the loaded values back through reset/change paths, so keep restore logic deterministic and migration-aware."
],
"setup-deps": [
"Use this before serious build work when dependency state is uncertain.",
"The upstream setup flow distinguishes between plugin SDKs, Skia prebuilt libs, and optional iOS libs. Do not assume they are all present by default.",
"Dependency gaps are a common root cause of build and validation failures, so verify early and report concrete missing pieces."
],
"setup-deps core": [
"The skills call out `Dependencies/IPlug/download-iplug-sdks.sh` for plugin SDK setup and `Dependencies/download-prebuilt-libs.sh` for Skia prebuilt libraries.",
"Standalone and AU builds need less external SDK setup than formats like VST3, CLAP, VST2, or AAX.",
"If iFactory manages the dependency as an addon instead, prefer the addon path and tell the user that exact route."
],
"setup-deps formats": [
"VST3 and CLAP can be bootstrapped by the normal dependency scripts or addon flows, depending on project setup.",
"VST2 is legacy and no longer publicly distributed, so do not suggest it lightly for new work.",
"AAX still requires a manual SDK download from Avid's developer portal, so treat AAX failures as expected until the user has that SDK."
],
"setup-deps verify": [
"After setup changes, verify with the smallest representative build rather than a full matrix.",
"Pick a target that exercises the dependency you just changed. For example, validate VST3 setup with a VST3 build, not an APP build.",
"If verification fails, report the exact failing step so the user knows whether the setup or the code still needs work."
],
"ui": [
"iPlug2's native UI system is IGraphics. Visible UI elements are controls, usually classes derived from `IControl`.",
"Most plugins set up UI in constructor lambdas such as `mMakeGraphicsFunc` and `mLayoutFunc`, then attach controls inside the layout lambda.",
"The UI can be destroyed and rebuilt when the editor closes and reopens, so any dynamic visibility or state must be re-established from plugin state, not assumed to persist in the control objects.",
"Controls are attached to IGraphics within the layout function with `pGraphics->AttachControl(<control>)`.",
"Layout work mostly revolves around `IRECT`, which represents control bounds and has a large helper API for padding, centering, strips, grids, and fractional slicing.",
"For resizable UIs, the upstream skill recommends `SetLayoutOnResize(true)` and repositioning existing controls instead of recreating them on every resize.",
"Some controls accept resources such as vector and bitmap images and fonts, you can learn how to import and use resources with `ifact info ui resources`.",
"You can see a list of available controls and learn more with `ifact info ui controls`."
],
"ui controls": [
"If the built-in controls are not enough, use `ifact info ui controls custom` for custom-control guidance.",
"Use your Doxygen lookup command to look further into any controls you wish to use or learn from.",
"Controls are broken into 3 categories based on prefix:",
"'IV': Vector controls. These are the normal first choice because they are skinnable with `IVStyle` and do not need art assets.",
"'IB': These controls accept provided bitmap images to use for skins, these bitmaps can have multiple textures stacked side by side into a sprite sheet.",
"'ISVG': These controls accept provided svg vector images to use for skins.",
"Controls without a skin prefix generally do not need external art assets.",
"# Controls that *can* control parameters",
"Functional controls link directly to parameters, automatically linking to the parameter and using its label.",
"However you may link them to kNoParameter.",
"## Continuous",
"Knobs: IVKnobControl, IBKnobControl (Sprite sheet), IBKnobRotaterControl (Rotates texture), ISVGKnobControl.",
"Sliders: IVSliderControl, IBSliderControl, ISVGSliderControl.",
"Others: IVXYPadControl, IVNumberBoxControl (Very versatile number input with +- buttons, number entry and vertical dragging.), IVRangeSliderControl.",
"## Discrete:",
"Toggles (Binary on/off): IVToggleControl, ISVGToggleControl, ITextToggleControl (Uses text as the skin, mainly used with forkawesome, the fork of fontawesome).",
"Switches (Multi-state, click to increment): IVSwitchControl, IBSwitchControl, ISVGSwitchControl, IVSlideSwitchControl (A click to increment slideswitch (not draggable) with text on the handle for the state)",
"Others: IVMenuButtonControl (dropdown), IVRadioButtonControl, IVTabSwitchControl (side by side text options using font icons)",
"# Controls that don't control parameters",
"Buttons: IVButtonControl, IBButtonControl, ISVGButtonControl. (trigger a provided function when clicked)",
"Static: IPanelControl (Filled rectangle), IBitmapControl, ISVGControl",
"Text: `ifact info ui controls text`",
"Line Plots: IVPlotControl, IVDisplayControl (Rolling history), IVScopeControl (Multi-channel oscilloscope)",
"Meters: IVMeterControl, IVLEDMeterControl (Segmented LED), IVPeakAvgMeterControl, IBMeterControl (Spritesheet of volume levels)",
"Spectrum analyzers: IVSpectrumAnalyzerControl, IVBarGraphSpectrumAnalyzerControl",
"MIDI: IVKeyboardControl, IWheelControl (Pitchbend/Mod wheel)",
"Preset managers: IVBakedPresetManagerControl, IVDiskPresetManagerControl",
"Colors: IColorPickerControl, IVColorSwatchControl",
"Tabs: IVTabbedPagesControl, IVTabPage",
"Tests: `ifact info ui controls tests`",
"Custom graphics: IWebViewControl, ILambdaControl (Plays custom animation when clicked), IPlatformViewControl (Embed a HWND, UIView or NSView), ISkLottieControl (Skia Lottie animation via Skottie), IShaderControl (Draw to UI via Skia shading language)",
"Others: IContainerBase (Allows a control to nest sub controls), IVMultiSliderControl (Editable bar graph), ICornerResizerControl, ILEDControl, IFPSDisplayControl, IPopupMenuControl (The popup list itself for a menu/drop-down), IVGroupControl (Draw rect around named IControl group), IGraphicsLiveEdit (Enables live-edit to rearrange UI)"
],
"ui controls custom": [
"Use a built-in control if it already matches the need. Reach for a custom control only when drawing or interaction really differs.",
"For simple custom drawing with little interaction, `ILambdaControl` is often enough. For full custom behavior, derive from `IControl`. For IV-style behavior, mix in `IVectorBase`. For child control containers, derive from `IContainerBase`.",
"Override `Draw(IGraphics& g)` for rendering and only add backend-specific logic when there is no backend-agnostic route.",
"IGraphics abstracts NanoVG and Skia. Check the active backend with `ifact graphics get <plugin>` and only switch it with `ifact graphics set <plugin> <SKIA|NANOVG>` when the user actually wants that change.",
"Skia also has Doxygen support, so Skia-specific API lookup can go through the normal `ifact doxy` flow using the `Skia` target."
],
"ui controls tests": [
"TestAnimationControl, TestArcControl, TestBezierControl, TestBlendControl, TestColorControl, TestCursorControl, TestCustomShaderControl, TestDirBrowseControl, TestDragAndDropControl, TestDrawContextControl, TestDropShadowControl, TestFlexBoxControl, TestFontControl, TestGesturesControl, GFXLabelControl, TestGradientControl, TestImageControl, TestKeyboardControl, TestLayerControl, TestMaskControl, TestMPSControl, TestMultiPathControl, TestMTControl, TestPolyControl, TestShadowGradientControl, TestSizeControl, TestSVGControl, TestTextControl, TestTextOrientationControl, TestTextSizeControl"
],
"ui controls text": [
"ITextControl, IMultiLineTextControl, IVLabelControl (More fancy and stylable than ITextControl), ISkParagraphControl (Rich text demo with Skia), IBTextControl (Bitmap font from spritesheet), IURLControl, IEditableTextControl, ITextEntryControl, IRTTextControl (Real-time text, can be safely updated from DSP at high rates), ICaptionControl (Displays the textual representation of a parameter), IBubbleControl (Text bubble, good for attaching to sliders to display value next to handle when dragging), PlaceHolder (Placeholder control which is text)"
],
"ui resources": [
"The available resources are listed at the bottom of config.h of the plugin as macros for the file names of resources.",
"To add a resource to a plugin you can use `ifact resource add <plugin folder name> <absolute resource path> <resource name in uppercase snake case>`; it will automatically include the resource and add a macro entry like '#define ROBOTO_FN \"Roboto-Regular.ttf\"' (_FN suffix added automatically).",
"Resources will normally be provided by the user, if the user has not provided the resources they want, let them know they can add resources to a plugin by dragging and dropping a file onto the plugin's sidebar icon or that you can add resources if they provide the path to them.",
"Fonts are loaded like `pGraphics->LoadFont(\"Roboto-Regular\", ROBOTO_FN)` where the first parameter is the ID.",
"SVGs are loaded as `const ISVG example = pGraphics->LoadSVG(EXAMPLE_FN)`.",
"Bitmaps can contain multiple textures stacked side by side as a sprite sheet which is either top to bottom or left to right.",
"Bitmaps can have multiple scales by using filenames like `example.png` and `example@2x.png`.",
"Bitmaps are loaded with `IBitmap IGraphics::LoadBitmap(const char* fileNameOrResID, int nStates=1, bool framesAreHorizontal=false, int targetScale=0)`.",
"Use `targetScale > 0` to explicitly load a higher-scale asset such as `@2x`."
],
"validate": [
"Validate built plugins with the format-specific tools instead of assuming a successful build means host compatibility.",
"The upstream skill uses `config.h` identifiers such as `PLUG_NAME`, `PLUG_UNIQUE_ID`, `PLUG_MFR_ID`, and `PLUG_TYPE` to drive the correct validator commands.",
"Capture validator output and report pass/fail per format so results are reproducible."
],
"validate au": [
"Use `auval` for AU validation. Derive the AU type from `PLUG_TYPE`: effect=`aufx`, instrument=`aumu`, MIDI effect=`aumf`.",
"The skill recommends restarting `AudioComponentRegistrar` before rerunning AU validation so changes are picked up cleanly.",
"For AUv3, ensure the host app/extension has been built and launched so the extension is registered before testing."
],
"validate clap": [
"Use `clap-validator validate <plugin.clap>` when CLAP support matters.",
"The skill notes useful options such as `--in-process` and `--only-failed` for faster focused debugging.",
"Treat descriptor and event-protocol failures as structural problems to fix before any broader tuning."
],
"validate pluginval": [
"Use `pluginval` as a broader stress and behavior check after the format-specific validator passes.",
"The upstream skill uses a strictness-based run such as `--strictness-level 5 --validate <plugin>`.",
"Pluginval is especially useful for catching lifecycle, state, and automation regressions that a simple build will miss."
],
"validate vst": [
"Use Steinberg's `validator` for VST3. The skills point to `Dependencies/IPlug/VST3_SDK/validator` or `validator.exe` after building or downloading it.",
"Run the validator against the installed `.vst3` bundle and treat failures as contract or packaging issues until proven otherwise.",
"If VST validation fails while APP passes, focus on format-specific glue first rather than shared DSP code."
],
"webview": [
"There are two distinct WebView patterns: a full web UI using `WebViewEditorDelegate`, or an embedded panel inside IGraphics using `IWebViewControl`. Do not mix their assumptions.",
"Full web UIs typically define `WEBVIEW_EDITOR_DELEGATE` and `NO_IGRAPHICS`, set up `mEditorInitFunc`, and load `resources/web/index.html` or a dev URL.",
"Use WebView when the user explicitly wants HTML/CSS/JS, a framework UI, or browser-style rendering. Stay in IGraphics otherwise."
],
"webview lifecycle": [
"For bundled UIs, `LoadIndexHtml(__FILE__, GetBundleID())` is the normal production path. For hot reload, switch to `LoadURL(\"http://localhost:5173/\")` or another dev server URL.",
"When the page finishes loading, iPlug2 automatically sends parameter metadata through `SAMFD` with `msgTag == -1`, then pushes live parameter values through `SPVFD` calls.",
"Just like IGraphics editors, WebView UIs can be reopened and rebuilt, so rehydrate UI state from plugin state instead of trusting browser-local transient state alone."
],
"webview protocol": [
"JS sends to C++ through the injected `IPlugSendMsg(...)` bridge. Core message types are `SPVFUI`, `BPCFUI`, `EPCFUI`, `SAMFUI`, and `SMMFUI`.",
"Parameter gestures must follow begin -> value updates -> end so DAW automation and undo behave correctly. `SPVFUI` values are normalized 0..1.",
"C++ calls back into global JS handlers such as `SPVFD`, `SCVFD`, `SCMFD`, `SAMFD`, and `SMMFD`. Define them explicitly in the web app.",
"Binary payloads are base64 encoded. `SAMFD(-1, ...)` is also used for the auto-sent parameter-info JSON blob."
],
"webview security": [
"Do not expose a vague command tunnel from JS into plugin code. Route only the message types and payload shapes the plugin actually needs.",
"Validate inbound JSON and binary payload assumptions before acting on them, especially for arbitrary messages and file-drop workflows.",
"If navigation matters, override `OnCanNavigateToURL(...)` to block or log unwanted page changes instead of letting the WebView roam freely."
]
}