@signalsandsorcery/plugin-sdk 2.38.2 → 2.40.2

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/dist/index.d.ts CHANGED
@@ -2676,6 +2676,12 @@ interface TrackDrawerProps {
2676
2676
  onImportSound?: () => void;
2677
2677
  /** Button label, e.g. "Import Sample" (drums/instruments) or "Import Preset" (synths). */
2678
2678
  importSoundLabel?: string;
2679
+ /**
2680
+ * Linked-group hint (@since SDK 2.48.0): shown in the drawer header on
2681
+ * every tab, e.g. "🔗 Sound changes apply to all 4 parts". Undefined
2682
+ * renders nothing (all single-track panels).
2683
+ */
2684
+ linkedSoundHint?: string;
2679
2685
  /** Current MIDI notes for the piano-roll editor. */
2680
2686
  editNotes?: readonly PluginMidiNote[];
2681
2687
  /** Persist edited notes; PRESENCE of this callback enables the Edit tab. */
@@ -2689,7 +2695,7 @@ interface TrackDrawerProps {
2689
2695
  /** Optional single-note preview when the user adds a note. */
2690
2696
  onAuditionNote?: (pitch: number, velocity: number, durationMs: number) => void;
2691
2697
  }
2692
- declare function TrackDrawer({ activeTab, onTabChange, trackId, fxState, onFxToggle, onFxPresetChange, onFxDryWetChange, fxDisabled, externalFxHost, freeze, instruments, currentPluginId, isLoading, onSelect, onRefresh, editorStage, onShowEditor, onBackToInstruments, selectedInstrumentName, soundHistory, soundHistoryCursor, onRestoreSound, onToggleFavorite, onImportSound, importSoundLabel, editNotes, onNotesChange, editBars, editBpm, editSnap, onAuditionNote, }: TrackDrawerProps): React$1.ReactElement;
2698
+ declare function TrackDrawer({ activeTab, onTabChange, trackId, fxState, onFxToggle, onFxPresetChange, onFxDryWetChange, fxDisabled, externalFxHost, freeze, instruments, currentPluginId, isLoading, onSelect, onRefresh, editorStage, onShowEditor, onBackToInstruments, selectedInstrumentName, soundHistory, soundHistoryCursor, onRestoreSound, onToggleFavorite, onImportSound, importSoundLabel, linkedSoundHint, editNotes, onNotesChange, editBars, editBpm, editSnap, onAuditionNote, }: TrackDrawerProps): React$1.ReactElement;
2693
2699
 
2694
2700
  /**
2695
2701
  * useTrackLevels — drives the cosmetic per-track strip meters.
@@ -2949,6 +2955,21 @@ interface SDKTrackRowProps {
2949
2955
  onImportSound?: () => void;
2950
2956
  /** Sound-import button label ("Import Sample" / "Import Preset"). */
2951
2957
  importSoundLabel?: string;
2958
+ /**
2959
+ * Linked-group hint (@since SDK 2.48.0): when set, the drawer shows this
2960
+ * info line on every tab and the Shuffle button gains a small 🔗 marker +
2961
+ * a title suffix. Undefined (all single-track panels) renders nothing.
2962
+ */
2963
+ linkedSoundHint?: string;
2964
+ /**
2965
+ * One-shot linked sync (@since SDK 2.48.0): presence renders a "→ All"
2966
+ * button next to Shuffle that pushes THIS row's current sound to every
2967
+ * linked sibling. The affordance for patch changes made inside a custom
2968
+ * plugin's own editor (Kontakt / Diva…), which fire no change event —
2969
+ * and the only sound-propagation control that works on such tracks,
2970
+ * since Shuffle is Surge-only.
2971
+ */
2972
+ onSyncSoundToGroup?: () => void;
2952
2973
  /** Current MIDI notes for the piano-roll editor (the 'edit' tab). */
2953
2974
  editNotes?: readonly PluginMidiNote[];
2954
2975
  /** Persist edited notes; PRESENCE of this callback enables the Edit tab. */
@@ -2968,7 +2989,7 @@ interface SDKTrackRowProps {
2968
2989
  * a thin peak meter welds to the bottom of the row. Omit to hide it. */
2969
2990
  levels?: TrackLevelsHandle;
2970
2991
  }
2971
- declare function TrackRow({ track, prompt, runtimeState, soloedOut, fxDetailState, drawerOpen, drawerTab, onTabChange, isGenerating, isAuthenticated, error, hasMidi, generationProgress, estimatedGenerationMs, onPromptChange, onGenerate, onShuffle, onCopy, onDelete, contentSlot, onMuteToggle, onSoloToggle, onVolumeChange, onPanChange, onFxToggle, onFxPresetChange, onFxDryWetChange, externalFxHost, onToggleFxDrawer, onProgressChange, accentColor, instrumentName, instrumentMissing, onToggleDrawer, availableInstruments, currentInstrumentPluginId, onInstrumentSelect, instrumentsLoading, onRefreshInstruments, editorStage, onShowEditor, onBackToInstruments, soundHistory, soundHistoryCursor, onRestoreSound, onToggleFavorite, onImportSound, importSoundLabel, editNotes, onNotesChange, editBars, editBpm, editSnap, onAuditionNote, drag, levels, }: SDKTrackRowProps): React$1.ReactElement;
2992
+ declare function TrackRow({ track, prompt, runtimeState, soloedOut, fxDetailState, drawerOpen, drawerTab, onTabChange, isGenerating, isAuthenticated, error, hasMidi, generationProgress, estimatedGenerationMs, onPromptChange, onGenerate, onShuffle, onCopy, onDelete, contentSlot, onMuteToggle, onSoloToggle, onVolumeChange, onPanChange, onFxToggle, onFxPresetChange, onFxDryWetChange, externalFxHost, onToggleFxDrawer, onProgressChange, accentColor, instrumentName, instrumentMissing, onToggleDrawer, availableInstruments, currentInstrumentPluginId, onInstrumentSelect, instrumentsLoading, onRefreshInstruments, editorStage, onShowEditor, onBackToInstruments, soundHistory, soundHistoryCursor, onRestoreSound, onToggleFavorite, onImportSound, importSoundLabel, linkedSoundHint, onSyncSoundToGroup, editNotes, onNotesChange, editBars, editBpm, editSnap, onAuditionNote, drag, levels, }: SDKTrackRowProps): React$1.ReactElement;
2972
2993
 
2973
2994
  /**
2974
2995
  * Crossfade-pair metadata — family-agnostic types + parsing shared by every
@@ -3838,6 +3859,29 @@ interface ConfirmDialogProps {
3838
3859
  }
3839
3860
  declare function ConfirmDialog({ open, title, message, confirmLabel, cancelLabel, destructive, onConfirm, onCancel, testIdPrefix, }: ConfirmDialogProps): React$1.ReactElement | null;
3840
3861
 
3862
+ /**
3863
+ * GroupCollapseChevron — the shared collapse/expand toggle for voice-group
3864
+ * header bars (ensemble / arp / bass / pad). One component so all four
3865
+ * headers look identical and plugins don't need their own lucide dep; the
3866
+ * state itself is owned by the shell's CollapsibleGroup wrapper and arrives
3867
+ * via GroupRenderContext (`ctx.collapsed` / `ctx.onToggleCollapse`).
3868
+ *
3869
+ * Renders nothing when `onToggle` is absent (pre-2.48 hosts / bare render
3870
+ * contexts), so plugins can mount it unconditionally.
3871
+ *
3872
+ * @since SDK 2.48.0
3873
+ */
3874
+
3875
+ interface GroupCollapseChevronProps {
3876
+ /** Whether the group's member rows are hidden. */
3877
+ collapsed?: boolean;
3878
+ /** Toggle handler (GroupRenderContext.onToggleCollapse). Absent ⇒ renders nothing. */
3879
+ onToggle?: () => void;
3880
+ /** Noun for the tooltip, e.g. "ensemble" → "Collapse ensemble". Default "group". */
3881
+ what?: string;
3882
+ }
3883
+ declare function GroupCollapseChevron({ collapsed, onToggle, what, }: GroupCollapseChevronProps): React$1.ReactElement | null;
3884
+
3841
3885
  /**
3842
3886
  * Modal — the SDK's one modal-stacking primitive (portal + z-tier + backdrop).
3843
3887
  *
@@ -4932,6 +4976,30 @@ interface PanelSoundAdapter {
4932
4976
  importNoun: string;
4933
4977
  /** History label for the lazily-seeded pre-shuffle sound, e.g. 'Previous preset'. */
4934
4978
  previousSoundLabel: string;
4979
+ /**
4980
+ * Linked-sound groups (@since SDK 2.48.0): the sibling tracks a sound
4981
+ * change on `track` should also apply to, or null/[] when the track is not
4982
+ * in a linked group (or the group's link toggle is OFF). Return ALL linked
4983
+ * members — the core filters: the source track is always dropped, and
4984
+ * preset-level broadcasts (shuffle / history-restore / sound-import) skip
4985
+ * siblings whose instrument differs from the source's (a Surge blob must
4986
+ * not land on Kontakt). Pick-tab instrument swaps broadcast to every
4987
+ * sibling unfiltered — that is what converges a mixed group.
4988
+ */
4989
+ broadcastTargets?(track: GeneratorTrackState, services: GenerationServices): Promise<Array<{
4990
+ engineId: string;
4991
+ dbId: string;
4992
+ label?: string;
4993
+ }> | null>;
4994
+ /**
4995
+ * Persist a descriptor as the track's DURABLE sound identity WITHOUT
4996
+ * re-applying it (the descriptor-space half of copySnapshot). The linked
4997
+ * broadcast calls it per target — and on the source after restore/import,
4998
+ * which apply live-only — so getTrackSound / transitions / agent tools
4999
+ * read the truth. Best-effort; families without a durable store omit it.
5000
+ * @since SDK 2.48.0
5001
+ */
5002
+ persistDescriptor?(trackId: string, descriptor: unknown, label: string): Promise<void>;
4935
5003
  }
