@signalsandsorcery/plugin-sdk 2.38.2 → 2.40.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/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,12 @@ 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;
2952
2964
  /** Current MIDI notes for the piano-roll editor (the 'edit' tab). */
2953
2965
  editNotes?: readonly PluginMidiNote[];
2954
2966
  /** Persist edited notes; PRESENCE of this callback enables the Edit tab. */
@@ -2968,7 +2980,7 @@ interface SDKTrackRowProps {
2968
2980
  * a thin peak meter welds to the bottom of the row. Omit to hide it. */
2969
2981
  levels?: TrackLevelsHandle;
2970
2982
  }
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;
2983
+ 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, editNotes, onNotesChange, editBars, editBpm, editSnap, onAuditionNote, drag, levels, }: SDKTrackRowProps): React$1.ReactElement;
2972
2984
 
2973
2985
  /**
2974
2986
  * Crossfade-pair metadata — family-agnostic types + parsing shared by every
@@ -3838,6 +3850,29 @@ interface ConfirmDialogProps {
3838
3850
  }
3839
3851
  declare function ConfirmDialog({ open, title, message, confirmLabel, cancelLabel, destructive, onConfirm, onCancel, testIdPrefix, }: ConfirmDialogProps): React$1.ReactElement | null;
3840
3852
 
3853
+ /**
3854
+ * GroupCollapseChevron — the shared collapse/expand toggle for voice-group
3855
+ * header bars (ensemble / arp / bass / pad). One component so all four
3856
+ * headers look identical and plugins don't need their own lucide dep; the
3857
+ * state itself is owned by the shell's CollapsibleGroup wrapper and arrives
3858
+ * via GroupRenderContext (`ctx.collapsed` / `ctx.onToggleCollapse`).
3859
+ *
3860
+ * Renders nothing when `onToggle` is absent (pre-2.48 hosts / bare render
3861
+ * contexts), so plugins can mount it unconditionally.
3862
+ *
3863
+ * @since SDK 2.48.0
3864
+ */
3865
+
3866
+ interface GroupCollapseChevronProps {
3867
+ /** Whether the group's member rows are hidden. */
3868
+ collapsed?: boolean;
3869
+ /** Toggle handler (GroupRenderContext.onToggleCollapse). Absent ⇒ renders nothing. */
3870
+ onToggle?: () => void;
3871
+ /** Noun for the tooltip, e.g. "ensemble" → "Collapse ensemble". Default "group". */
3872
+ what?: string;
3873
+ }
3874
+ declare function GroupCollapseChevron({ collapsed, onToggle, what, }: GroupCollapseChevronProps): React$1.ReactElement | null;
3875
+
3841
3876
  /**
3842
3877
  * Modal — the SDK's one modal-stacking primitive (portal + z-tier + backdrop).
3843
3878
  *
@@ -4932,6 +4967,30 @@ interface PanelSoundAdapter {
4932
4967
  importNoun: string;
4933
4968
  /** History label for the lazily-seeded pre-shuffle sound, e.g. 'Previous preset'. */
4934
4969
  previousSoundLabel: string;
4970
+ /**
4971
+ * Linked-sound groups (@since SDK 2.48.0): the sibling tracks a sound
4972
+ * change on `track` should also apply to, or null/[] when the track is not
4973
+ * in a linked group (or the group's link toggle is OFF). Return ALL linked
4974
+ * members — the core filters: the source track is always dropped, and
4975
+ * preset-level broadcasts (shuffle / history-restore / sound-import) skip
4976
+ * siblings whose instrument differs from the source's (a Surge blob must
4977
+ * not land on Kontakt). Pick-tab instrument swaps broadcast to every
4978
+ * sibling unfiltered — that is what converges a mixed group.
4979
+ */
4980
+ broadcastTargets?(track: GeneratorTrackState, services: GenerationServices): Promise<Array<{
4981
+ engineId: string;
4982
+ dbId: string;
4983
+ label?: string;
4984
+ }> | null>;
4985
+ /**
4986
+ * Persist a descriptor as the track's DURABLE sound identity WITHOUT
4987
+ * re-applying it (the descriptor-space half of copySnapshot). The linked
4988
+ * broadcast calls it per target — and on the source after restore/import,
4989
+ * which apply live-only — so getTrackSound / transitions / agent tools
4990
+ * read the truth. Best-effort; families without a durable store omit it.
4991
+ * @since SDK 2.48.0
4992
+ */
4993
+ persistDescriptor?(trackId: string, descriptor: unknown, label: string): Promise<void>;
4935
4994
  }
