@signalsandsorcery/plugin-sdk 2.0.2 → 2.24.1

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/README.md CHANGED
@@ -31,8 +31,8 @@ These built-in plugins serve as reference implementations:
31
31
  | Plugin | Type | Description | Source |
32
32
  |--------|------|-------------|--------|
33
33
  | Synth Generator | `midi` | AI-powered MIDI generation with Surge XT presets | [sas-synth-plugin](https://github.com/shiehn/sas-synth-plugin) |
34
- | Sample Player | `sample` | Sample library browser with time-stretching | [sas-sample-plugin](https://github.com/shiehn/sas-sample-plugin) |
35
- | Audio Texture | `audio` | AI audio texture generation | [sas-audio-plugin](https://github.com/shiehn/sas-audio-plugin) |
34
+ | Loops | `sample` | Audio loop / sample library browser with time-stretching | [sas-loops-plugin](https://github.com/shiehn/sas-loops-plugin) |
35
+ | Stems | `audio` | AI audio-from-text generation with optional stem splitting | [sas-stems-plugin](https://github.com/shiehn/sas-stems-plugin) |
36
36
 
37
37
  ## What's in the SDK
38
38
 
@@ -66,9 +66,36 @@ Pre-built components that match the host app's visual style:
66
66
  | `FxToggleBar` | Per-track FX control panel with 6 categories, 5 presets each, and dry/wet sliders |
67
67
  | `SorceryProgressBar` | Animated progress bar with time-based pacing for long operations |
68
68
  | `InstrumentDrawer` | Searchable grid of available VST3/AU instrument plugins |
69
+ | `DownloadPackButton` | Download/verify/extract button for a sample pack; driven through `host.startSamplePackDownload` + `host.onSamplePackProgress` (since 2.8.0) |
70
+ | `SamplePackCTACard` | Empty-state card a generator panel renders when its sample pack is missing or stale; wraps `DownloadPackButton` (since 2.8.0) |
71
+
72
+ **Waveform / audio-clip toolkit** *(since 2.10.0)* — shared by audio-oriented plugins (stems, recorder):
73
+
74
+ | Export | Kind | Description |
75
+ |--------|------|-------------|
76
+ | `WaveformView` | component | Static waveform render of an audio file (decodes + draws peaks) |
77
+ | `ScrollingWaveform` | component | Live scrolling waveform for input monitoring / recording |
78
+ | `LevelMeter` | component | Peak/RMS level meter |
79
+ | `OffsetScrubber` | component | Drag-to-offset clip start with beat tick marks + snap |
80
+ | `computePeaks` / `drawWaveform` | util | Peak math + canvas drawing (`WaveformPeaks`) |
81
+ | `analyzeWavPeak` | util | Peak analysis of a WAV (`PeakAnalysis`) |
82
+ | `synthesizeCuePoints` | util | Derive cue points from a clip (`SynthesizeCuePointsOptions`) |
69
83
 
70
84
  ```typescript
71
- import { TrackRow, VolumeSlider, PanSlider, FxToggleBar, SorceryProgressBar } from '@signalsandsorcery/plugin-sdk';
85
+ import {
86
+ TrackRow, VolumeSlider, PanSlider, FxToggleBar, SorceryProgressBar,
87
+ SamplePackCTACard, DownloadPackButton,
88
+ } from '@signalsandsorcery/plugin-sdk';
89
+
90
+ // SamplePackCTACard / DownloadPackButton take the `host` the plugin received
91
+ // and drive the download entirely through PluginHost — a plugin never reaches
92
+ // the app's renderer or window.electronAPI to manage its sample pack.
93
+ <SamplePackCTACard
94
+ host={host}
95
+ pack={{ packId: 'sas-drum-pack', displayName: 'Drum Sample Library', description: 'Kicks, snares, hats', sizeBytes: 100_934_888 }}
96
+ status={packStatus} // 'missing' | 'stale' | 'checking'
97
+ onDownloadComplete={refresh} // re-check pack status when the download finishes
98
+ />
72
99
  ```
73
100
 
74
101
  ### Hooks
@@ -84,13 +111,16 @@ const [prompts, setPrompts, setPromptsForScene] = useSceneState(activeSceneId, {
84
111
 
85
112
  ```typescript
86
113
  import {
87
- VALID_INSTRUMENT_ROLES, // ['bass', 'kick', 'snare', 'lead', 'pad', ...]
88
- PLUGIN_SDK_VERSION, // '1.0.0'
114
+ PLUGIN_SDK_VERSION, // '2.8.0'
89
115
  FX_CATEGORIES, // ['eq', 'compressor', 'chorus', 'phaser', 'delay', 'reverb']
90
116
  FX_PRESET_CONFIGS, // Preset definitions for all 6 FX categories
91
117
  } from '@signalsandsorcery/plugin-sdk';
92
118
  ```
93
119
 
120
+ > **Instrument roles are not a static export.** `VALID_INSTRUMENT_ROLES` was
121
+ > removed in SDK 2.0.0 — call `host.getValidRoles()` at runtime instead. The
122
+ > canonical role list lives in the host app, so plugins always see the current set.
123
+
94
124
  ## Quick Start
95
125
 
96
126
  ### 1. Create the manifest (`plugin.json`)
@@ -264,6 +294,27 @@ Six categories in signal chain order: `eq` > `compressor` > `chorus` > `phaser`
264
294
  | `getActiveSceneId()` | Current scene ID (synchronous) |
265
295
  | `getSceneList()` | All scenes in the project |
266
296
 
297
+ ### Sample Packs *(status methods since SDK 2.7.0; download/progress since 2.8.0)*
298
+ Versioned sample packs (drums, instruments, the loop/sample library) install on demand under `<userData>/samples/`. A plugin checks install state to decide between its normal UI and a "download library" CTA, then drives the download **through the host** — never `window.electronAPI`.
299
+
300
+ | Method | Description |
301
+ |--------|-------------|
302
+ | `getSamplePackRoot(packId)` | Absolute path to the installed pack root, or null if missing/stale |
303
+ | `isSamplePackCurrent(packId)` | True iff the installed version matches this build's expected version |
304
+ | `getSamplePackInstalledVersion(packId)` | Installed version string, or null if not installed |
305
+ | `startSamplePackDownload(packId)` | Trigger download + install; resolves `{ success, error? }` |
306
+ | `onSamplePackProgress(packId, listener)` | Subscribe to `{ status, progress }` updates; returns an unsubscribe fn |
307
+
308
+ ### Deck Playback *(since SDK 2.9.0)*
309
+ The two playback decks: `'loop-a'` (composition / cue, headphones) and `'loop-b'` (performance / main). These route through the **same host path the workstation UI uses**, so the deck mutual-exclusivity rules (the host's PlaybackRuleEngine) are enforced identically — a plugin can't bypass them. Used by playback-driven plugins (e.g. the recorder, which starts loop-a so a take has a backing loop). Available to renderer-hosted plugins.
310
+
311
+ | Method | Description |
312
+ |--------|-------------|
313
+ | `deckPlay(deckId, contentId?, contentType?)` | Start a deck playing a scene/transition (`contentType` defaults to `'scene'`); resolves `{ success, error?, code? }` |
314
+ | `deckStop(deckId)` | Stop a deck; resolves `{ success, error? }` |
315
+ | `onDeckStateChanged(listener)` | Subscribe to `{ deckId, property, value }` (e.g. `property: 'playing'`); returns an unsubscribe fn |
316
+ | `onAllDecksStopped(listener)` | Subscribe to the global "all decks stopped" event; returns an unsubscribe fn |
317
+
267
318
  ### Transport & Events
268
319
  | Method | Description |
269
320
  |--------|-------------|
@@ -373,8 +424,8 @@ All errors are `PluginError` instances with a typed `code` property:
373
424
 
374
425
  - **[Signals & Sorcery](https://signalsandsorcery.com)** — the flagship AI music production workstation
375
426
  - **[sas-synth-plugin](https://github.com/shiehn/sas-synth-plugin)** — AI MIDI generation with Surge XT
376
- - **[sas-sample-plugin](https://github.com/shiehn/sas-sample-plugin)** — Sample library browser with time-stretching
377
- - **[sas-audio-plugin](https://github.com/shiehn/sas-audio-plugin)** — AI audio texture generation
427
+ - **[sas-loops-plugin](https://github.com/shiehn/sas-loops-plugin)** — Audio loop / sample library browser with time-stretching
428
+ - **[sas-stems-plugin](https://github.com/shiehn/sas-stems-plugin)** — AI audio-from-text generation with stem splitting
378
429
  - **[DeclarAgent](https://github.com/shiehn/DeclarAgent)** — Declarative agent + MCP transport for S&S
379
430
 
380
431
  <p align="center">