4936
5004
  /** The 🎲: pick + apply one new sound, honoring the exclusion cycle. */
4937
5005
  interface PanelShuffleAdapter {
@@ -4971,6 +5039,12 @@ interface GenerationServices {
4971
5039
  createFamilyTrack(nameSuffix?: string): Promise<PluginTrackHandle>;
4972
5040
  /** Resolved groups for a registered group extension. */
4973
5041
  resolvedGroups<M>(metaKey: string): ResolvedTrackGroup<M, GeneratorTrackState>[];
5042
+ /**
5043
+ * The family sound adapter. Always present when built by the core's
5044
+ * makeServices; optional only for pre-2.48 hand-built test services.
5045
+ * @since SDK 2.48.0
5046
+ */
5047
+ sound?: PanelSoundAdapter;
4974
5048
  }
4975
5049
  /**
4976
5050
  * One prompt-driven generation turn. The core owns the wrapper: prompt/auth
@@ -4988,6 +5062,12 @@ interface CoreTrackHandlers {
4988
5062
  promptChange(trackId: string, prompt: string): void;
4989
5063
  generate(trackId: string): void;
4990
5064
  shuffle(trackId: string): void;
5065
+ /**
5066
+ * One-shot linked sync (@since SDK 2.48.0): broadcast the track's CURRENT
5067
+ * sound to its linked siblings — the affordance for patch changes made
5068
+ * inside a plugin's own editor (no change event to hook).
5069
+ */
5070
+ syncSoundToGroup(trackId: string): void;
4991
5071
  copy(trackId: string): void;
4992
5072
  delete(trackId: string): void;
4993
5073
  muteToggle(trackId: string): void;
@@ -5024,6 +5104,15 @@ interface GroupRenderContext {
5024
5104
  engineId: string;
5025
5105
  dbId: string;
5026
5106
  }>, cleanupKeySuffixes: string[]): Promise<void>;
5107
+ /**
5108
+ * Whether this group is visually collapsed (@since SDK 2.48.0). The shell
5109
+ * owns the state and persists it per group in scene-data
5110
+ * (`track:<groupId>:groupUi`); renderGroup wraps its member rows in
5111
+ * `{!ctx.collapsed && …}` and renders a GroupCollapseChevron in its header.
5112
+ */
5113
+ collapsed?: boolean;
5114
+ /** Toggle this group's collapsed state (persisted). @since SDK 2.48.0 */
5115
+ onToggleCollapse?: () => void;
5027
5116
  }