4936
4995
  /** The 🎲: pick + apply one new sound, honoring the exclusion cycle. */
4937
4996
  interface PanelShuffleAdapter {
@@ -4971,6 +5030,12 @@ interface GenerationServices {
4971
5030
  createFamilyTrack(nameSuffix?: string): Promise<PluginTrackHandle>;
4972
5031
  /** Resolved groups for a registered group extension. */
4973
5032
  resolvedGroups<M>(metaKey: string): ResolvedTrackGroup<M, GeneratorTrackState>[];
5033
+ /**
5034
+ * The family sound adapter. Always present when built by the core's
5035
+ * makeServices; optional only for pre-2.48 hand-built test services.
5036
+ * @since SDK 2.48.0
5037
+ */
5038
+ sound?: PanelSoundAdapter;
4974
5039
  }
4975
5040
  /**
4976
5041
  * One prompt-driven generation turn. The core owns the wrapper: prompt/auth
@@ -5024,6 +5089,15 @@ interface GroupRenderContext {
5024
5089
  engineId: string;
5025
5090
  dbId: string;
5026
5091
  }>, cleanupKeySuffixes: string[]): Promise<void>;
5092
+ /**
5093
+ * Whether this group is visually collapsed (@since SDK 2.48.0). The shell
5094
+ * owns the state and persists it per group in scene-data
5095
+ * (`track:<groupId>:groupUi`); renderGroup wraps its member rows in
5096
+ * `{!ctx.collapsed && …}` and renders a GroupCollapseChevron in its header.
5097
+ */
5098
+ collapsed?: boolean;
5099
+ /** Toggle this group's collapsed state (persisted). @since SDK 2.48.0 */
5100
+ onToggleCollapse?: () => void;
5027
5101
  }
5028
5102
  /**
5029
5103
  * A family-registered multi-track group row (the crossfade seam,
@@ -5303,6 +5377,12 @@ interface GeneratorPanelCore {
5303
5377
  handlers: CoreTrackHandlers;
5304
5378
  handleGenerate(trackId: string): Promise<void>;
5305
5379
  handleShuffle(trackId: string): Promise<void>;
5380
+ /**
5381
+ * History-tab restore + linked-group broadcast (@since SDK 2.48.0) — the
5382
+ * shell wires this as every row's onRestoreSound. Identical to
5383
+ * soundHistory.restoreTo for panels without broadcastTargets.
5384
+ */
5385
+ handleRestoreSound(trackId: string, index: number): Promise<void>;
5306
5386
  handleAddTrack(): Promise<void>;
5307
5387
  handleDeleteTrack(trackId: string): Promise<void>;
5308
5388
  handleExportMidi(): Promise<void>;