5028
5117
  /**
5029
5118
  * A family-registered multi-track group row (the crossfade seam,
@@ -5303,6 +5392,18 @@ interface GeneratorPanelCore {
5303
5392
  handlers: CoreTrackHandlers;
5304
5393
  handleGenerate(trackId: string): Promise<void>;
5305
5394
  handleShuffle(trackId: string): Promise<void>;
5395
+ /**
5396
+ * History-tab restore + linked-group broadcast (@since SDK 2.48.0) — the
5397
+ * shell wires this as every row's onRestoreSound. Identical to
5398
+ * soundHistory.restoreTo for panels without broadcastTargets.
5399
+ */
5400
+ handleRestoreSound(trackId: string, index: number): Promise<void>;
5401
+ /**
5402
+ * One-shot linked sync (@since SDK 2.48.0): capture the track's CURRENT
5403
+ * sound and broadcast it to its linked siblings — for edits made inside a
5404
+ * plugin's own editor, which fire no change event.
5405
+ */
5406
+ handleSyncSoundToGroup(trackId: string): Promise<void>;
5306
5407
  handleAddTrack(): Promise<void>;
5307
5408
  handleDeleteTrack(trackId: string): Promise<void>;
5308
5409
  handleExportMidi(): Promise<void>;
@@ -5380,22 +5481,127 @@ interface SurgeSoundAdapterOverrides {
5380
5481
  declare function createSurgeSoundAdapter(host: PluginHost, overrides?: SurgeSoundAdapterOverrides): PanelSoundAdapter;
5381
5482
 
5382
5483
  /**
5383
- * ensemble-core: voice specifications — the register + complexity hierarchy
5384
- * as DATA. The first live per-voice register map in the platform (the only
5385
- * prior per-role [low,high] table, MusicTheory.getSuggestedRegister, was
5386
- * dead code).
5484
+ * ensemble-core: style packs. A style = which SOFT rules are violations +
5485
+ * a prompt paragraph steering the joint composition. Hard rules (register,
5486
+ * per-voice monophony, density caps, root-only anchors) apply to every
5487
+ * style — see enforce-voice.ts. Explicitly NOT just baroque: parallels are
5488
+ * a defect in `counterpoint`, the whole point of `interlock`, and the very
5489
+ * mechanism of the horn-section styles (`stabs` / `riffs` / `unison`),
5490
+ * which additionally INVERT the coordination rule — togetherness is
5491
+ * required, not forbidden (`maxOnsetIndependence`).
5492
+ *
5493
+ * Which styles are offered under which parent instrumentation lives in
5494
+ * instrumentation.ts (STYLES_FOR_INSTRUMENTATION).
5495
+ *
5496
+ * @since SDK 2.42.0 (horn-section styles @since 2.39.0 — see instrumentation.ts)
5497
+ */
5498
+ type EnsembleStyle = 'counterpoint' | 'chorale' | 'interlock' | 'stabs' | 'riffs' | 'unison';
5499
+ /**
5500
+ * The WOVEN (strings/winds) trio. Kept under the historical name because
5501
+ * pre-instrumentation stored configs and consumers validate against it;
5502
+ * per-mode lists live in instrumentation.ts.
5503
+ */
5504
+ declare const ENSEMBLE_STYLES: readonly EnsembleStyle[];
5505
+ interface EnsembleStyleRules {
5506
+ /** Consecutive perfect 5ths/octaves between adjacent voices are violations. */
5507
+ forbidParallelPerfects: boolean;
5508
+ /** A nominally-upper voice sounding below its neighbor is a violation. */
5509
+ forbidVoiceCrossing: boolean;
5510
+ /**
5511
+ * Minimum fraction of an upper voice's onsets that must NOT coincide with
5512
+ * its lower neighbor (0 = homorhythm fine, 1 = fully independent).
5513
+ */
5514
+ minOnsetIndependence: number;
5515
+ /**
5516
+ * Section styles only: the CEILING on that same fraction — a pair whose
5517
+ * upper voice attacks apart from its lower neighbor more than this is a
5518
+ * violation (the section must hit together). Absent = no ceiling.
5519
+ */
5520
+ maxOnsetIndependence?: number;
5521
+ /**
5522
+ * Mechanical per-note duration ceiling in beats, enforced by
5523
+ * enforceVoice (stab styles — a punch must not become a pad). Absent =
5524
+ * no cap.
5525
+ */
5526
+ maxNoteDurationBeats?: number;
5527
+ /** Prompt paragraph injected into the system prompt for this style. */
5528
+ promptParagraph: string;
5529
+ }
5530
+ /**
5531
+ * Section-style togetherness ceilings + the stab length, exported in the
5532
+ * bass-plugin tradition — tune by ear, not by refactor. Independence is the
5533
+ * fraction of an upper voice's onsets its lower neighbor does NOT share:
5534
+ * 0.25 tolerates a stray pickup note per phrase, 0.15 demands lockstep.
5535
+ */
5536
+ declare const STAB_MAX_ONSET_INDEPENDENCE = 0.25;
5537
+ declare const RIFF_MAX_ONSET_INDEPENDENCE = 0.3;
5538
+ declare const UNISON_MAX_ONSET_INDEPENDENCE = 0.15;
5539
+ /** A stab longer than a quarter note is a pad — mechanically trimmed. */
5540
+ declare const STAB_MAX_NOTE_DURATION_BEATS = 1;
5541
+ declare const STYLE_RULES: Record<EnsembleStyle, EnsembleStyleRules>;
5542
+
5543
+ /**
5544
+ * ensemble-core: the INSTRUMENTATION axis — which family of ensemble the
5545
+ * voices model. The parent selection gates the style list (a funk horn
5546
+ * section has no 'chorale'; a string ensemble has no 'stabs') and picks the
5547
+ * voice-spec table (registers, roles, rhythm palettes — see voice-spec.ts).
5548
+ *
5549
+ * Sound coupling stays category-level ONLY: specs stamp the generally
5550
+ * correct role ('strings' / 'brass' / 'winds') and registers use REAL
5551
+ * instrument ranges — users routinely swap the placeholder Surge XT patch
5552
+ * for a sampled library (Kontakt, Omnisphere), so the written MIDI must sit
5553
+ * where real sections play, not where any particular synth patch flatters.
5387
5554
  *
5388
- * The shape encodes the product intent: the TOP voice is the highest-pitched
5389
- * and most complex line; complexity decreases with register; the bottom
5390
- * voice is a sparse anchor (root pitch classes only when `rootOnly`).
5555
+ * @since SDK 2.39.0
5556
+ */
5557
+
5558
+ type EnsembleInstrumentation = 'strings' | 'horns' | 'winds';
5559
+ declare const ENSEMBLE_INSTRUMENTATIONS: readonly EnsembleInstrumentation[];
5560
+ /**
5561
+ * Styles selectable under each parent instrumentation. Strings and winds
5562
+ * share the WOVEN trio (independent/held-line writing); horns get the
5563
+ * SECTION trio (rhythmic-unison funk writing) — the two families obey
5564
+ * opposite coordination rules (see ensemble-prompt.ts).
5565
+ */
5566
+ declare const STYLES_FOR_INSTRUMENTATION: Record<EnsembleInstrumentation, readonly EnsembleStyle[]>;
5567
+ declare const DEFAULT_STYLE_FOR_INSTRUMENTATION: Record<EnsembleInstrumentation, EnsembleStyle>;
5568
+ /** Clamp an arbitrary stored/hinted value into the closed instrumentation domain. */
5569
+ declare function normalizeInstrumentation(raw: unknown): EnsembleInstrumentation;
5570
+ /**
5571
+ * Clamp a stored/hinted style into the instrumentation's own list — a group
5572
+ * switched from Strings to Horns with 'counterpoint' still stored lands on
5573
+ * the horn default instead of a style the mode can't honor.
5574
+ */
5575
+ declare function styleForInstrumentation(instrumentation: EnsembleInstrumentation, rawStyle: string | undefined | null): EnsembleStyle;
5576
+
5577
+ /**
5578
+ * ensemble-core: voice specifications — the register + complexity hierarchy
5579
+ * as DATA, one table set per INSTRUMENTATION (see instrumentation.ts). The
5580
+ * first live per-voice register map in the platform (the only prior
5581
+ * per-role [low,high] table, MusicTheory.getSuggestedRegister, was dead
5582
+ * code).
5583
+ *
5584
+ * The WOVEN families (strings, winds) encode the original product intent:
5585
+ * the TOP voice is the highest-pitched and most complex line; complexity
5586
+ * decreases with register; the bottom voice is a sparse anchor. The
5587
+ * SECTION family (horns) deliberately breaks that pyramid: every player
5588
+ * shares the lead's rhythm, so caps are EQUAL and generous — density
5589
+ * thinning is a runaway guard there, never a shaping tool (unequal caps
5590
+ * would punch holes in unison hits).
5591
+ *
5592
+ * Horn/wind registers are REAL instrument ranges in concert pitch
5593
+ * (comfortable working tessitura, not extremes) — the Surge XT patch is a
5594
+ * placeholder and users re-target sampled libraries, so the MIDI must sit
5595
+ * where actual sections play.
5391
5596
  *
5392
5597
  * All thresholds are exported constants in the bass-plugin tradition —
5393
5598
  * tune by ear, not by refactor. Roles are plain strings validated by the
5394
5599
  * host at stamp time (`host.getValidRoles()`); the SDK deliberately ships
5395
5600
  * no role list.
5396
5601
  *
5397
- * @since SDK 2.42.0
5602
+ * @since SDK 2.42.0 (horns/winds tables @since 2.39.0)
5398
5603
  */
5604
+
5399
5605
  interface EnsembleVoiceSpec {
5400
5606
  /** 0 = top voice; increases downward. */
5401
5607
  voiceIndex: number;
@@ -5421,16 +5627,19 @@ interface EnsembleVoiceSpec {
5421
5627
  */
5422
5628
  monoPreference: 'high' | 'low';
5423
5629
  }
5630
+ /** Equal per-voice cap for horn tables — a runaway guard, not a shaper. */
5631
+ declare const HORN_MAX_NOTES_PER_BAR = 12;
5424
5632
  /** Supported ensemble sizes. */
5425
5633
  declare const ENSEMBLE_MIN_VOICES = 2;
5426
5634
  declare const ENSEMBLE_MAX_VOICES = 6;
5427
5635
  /**
5428
- * Default voice specs for an N-voice ensemble, top voice first. Clamps N to
5429
- * the supported range. Returned objects are fresh copies — callers may
5430
- * override fields (e.g. style packs narrowing registers) without touching
5431
- * the tables.
5636
+ * Default voice specs for an N-voice ensemble of the given instrumentation,
5637
+ * top voice first. Clamps N to the supported range; instrumentation
5638
+ * defaults to 'strings' (the pre-instrumentation behavior, unchanged).
5639
+ * Returned objects are fresh copies — callers may override fields (e.g.
5640
+ * style packs narrowing registers) without touching the tables.
5432
5641
  */
5433
- declare function defaultVoiceSpecs(voiceCount: number): EnsembleVoiceSpec[];
5642
+ declare function defaultVoiceSpecs(voiceCount: number, instrumentation?: EnsembleInstrumentation): EnsembleVoiceSpec[];
5434
5643
 
5435
5644
  /**
5436
5645
  * ensemble-core: HARD per-voice enforcement — the mechanical layer between
@@ -5476,6 +5685,12 @@ interface EnforceVoiceOptions {
5476
5685
  scalePcs?: ReadonlySet<number>;
5477
5686
  /** Chord-tone pitch classes for a bar — exemptions for the scale snap. */
5478
5687
  chordPcsAtBar?: (bar: number) => ReadonlySet<number> | null;
5688
+ /**
5689
+ * Style-level per-note duration ceiling in beats (stab styles — see
5690
+ * STYLE_RULES[*].maxNoteDurationBeats). A punch must not become a pad;
5691
+ * longer notes are trimmed, never dropped.
5692
+ */
5693
+ maxNoteDurationBeats?: number;
5479
5694
  }
5480
5695
  interface EnforceVoiceResult {
5481
5696
  notes: EnsembleNote[];
@@ -5541,34 +5756,10 @@ declare function describeViolations(analysis: EnsembleAnalysis, rules: {
5541
5756
  forbidParallelPerfects: boolean;
5542
5757
  forbidVoiceCrossing: boolean;
5543
5758
  minOnsetIndependence: number;
5759
+ /** Section styles: independence ABOVE this is the violation (see styles.ts). */
5760
+ maxOnsetIndependence?: number;
5544
5761
  }): string[];
5545
5762
 
5546
- /**
5547
- * ensemble-core: style packs. A style = which SOFT rules are violations +
5548
- * a prompt paragraph steering the joint composition. Hard rules (register,
5549
- * per-voice monophony, density caps, root-only anchors) apply to every
5550
- * style — see enforce-voice.ts. Explicitly NOT just baroque: parallels are
5551
- * a defect in `counterpoint` and the whole point of `interlock`.
5552
- *
5553
- * @since SDK 2.42.0
5554
- */
5555
- type EnsembleStyle = 'counterpoint' | 'chorale' | 'interlock';
5556
- declare const ENSEMBLE_STYLES: readonly EnsembleStyle[];
5557
- interface EnsembleStyleRules {
5558
- /** Consecutive perfect 5ths/octaves between adjacent voices are violations. */
5559
- forbidParallelPerfects: boolean;
5560
- /** A nominally-upper voice sounding below its neighbor is a violation. */
5561
- forbidVoiceCrossing: boolean;
5562
- /**
5563
- * Minimum fraction of an upper voice's onsets that must NOT coincide with
5564
- * its lower neighbor (0 = homorhythm fine, 1 = fully independent).
5565
- */
5566
- minOnsetIndependence: number;
5567
- /** Prompt paragraph injected into the system prompt for this style. */
5568
- promptParagraph: string;
5569
- }
5570
- declare const STYLE_RULES: Record<EnsembleStyle, EnsembleStyleRules>;
5571
-
5572
5763
  /**
5573
5764
  * ensemble-core: the `submit_ensemble` function-calling contract — how the
5574
5765
  * ONE joint LLM call returns all voices as structured JSON. Built for
@@ -5604,21 +5795,30 @@ declare function parseEnsembleArgs(args: unknown, voiceCount: number): ParsedEns
5604
5795
 
5605
5796
  /**
5606
5797
  * ensemble-core: the joint-composition system prompt. ONE call composes ALL
5607
- * voices together — the coordination (imitation, staggered entrances,
5608
- * contrary motion) has to be planned across voices, which is exactly what
5609
- * per-track generation can never do. Mirrors the bass plugin's prompt
5610
- * discipline: numbered load-bearing rules, register/density contracts
5611
- * stated per voice, sound selection nowhere in sight (that stays
5798
+ * voices together — the coordination has to be planned across voices, which
5799
+ * is exactly what per-track generation can never do. Mirrors the bass
5800
+ * plugin's prompt discipline: numbered load-bearing rules, register/density
5801
+ * contracts stated per voice, sound selection nowhere in sight (that stays
5612
5802
  * mechanical, host-side).
5613
5803
  *
5804
+ * The numbered rules are INSTRUMENTATION-dependent — the two families obey
5805
+ * opposite coordination physics:
5806
+ *
5807
+ * WOVEN (strings, winds): independent lines that converse — imitation,
5808
+ * contrary motion, staggered entrances, avoid attacking together.
5809
+ *
5810
+ * SECTION (horns): one instrument with many bells — every voice attacks
5811
+ * WITH the lead, voiced under it, short and syncopated, biased hard
5812
+ * toward dance/funk (James Brown stabs, rhythmic punches).
5813
+ *
5614
5814
  * The musical context (key/BPM/chords/contract) arrives via the host's
5615
- * generateWithLLM(Tools) auto-prefix — this prompt states the ENSEMBLE
5815
+ * generateWithLLM(Tools) auto-prefix — this prompt states the ensemble
5616
5816
  * rules and the per-voice contracts only.
5617
5817
  *
5618
- * @since SDK 2.42.0
5818
+ * @since SDK 2.42.0 (section rules @since 2.39.0)
5619
5819
  */
5620
5820
 
5621
- declare function buildEnsembleSystemPrompt(specs: readonly EnsembleVoiceSpec[], style: EnsembleStyle): string;
5821
+ declare function buildEnsembleSystemPrompt(specs: readonly EnsembleVoiceSpec[], style: EnsembleStyle, instrumentation?: EnsembleInstrumentation): string;
5622
5822
  /**
5623
5823
  * Build the retry user-message suffix from soft-rule violations — one
5624
5824
  * guided second attempt, quota-conscious (callers should not loop).
@@ -5837,4 +6037,4 @@ interface PickTopKOptions {
5837
6037
  */
5838
6038
  declare function pickTopKWeighted<T>(scored: ReadonlyArray<ScoredCandidate<T>>, options?: PickTopKOptions): T | null;
5839
6039
 
5840
- export { AUDIO_EFFECTS, AUDIO_EFFECT_LABEL, type AdjacentPairAnalysis, type AudioEffect, type AudioInputDevice, type BulkAddPlaceholderTrack, type ComposeProgressEvent, type ComposeProgressListener, type ComposeSceneOptions, type ComposeSceneResult, ConfirmDialog, type ConfirmDialogProps, type CoreTrackHandlers, type CreateTrackOptions, type CrossfadeInpaintInput, type CrossfadeLayer, type CrossfadeMeta, CrossfadeModal, type CrossfadeModalProps, type CrossfadePairMeta, type CrossfadeSelection, type CrossfadeSlot, CrossfadeTrackRow, type CrossfadeTrackRowProps, type CrossfadeVolumeCurves, DB_MAX, DB_MIN, DEFAULT_FX_CATEGORY_DETAIL, DEFAULT_FX_DRY_WET, DRAG_DEAD_ZONE, type DeckBoundaryEvent, type DeckBoundaryListener, type DesignerRowSlots, DownloadPackButton, type DownloadPackButtonProps, type DownloadPackButtonVariant, type DrawerTab, type DrumKit, EMPTY_FX_DETAIL_STATE, EMPTY_FX_STATE, ENSEMBLE_MAX_VOICES, ENSEMBLE_MIN_VOICES, ENSEMBLE_STYLES, EQUAL_POWER_GAIN, type EnforceVoiceOptions, type EnforceVoiceResult, type EnsembleAnalysis, type EnsembleNote, type EnsembleStyle, type EnsembleStyleRules, type EnsembleVoiceSpec, type ExportMidiBundleOptions, type ExportMidiBundleResult, type ExportedPluginData, FX_CATEGORIES, FX_CHAIN_ORDER, FX_DISPLAY_LABELS, FX_ENGINE_PLUGIN_NAMES, FX_PRESET_CONFIGS, type FadeDirection, type FadeEntry, type FadeGesture, type FadeLayer, type FadeMeta, FadeModal, type FadeModalProps, type FadeSelection, FadeTrackRow, type FadeTrackRowProps, type FreezeDep, type FxCategory, type FxCategoryDetailState, type FxPreset, type FxPresetConfig, type FxPresetData, type FxPresetDataEntry, FxToggleBar, type FxToggleBarProps, GUTTER_W, type GenerationServices, type GeneratorPanelAdapter, type GeneratorPanelCore, GeneratorPanelShell, type GeneratorPanelShellProps, type GeneratorPanelSlots, type GeneratorPlugin, type GeneratorTrackState, type GeneratorType, type GroupFadeEntry, type GroupFadeEntryOf, type GroupFadeMemberLayer, GroupFadeTrackRow, type GroupFadeTrackRowProps, type GroupParseSpec, type GroupRenderContext, type ImportCandidateScene, type ImportCandidateTrack, ImportTrackModal, type ImportTrackModalProps, type InstrumentDescriptor, TrackDrawer as InstrumentDrawer, type TrackDrawerProps as InstrumentDrawerProps, type InstrumentSampler, type InstrumentZone, type LLMCandidate, type LLMContent, type LLMFunctionDeclaration, type LLMGenerationConfig, type LLMGenerationRequest, type LLMGenerationResult, type LLMNoteResponse, type LLMPart, type LLMSystemInstruction, type LLMTool, type LLMToolUseRequest, type LLMToolUseResponse, type LLMUsageMetadata, LevelMeter, type LevelMeterProps, type ListAudioFilesOptions, type ListImportableTracksOptions, MIN_NOTE_DURATION_BEATS, type MidiClipData, type MidiWriteResult, type MixInterpolation, Modal, type ModalProps, type MotionKind, type MusicalContext, OffsetScrubber, type OffsetScrubberProps, PLUGIN_SDK_VERSION, PX_PER_BEAT, PanSlider, type PanelBusFxEntry, type PanelBusLevels, type PanelBusState, type PanelFeatureFlags, type PanelGenerationStrategy, type PanelGroupExtension, type PanelIdentity, PanelMasterStrip, type PanelMasterStripProps, type PanelShuffleAdapter, type PanelSoundAdapter, type PanelTransitionGroupAdapter, type ParsedEnsemble, type PeakAnalysis, PianoRollEditor, type PianoRollEditorProps, type PickTopKOptions, type PluginAppTool, type PluginAppToolInputSchema, type PluginAppToolResult, type PluginAudioTextureRequest, type PluginAudioTextureResult, type PluginCapabilities, type PluginChordSegment, type PluginChordTiming, type PluginConcurrentTrackInfo, type PluginCuePoints, type PluginDownloadOptions, PluginError, type PluginErrorCode, type PluginFileDialogOptions, type PluginFxCategoryDetailState, type PluginGenerationContext, type PluginGenerationContextOptions, type PluginHost, type PluginHttpRequestOptions, type PluginHttpResponse, type PluginManifest, type PluginMidiNote, type PluginPresetData, type PluginPresetInfo, type PluginRegistration, type PluginSampleFilter, type PluginSampleImportResult, type PluginSampleInfo, type PluginSampleTrackInfo, type PluginSceneContext, type PluginSceneInfo, type PluginSettingsSchema, type PluginSettingsStore, type PluginSkill, type PluginSkillInputSchema, type PluginStatus, type PluginStemSplitResult, type PluginStemTrackInfo, type PluginSynthInfo, type PluginTrackFxDetailState, type PluginTrackHandle, type PluginTrackInfo, type PluginTrackLevel, type PluginTrackRuntimeState, type PluginTransportState, type PluginTrimWindow, type PluginUIProps, type PostProcessOptions, RESIZE_HANDLE_PX, ROW_HEIGHT, type ReadMidiClip, type ReadMidiResult, type RecordingChunkFinalizedEvent, type RecordingTargetInfo, type ResolveGroupsOptions, type ResolvedCrossfadePair, type ResolvedFade, type ResolvedGroupFade, type ResolvedGroupsResult, type ResolvedTrackGroup, type SDKTrackRowProps, SLIDER_UNITY, STYLE_RULES, SUBMIT_ENSEMBLE_TOOL_NAME, SamplePackCTACard, type SamplePackCTACardProps, type SamplePackCTACardStatus, type SamplePackCardInfo, type SavePluginPresetOptions, type SceneChangeListener, type SceneFamilyTrack, type SceneTrackSummary, type ScoredCandidate, ScrollingWaveform, type ScrollingWaveformProps, type SettingDefinition, type ShufflePresetOptions, type ShufflePresetResult, SorceryProgressBar, type SoundHistoryEntry, type StemType, type SurgeSoundAdapterOverrides, type SurgeXtStatus, type SynthesizeCuePointsOptions, TEXTURAL_ROLES, TRANSITION_DESIGNER_DRAFT_KEY, type TrackCreatedContext, TrackDrawer, type TrackDrawerProps, type TrackExternalFxEntry, TrackExternalFxSection, type TrackExternalFxSectionProps, TrackFreezeSection, type TrackFreezeSectionProps, type TrackFreezeState, type TrackFxDetailState, type TrackFxState, type TrackGroupMember, type TrackGroupMeta, type TrackLevelsHandle, TrackMeterStrip, type TrackMeterStripProps, type TrackMeterView, TrackRow, type TrackRowDragProps, type TrackSoundHistory, type TrackSoundSnapshot, type TrackStateChangeListener, TransitionDesigner, type TransitionDesignerDraft, type TransitionDesignerProps, type TransitionOps, type TransitionRowType, type TransportEvent, type TransportEventListener, type UnsubscribeFn, type UseGeneratorPanelCoreOptions, type UsePanelBusResult, type UseSoundHistoryOptions, type UseSoundHistoryResult, type UseTrackExternalFxResult, type UseTrackFreezeResult, type UseTrackReorderOptions, type UseTrackReorderResult, type UseTransitionOpsInputs, type VerbatimFadeMember, type VolumeAutomationPoint, VolumeSlider, type WaveformPeaks, WaveformView, type WaveformViewProps, analyzeEnsemble, analyzeWavPeak, asAudioEffect, asCrossfadeMeta, asFadeMeta, asTransitionDesignerDraft, buildCrossfadeInpaintPrompt, buildCrossfadeVolumeCurves, buildEnsembleSystemPrompt, buildFadeVolumeCurve, buildRowSlots, buildSubmitEnsembleParameters, buildViolationRetrySuffix, calculateTimeBasedTarget, cellToPx, centerScrollTop, computePeaks, createSurgeSoundAdapter, dbIdsFromKeys, dbToSlider, defaultFadeGesture, defaultVoiceSpecs, describeViolations, drawWaveform, effectivePxPerBeat, enforceVoice, foldPitchToRegister, formatConcurrentTracks, hashString, moveItem, nearestPitchWithPc, newTrackState, normalizeSlots, padPair, padSlots, parseCrossfadePairs, parseEnsembleArgs, parseFades, parseLLMNoteResponse, parseTrackGroups, pickTopKWeighted, pitchToName, pluginFxToToggleFx, promptEnterToGenerate, pxToCell, reconcileSlots, resizeNoteDuration, resolveTrackGroups, rowKey, rowType, scorePromptMatch, sliderToDb, slotsEqual, soundIdentity, splitFadeEntries, synthesizeCuePoints, tokenizePrompt, trackDataKey, transposeNotes, useAnySolo, useGeneratorPanelCore, usePanelBus, useSceneState, useSoundHistory, useTrackExternalFx, useTrackFreeze, useTrackLevel, useTrackLevels, useTrackMeter, useTrackReorder, useTransitionOps, useTransportPlaying };
6040
+ export { AUDIO_EFFECTS, AUDIO_EFFECT_LABEL, type AdjacentPairAnalysis, type AudioEffect, type AudioInputDevice, type BulkAddPlaceholderTrack, type ComposeProgressEvent, type ComposeProgressListener, type ComposeSceneOptions, type ComposeSceneResult, ConfirmDialog, type ConfirmDialogProps, type CoreTrackHandlers, type CreateTrackOptions, type CrossfadeInpaintInput, type CrossfadeLayer, type CrossfadeMeta, CrossfadeModal, type CrossfadeModalProps, type CrossfadePairMeta, type CrossfadeSelection, type CrossfadeSlot, CrossfadeTrackRow, type CrossfadeTrackRowProps, type CrossfadeVolumeCurves, DB_MAX, DB_MIN, DEFAULT_FX_CATEGORY_DETAIL, DEFAULT_FX_DRY_WET, DEFAULT_STYLE_FOR_INSTRUMENTATION, DRAG_DEAD_ZONE, type DeckBoundaryEvent, type DeckBoundaryListener, type DesignerRowSlots, DownloadPackButton, type DownloadPackButtonProps, type DownloadPackButtonVariant, type DrawerTab, type DrumKit, EMPTY_FX_DETAIL_STATE, EMPTY_FX_STATE, ENSEMBLE_INSTRUMENTATIONS, ENSEMBLE_MAX_VOICES, ENSEMBLE_MIN_VOICES, ENSEMBLE_STYLES, EQUAL_POWER_GAIN, type EnforceVoiceOptions, type EnforceVoiceResult, type EnsembleAnalysis, type EnsembleInstrumentation, type EnsembleNote, type EnsembleStyle, type EnsembleStyleRules, type EnsembleVoiceSpec, type ExportMidiBundleOptions, type ExportMidiBundleResult, type ExportedPluginData, FX_CATEGORIES, FX_CHAIN_ORDER, FX_DISPLAY_LABELS, FX_ENGINE_PLUGIN_NAMES, FX_PRESET_CONFIGS, type FadeDirection, type FadeEntry, type FadeGesture, type FadeLayer, type FadeMeta, FadeModal, type FadeModalProps, type FadeSelection, FadeTrackRow, type FadeTrackRowProps, type FreezeDep, type FxCategory, type FxCategoryDetailState, type FxPreset, type FxPresetConfig, type FxPresetData, type FxPresetDataEntry, FxToggleBar, type FxToggleBarProps, GUTTER_W, type GenerationServices, type GeneratorPanelAdapter, type GeneratorPanelCore, GeneratorPanelShell, type GeneratorPanelShellProps, type GeneratorPanelSlots, type GeneratorPlugin, type GeneratorTrackState, type GeneratorType, GroupCollapseChevron, type GroupCollapseChevronProps, type GroupFadeEntry, type GroupFadeEntryOf, type GroupFadeMemberLayer, GroupFadeTrackRow, type GroupFadeTrackRowProps, type GroupParseSpec, type GroupRenderContext, HORN_MAX_NOTES_PER_BAR, type ImportCandidateScene, type ImportCandidateTrack, ImportTrackModal, type ImportTrackModalProps, type InstrumentDescriptor, TrackDrawer as InstrumentDrawer, type TrackDrawerProps as InstrumentDrawerProps, type InstrumentSampler, type InstrumentZone, type LLMCandidate, type LLMContent, type LLMFunctionDeclaration, type LLMGenerationConfig, type LLMGenerationRequest, type LLMGenerationResult, type LLMNoteResponse, type LLMPart, type LLMSystemInstruction, type LLMTool, type LLMToolUseRequest, type LLMToolUseResponse, type LLMUsageMetadata, LevelMeter, type LevelMeterProps, type ListAudioFilesOptions, type ListImportableTracksOptions, MIN_NOTE_DURATION_BEATS, type MidiClipData, type MidiWriteResult, type MixInterpolation, Modal, type ModalProps, type MotionKind, type MusicalContext, OffsetScrubber, type OffsetScrubberProps, PLUGIN_SDK_VERSION, PX_PER_BEAT, PanSlider, type PanelBusFxEntry, type PanelBusLevels, type PanelBusState, type PanelFeatureFlags, type PanelGenerationStrategy, type PanelGroupExtension, type PanelIdentity, PanelMasterStrip, type PanelMasterStripProps, type PanelShuffleAdapter, type PanelSoundAdapter, type PanelTransitionGroupAdapter, type ParsedEnsemble, type PeakAnalysis, PianoRollEditor, type PianoRollEditorProps, type PickTopKOptions, type PluginAppTool, type PluginAppToolInputSchema, type PluginAppToolResult, type PluginAudioTextureRequest, type PluginAudioTextureResult, type PluginCapabilities, type PluginChordSegment, type PluginChordTiming, type PluginConcurrentTrackInfo, type PluginCuePoints, type PluginDownloadOptions, PluginError, type PluginErrorCode, type PluginFileDialogOptions, type PluginFxCategoryDetailState, type PluginGenerationContext, type PluginGenerationContextOptions, type PluginHost, type PluginHttpRequestOptions, type PluginHttpResponse, type PluginManifest, type PluginMidiNote, type PluginPresetData, type PluginPresetInfo, type PluginRegistration, type PluginSampleFilter, type PluginSampleImportResult, type PluginSampleInfo, type PluginSampleTrackInfo, type PluginSceneContext, type PluginSceneInfo, type PluginSettingsSchema, type PluginSettingsStore, type PluginSkill, type PluginSkillInputSchema, type PluginStatus, type PluginStemSplitResult, type PluginStemTrackInfo, type PluginSynthInfo, type PluginTrackFxDetailState, type PluginTrackHandle, type PluginTrackInfo, type PluginTrackLevel, type PluginTrackRuntimeState, type PluginTransportState, type PluginTrimWindow, type PluginUIProps, type PostProcessOptions, RESIZE_HANDLE_PX, RIFF_MAX_ONSET_INDEPENDENCE, ROW_HEIGHT, type ReadMidiClip, type ReadMidiResult, type RecordingChunkFinalizedEvent, type RecordingTargetInfo, type ResolveGroupsOptions, type ResolvedCrossfadePair, type ResolvedFade, type ResolvedGroupFade, type ResolvedGroupsResult, type ResolvedTrackGroup, type SDKTrackRowProps, SLIDER_UNITY, STAB_MAX_NOTE_DURATION_BEATS, STAB_MAX_ONSET_INDEPENDENCE, STYLES_FOR_INSTRUMENTATION, STYLE_RULES, SUBMIT_ENSEMBLE_TOOL_NAME, SamplePackCTACard, type SamplePackCTACardProps, type SamplePackCTACardStatus, type SamplePackCardInfo, type SavePluginPresetOptions, type SceneChangeListener, type SceneFamilyTrack, type SceneTrackSummary, type ScoredCandidate, ScrollingWaveform, type ScrollingWaveformProps, type SettingDefinition, type ShufflePresetOptions, type ShufflePresetResult, SorceryProgressBar, type SoundHistoryEntry, type StemType, type SurgeSoundAdapterOverrides, type SurgeXtStatus, type SynthesizeCuePointsOptions, TEXTURAL_ROLES, TRANSITION_DESIGNER_DRAFT_KEY, type TrackCreatedContext, TrackDrawer, type TrackDrawerProps, type TrackExternalFxEntry, TrackExternalFxSection, type TrackExternalFxSectionProps, TrackFreezeSection, type TrackFreezeSectionProps, type TrackFreezeState, type TrackFxDetailState, type TrackFxState, type TrackGroupMember, type TrackGroupMeta, type TrackLevelsHandle, TrackMeterStrip, type TrackMeterStripProps, type TrackMeterView, TrackRow, type TrackRowDragProps, type TrackSoundHistory, type TrackSoundSnapshot, type TrackStateChangeListener, TransitionDesigner, type TransitionDesignerDraft, type TransitionDesignerProps, type TransitionOps, type TransitionRowType, type TransportEvent, type TransportEventListener, UNISON_MAX_ONSET_INDEPENDENCE, type UnsubscribeFn, type UseGeneratorPanelCoreOptions, type UsePanelBusResult, type UseSoundHistoryOptions, type UseSoundHistoryResult, type UseTrackExternalFxResult, type UseTrackFreezeResult, type UseTrackReorderOptions, type UseTrackReorderResult, type UseTransitionOpsInputs, type VerbatimFadeMember, type VolumeAutomationPoint, VolumeSlider, type WaveformPeaks, WaveformView, type WaveformViewProps, analyzeEnsemble, analyzeWavPeak, asAudioEffect, asCrossfadeMeta, asFadeMeta, asTransitionDesignerDraft, buildCrossfadeInpaintPrompt, buildCrossfadeVolumeCurves, buildEnsembleSystemPrompt, buildFadeVolumeCurve, buildRowSlots, buildSubmitEnsembleParameters, buildViolationRetrySuffix, calculateTimeBasedTarget, cellToPx, centerScrollTop, computePeaks, createSurgeSoundAdapter, dbIdsFromKeys, dbToSlider, defaultFadeGesture, defaultVoiceSpecs, describeViolations, drawWaveform, effectivePxPerBeat, enforceVoice, foldPitchToRegister, formatConcurrentTracks, hashString, moveItem, nearestPitchWithPc, newTrackState, normalizeInstrumentation, normalizeSlots, padPair, padSlots, parseCrossfadePairs, parseEnsembleArgs, parseFades, parseLLMNoteResponse, parseTrackGroups, pickTopKWeighted, pitchToName, pluginFxToToggleFx, promptEnterToGenerate, pxToCell, reconcileSlots, resizeNoteDuration, resolveTrackGroups, rowKey, rowType, scorePromptMatch, sliderToDb, slotsEqual, soundIdentity, splitFadeEntries, styleForInstrumentation, synthesizeCuePoints, tokenizePrompt, trackDataKey, transposeNotes, useAnySolo, useGeneratorPanelCore, usePanelBus, useSceneState, useSoundHistory, useTrackExternalFx, useTrackFreeze, useTrackLevel, useTrackLevels, useTrackMeter, useTrackReorder, useTransitionOps, useTransportPlaying };