@@ -5380,22 +5460,127 @@ interface SurgeSoundAdapterOverrides {
5380
5460
  declare function createSurgeSoundAdapter(host: PluginHost, overrides?: SurgeSoundAdapterOverrides): PanelSoundAdapter;
5381
5461
 
5382
5462
  /**
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).
5463
+ * ensemble-core: style packs. A style = which SOFT rules are violations +
5464
+ * a prompt paragraph steering the joint composition. Hard rules (register,
5465
+ * per-voice monophony, density caps, root-only anchors) apply to every
5466
+ * style — see enforce-voice.ts. Explicitly NOT just baroque: parallels are
5467
+ * a defect in `counterpoint`, the whole point of `interlock`, and the very
5468
+ * mechanism of the horn-section styles (`stabs` / `riffs` / `unison`),
5469
+ * which additionally INVERT the coordination rule — togetherness is
5470
+ * required, not forbidden (`maxOnsetIndependence`).
5471
+ *
5472
+ * Which styles are offered under which parent instrumentation lives in
5473
+ * instrumentation.ts (STYLES_FOR_INSTRUMENTATION).
5474
+ *
5475
+ * @since SDK 2.42.0 (horn-section styles @since 2.39.0 — see instrumentation.ts)
5476
+ */
5477
+ type EnsembleStyle = 'counterpoint' | 'chorale' | 'interlock' | 'stabs' | 'riffs' | 'unison';
5478
+ /**
5479
+ * The WOVEN (strings/winds) trio. Kept under the historical name because
5480
+ * pre-instrumentation stored configs and consumers validate against it;
5481
+ * per-mode lists live in instrumentation.ts.
5482
+ */
5483
+ declare const ENSEMBLE_STYLES: readonly EnsembleStyle[];
5484
+ interface EnsembleStyleRules {
5485
+ /** Consecutive perfect 5ths/octaves between adjacent voices are violations. */
5486
+ forbidParallelPerfects: boolean;
5487
+ /** A nominally-upper voice sounding below its neighbor is a violation. */
5488
+ forbidVoiceCrossing: boolean;
5489
+ /**
5490
+ * Minimum fraction of an upper voice's onsets that must NOT coincide with
5491
+ * its lower neighbor (0 = homorhythm fine, 1 = fully independent).
5492
+ */
5493
+ minOnsetIndependence: number;
5494
+ /**
5495
+ * Section styles only: the CEILING on that same fraction — a pair whose
5496
+ * upper voice attacks apart from its lower neighbor more than this is a
5497
+ * violation (the section must hit together). Absent = no ceiling.
5498
+ */
5499
+ maxOnsetIndependence?: number;
5500
+ /**
5501
+ * Mechanical per-note duration ceiling in beats, enforced by
5502
+ * enforceVoice (stab styles — a punch must not become a pad). Absent =
5503
+ * no cap.
5504
+ */
5505
+ maxNoteDurationBeats?: number;
5506
+ /** Prompt paragraph injected into the system prompt for this style. */
5507
+ promptParagraph: string;
5508
+ }
5509
+ /**
5510
+ * Section-style togetherness ceilings + the stab length, exported in the
5511
+ * bass-plugin tradition — tune by ear, not by refactor. Independence is the
5512
+ * fraction of an upper voice's onsets its lower neighbor does NOT share:
5513
+ * 0.25 tolerates a stray pickup note per phrase, 0.15 demands lockstep.
5514
+ */
5515
+ declare const STAB_MAX_ONSET_INDEPENDENCE = 0.25;
5516
+ declare const RIFF_MAX_ONSET_INDEPENDENCE = 0.3;
5517
+ declare const UNISON_MAX_ONSET_INDEPENDENCE = 0.15;
5518
+ /** A stab longer than a quarter note is a pad — mechanically trimmed. */
5519
+ declare const STAB_MAX_NOTE_DURATION_BEATS = 1;
5520
+ declare const STYLE_RULES: Record<EnsembleStyle, EnsembleStyleRules>;
5521
+
5522
+ /**
5523
+ * ensemble-core: the INSTRUMENTATION axis — which family of ensemble the
5524
+ * voices model. The parent selection gates the style list (a funk horn
5525
+ * section has no 'chorale'; a string ensemble has no 'stabs') and picks the
5526
+ * voice-spec table (registers, roles, rhythm palettes — see voice-spec.ts).
5387
5527
  *
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`).
5528
+ * Sound coupling stays category-level ONLY: specs stamp the generally
5529
+ * correct role ('strings' / 'brass' / 'winds') and registers use REAL
5530
+ * instrument ranges users routinely swap the placeholder Surge XT patch
5531
+ * for a sampled library (Kontakt, Omnisphere), so the written MIDI must sit
5532
+ * where real sections play, not where any particular synth patch flatters.
5533
+ *
5534
+ * @since SDK 2.39.0
5535
+ */
5536
+
5537
+ type EnsembleInstrumentation = 'strings' | 'horns' | 'winds';
5538
+ declare const ENSEMBLE_INSTRUMENTATIONS: readonly EnsembleInstrumentation[];
5539
+ /**
5540
+ * Styles selectable under each parent instrumentation. Strings and winds
5541
+ * share the WOVEN trio (independent/held-line writing); horns get the
5542
+ * SECTION trio (rhythmic-unison funk writing) — the two families obey
5543
+ * opposite coordination rules (see ensemble-prompt.ts).
5544
+ */
5545
+ declare const STYLES_FOR_INSTRUMENTATION: Record<EnsembleInstrumentation, readonly EnsembleStyle[]>;
5546
+ declare const DEFAULT_STYLE_FOR_INSTRUMENTATION: Record<EnsembleInstrumentation, EnsembleStyle>;
5547
+ /** Clamp an arbitrary stored/hinted value into the closed instrumentation domain. */
5548
+ declare function normalizeInstrumentation(raw: unknown): EnsembleInstrumentation;
5549
+ /**
5550
+ * Clamp a stored/hinted style into the instrumentation's own list — a group
5551
+ * switched from Strings to Horns with 'counterpoint' still stored lands on
5552
+ * the horn default instead of a style the mode can't honor.
5553
+ */
5554
+ declare function styleForInstrumentation(instrumentation: EnsembleInstrumentation, rawStyle: string | undefined | null): EnsembleStyle;
5555
+
5556
+ /**
5557
+ * ensemble-core: voice specifications — the register + complexity hierarchy
5558
+ * as DATA, one table set per INSTRUMENTATION (see instrumentation.ts). The
5559
+ * first live per-voice register map in the platform (the only prior
5560
+ * per-role [low,high] table, MusicTheory.getSuggestedRegister, was dead
5561
+ * code).
5562
+ *
5563
+ * The WOVEN families (strings, winds) encode the original product intent:
5564
+ * the TOP voice is the highest-pitched and most complex line; complexity
5565
+ * decreases with register; the bottom voice is a sparse anchor. The
5566
+ * SECTION family (horns) deliberately breaks that pyramid: every player
5567
+ * shares the lead's rhythm, so caps are EQUAL and generous — density
5568
+ * thinning is a runaway guard there, never a shaping tool (unequal caps
5569
+ * would punch holes in unison hits).
5570
+ *
5571
+ * Horn/wind registers are REAL instrument ranges in concert pitch
5572
+ * (comfortable working tessitura, not extremes) — the Surge XT patch is a
5573
+ * placeholder and users re-target sampled libraries, so the MIDI must sit
5574
+ * where actual sections play.
5391
5575
  *
5392
5576
  * All thresholds are exported constants in the bass-plugin tradition —
5393
5577
  * tune by ear, not by refactor. Roles are plain strings validated by the
5394
5578
  * host at stamp time (`host.getValidRoles()`); the SDK deliberately ships
5395
5579
  * no role list.
5396
5580
  *
5397
- * @since SDK 2.42.0
5581
+ * @since SDK 2.42.0 (horns/winds tables @since 2.39.0)
5398
5582
  */
5583
+
5399
5584
  interface EnsembleVoiceSpec {
5400
5585
  /** 0 = top voice; increases downward. */
5401
5586
  voiceIndex: number;
@@ -5421,16 +5606,19 @@ interface EnsembleVoiceSpec {
5421
5606
  */
5422
5607
  monoPreference: 'high' | 'low';
5423
5608
  }
5609
+ /** Equal per-voice cap for horn tables — a runaway guard, not a shaper. */
5610
+ declare const HORN_MAX_NOTES_PER_BAR = 12;
5424
5611
  /** Supported ensemble sizes. */
5425
5612
  declare const ENSEMBLE_MIN_VOICES = 2;
5426
5613
  declare const ENSEMBLE_MAX_VOICES = 6;
5427
5614
  /**
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.
5615
+ * Default voice specs for an N-voice ensemble of the given instrumentation,
5616
+ * top voice first. Clamps N to the supported range; instrumentation
5617
+ * defaults to 'strings' (the pre-instrumentation behavior, unchanged).
5618
+ * Returned objects are fresh copies — callers may override fields (e.g.
5619
+ * style packs narrowing registers) without touching the tables.
5432
5620
  */
5433
- declare function defaultVoiceSpecs(voiceCount: number): EnsembleVoiceSpec[];
5621
+ declare function defaultVoiceSpecs(voiceCount: number, instrumentation?: EnsembleInstrumentation): EnsembleVoiceSpec[];
5434
5622
 
5435
5623
  /**
5436
5624
  * ensemble-core: HARD per-voice enforcement — the mechanical layer between
@@ -5476,6 +5664,12 @@ interface EnforceVoiceOptions {
5476
5664
  scalePcs?: ReadonlySet<number>;
5477
5665
  /** Chord-tone pitch classes for a bar — exemptions for the scale snap. */
5478
5666
  chordPcsAtBar?: (bar: number) => ReadonlySet<number> | null;
5667
+ /**
5668
+ * Style-level per-note duration ceiling in beats (stab styles — see
5669
+ * STYLE_RULES[*].maxNoteDurationBeats). A punch must not become a pad;
5670
+ * longer notes are trimmed, never dropped.
5671
+ */
5672
+ maxNoteDurationBeats?: number;
5479
5673
  }
5480
5674
  interface EnforceVoiceResult {
5481
5675
  notes: EnsembleNote[];
@@ -5541,34 +5735,10 @@ declare function describeViolations(analysis: EnsembleAnalysis, rules: {
5541
5735
  forbidParallelPerfects: boolean;
5542
5736
  forbidVoiceCrossing: boolean;
5543
5737
  minOnsetIndependence: number;
5738
+ /** Section styles: independence ABOVE this is the violation (see styles.ts). */
5739
+ maxOnsetIndependence?: number;
5544
5740
  }): string[];
5545
5741
 
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
5742
  /**
5573
5743
  * ensemble-core: the `submit_ensemble` function-calling contract — how the
5574
5744
  * ONE joint LLM call returns all voices as structured JSON. Built for
@@ -5604,21 +5774,30 @@ declare function parseEnsembleArgs(args: unknown, voiceCount: number): ParsedEns
5604
5774
 
5605
5775
  /**
5606
5776
  * 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
5777
+ * voices together — the coordination has to be planned across voices, which
5778
+ * is exactly what per-track generation can never do. Mirrors the bass
5779
+ * plugin's prompt discipline: numbered load-bearing rules, register/density
5780
+ * contracts stated per voice, sound selection nowhere in sight (that stays
5612
5781
  * mechanical, host-side).
5613
5782
  *
5783
+ * The numbered rules are INSTRUMENTATION-dependent — the two families obey
5784
+ * opposite coordination physics:
5785
+ *
5786
+ * WOVEN (strings, winds): independent lines that converse — imitation,
5787
+ * contrary motion, staggered entrances, avoid attacking together.
5788
+ *
5789
+ * SECTION (horns): one instrument with many bells — every voice attacks
5790
+ * WITH the lead, voiced under it, short and syncopated, biased hard
5791
+ * toward dance/funk (James Brown stabs, rhythmic punches).
5792
+ *
5614
5793
  * The musical context (key/BPM/chords/contract) arrives via the host's
5615
- * generateWithLLM(Tools) auto-prefix — this prompt states the ENSEMBLE
5794
+ * generateWithLLM(Tools) auto-prefix — this prompt states the ensemble
5616
5795
  * rules and the per-voice contracts only.
5617
5796
  *
5618
- * @since SDK 2.42.0
5797
+ * @since SDK 2.42.0 (section rules @since 2.39.0)
5619
5798
  */
5620
5799
 
5621
- declare function buildEnsembleSystemPrompt(specs: readonly EnsembleVoiceSpec[], style: EnsembleStyle): string;
5800
+ declare function buildEnsembleSystemPrompt(specs: readonly EnsembleVoiceSpec[], style: EnsembleStyle, instrumentation?: EnsembleInstrumentation): string;
5622
5801
  /**
5623
5802
  * Build the retry user-message suffix from soft-rule violations — one
5624
5803
  * guided second attempt, quota-conscious (callers should not loop).
@@ -5837,4 +6016,4 @@ interface PickTopKOptions {
5837
6016
  */
5838
6017
  declare function pickTopKWeighted<T>(scored: ReadonlyArray<ScoredCandidate<T>>, options?: PickTopKOptions): T | null;
5839
6018
 
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 };
6019
+ 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 };