@nodaro/prompts 1.7.3 → 1.8.0

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.
Files changed (72) hide show
  1. package/dist/index.cjs +5422 -4269
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +1198 -61
  4. package/dist/index.d.ts +1198 -61
  5. package/dist/index.js +5336 -4271
  6. package/dist/index.js.map +1 -1
  7. package/package.json +1 -1
  8. package/src/__tests__/b7-person-pack-e2e.test.ts +37 -0
  9. package/src/__tests__/catalog-funnel-ratchet.test.ts +97 -0
  10. package/src/__tests__/catalog-packs.test.ts +130 -0
  11. package/src/__tests__/catalog-sidecar-coverage.test.ts +27 -0
  12. package/src/__tests__/catalog-terms.test.ts +162 -0
  13. package/src/__tests__/character-default-role.test.ts +3 -2
  14. package/src/__tests__/content-free-contract.test.ts +45 -0
  15. package/src/__tests__/dod-replace-pack-acceptance.test.ts +41 -0
  16. package/src/__tests__/fixtures/parameter-hint-golden.json +2959 -0
  17. package/src/__tests__/fixtures/person-sector-pack.ts +27 -0
  18. package/src/__tests__/i18n-entry-completeness.test.ts +5 -2
  19. package/src/__tests__/parameter-hint-mode.test.ts +385 -0
  20. package/src/__tests__/parameter-prompt-hint-pack-fallback.test.ts +25 -0
  21. package/src/__tests__/person-packs.test.ts +166 -0
  22. package/src/__tests__/project-all-catalogs.test.ts +26 -0
  23. package/src/__tests__/prompt-builder.test.ts +53 -0
  24. package/src/__tests__/registered-catalogs-funnel.test.ts +30 -0
  25. package/src/__tests__/registered-catalogs-guard.test.ts +11 -0
  26. package/src/__tests__/term.test.ts +104 -0
  27. package/src/__tests__/transitions.test.ts +8 -5
  28. package/src/__tests__/upstream-immutability.test.ts +23 -0
  29. package/src/action-fx.ts +67 -17
  30. package/src/aesthetic.ts +54 -6
  31. package/src/atmosphere.ts +64 -23
  32. package/src/backdrop.ts +44 -30
  33. package/src/camera-format.ts +33 -11
  34. package/src/camera-motions.ts +89 -0
  35. package/src/catalog-packs.ts +125 -0
  36. package/src/catalog-sidecar-coverage.ts +36 -0
  37. package/src/character-fx.ts +112 -39
  38. package/src/color-look.ts +44 -27
  39. package/src/composition-effects.ts +21 -7
  40. package/src/era.ts +24 -0
  41. package/src/exposure-settings.ts +76 -18
  42. package/src/framing.ts +100 -0
  43. package/src/held-prop.ts +125 -63
  44. package/src/identity-lock.ts +12 -5
  45. package/src/image-reference-doctrine.ts +55 -0
  46. package/src/index.ts +5 -0
  47. package/src/instrumentation.ts +148 -57
  48. package/src/lens.ts +31 -15
  49. package/src/lighting.ts +120 -59
  50. package/src/loop-subject.ts +27 -1
  51. package/src/materials.ts +123 -69
  52. package/src/mood.ts +123 -51
  53. package/src/music-genre.ts +171 -67
  54. package/src/music-mood.ts +85 -17
  55. package/src/parameter-prompt-hint.ts +168 -56
  56. package/src/person-packs.ts +182 -0
  57. package/src/person.ts +506 -408
  58. package/src/photo-genre.ts +37 -22
  59. package/src/photographer.ts +138 -1
  60. package/src/picker-catalogs.ts +86 -40
  61. package/src/pose.ts +105 -40
  62. package/src/post-process-effects.ts +51 -8
  63. package/src/prompt-builder.ts +16 -1
  64. package/src/render-quality.ts +25 -7
  65. package/src/setting.ts +30 -14
  66. package/src/style.ts +33 -15
  67. package/src/styling.ts +155 -94
  68. package/src/temporal.ts +80 -18
  69. package/src/term.ts +155 -0
  70. package/src/transitions.ts +73 -26
  71. package/src/voice-character.ts +190 -90
  72. package/src/voice-delivery.ts +83 -12
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { ConnectedReference, GenericNode, GenericEdge, HintNodeLike, HintGraphContext, EntityStyle, SupportedFontName, CharacterDef, IdentityMeta, SceneData, CharacterMentionTokenInfo, LocationMentionTokenInfo, UsageMode, StyleDirectives, I18nCatalogId, SurroundDirection } from '@nodaro/shared';
1
+ import { ConnectedReference, GenericNode, GenericEdge, HintNodeLike, HintGraphContext, EntityStyle, SupportedFontName, CharacterDef, IdentityMeta, SceneData, CharacterMentionTokenInfo, LocationMentionTokenInfo, UsageMode, ProjectedCatalog, ProjectedCatalogDimension, ProjectedCatalogOption, LocaleId, LocaleCatalogMap, StyleDirectives, I18nCatalogId, SurroundDirection } from '@nodaro/shared';
2
2
  export { HintEdgeLike, HintGraphContext, HintNodeLike } from '@nodaro/shared';
3
3
  import { z } from 'zod';
4
4
 
@@ -18,7 +18,14 @@ import { z } from 'zod';
18
18
  */
19
19
 
20
20
  type IdentityLockMode = "off" | "soft" | "strict";
21
- /** Default applied when a Character node was created before the field existed. */
21
+ /**
22
+ * The identity-lock default for characters — the value used wherever a Character
23
+ * node or entity has no explicit `identityLock`/`identity_lock`: the UI display
24
+ * fallback (canvas node, config panel, Character Studio), the runtime coercion in
25
+ * `toIdentityLockMode`, and the backend create defaults (characters route, MCP
26
+ * create_character, asset generation). Mirror this value in the
27
+ * `characters.identity_lock` SQL column default (migration 353).
28
+ */
22
29
  declare const DEFAULT_IDENTITY_LOCK: IdentityLockMode;
23
30
  /**
24
31
  * Natural-language clause for each mode. Returns an empty string for "off"
@@ -35,9 +42,9 @@ declare function toIdentityLockMode(value: unknown): IdentityLockMode;
35
42
  * - off → { enabled: false } (no lock line)
36
43
  * - soft → { enabled: true, text: <soft clause> } (mild "preserve likeness")
37
44
  * - strict → { enabled: true, text: <strict clause> }(strong "match exactly")
38
- * `undefined` coerces to the runtime default (`"soft"`) via `toIdentityLockMode`,
39
- * so existing nodes (which never set the field) emit the mild line in hybrid. The
40
- * per-mention `~lock`/`~nolock` sentinel still overrides via `withForcedIdentityLock`.
45
+ * `undefined` coerces to the runtime default (`DEFAULT_IDENTITY_LOCK`, now `"off"`)
46
+ * via `toIdentityLockMode`, so a node that never set the field emits NO lock line
47
+ * in hybrid. The per-mention `~lock`/`~nolock` sentinel still overrides via `withForcedIdentityLock`.
41
48
  */
42
49
  declare function characterLockToRefLock(mode: IdentityLockMode | undefined): {
43
50
  enabled: boolean;
@@ -290,10 +297,143 @@ declare function referenceRulesBlock(opts?: {
290
297
  sceneFrame?: boolean;
291
298
  }): string;
292
299
 
300
+ /**
301
+ * Compact professional TERMS for picker-catalog entries.
302
+ *
303
+ * Every picker catalog entry carries a long `promptHint` — a full mechanism
304
+ * description injected downstream by `getParameterPromptHint`. A `term` is the
305
+ * SHORT form of the same entry: the two-to-four word phrase a professional
306
+ * would actually write in a prompt ("whip pan left", "hard cut", "medium
307
+ * close-up") when the consumer wants a compact instruction instead of a
308
+ * paragraph.
309
+ *
310
+ * The split of responsibilities is:
311
+ * - `label` → what USERS see in the picker.
312
+ * - `promptHint` → what MODELS read in verbose ("full") hint mode.
313
+ * - `term` → what MODELS read in compact hint mode.
314
+ *
315
+ * ---------------------------------------------------------------------------
316
+ * THE CONVENTION EVERY CATALOG FOLLOWS
317
+ * ---------------------------------------------------------------------------
318
+ * 1. The catalog's entry interface gains an OPTIONAL `term?: string`. It is
319
+ * authored only where the label does not already read as the professional
320
+ * term (see `isSuspiciousDerivedTerm` for the failure shapes); everywhere
321
+ * else the lowercased label IS the term and no data is added.
322
+ * 2. Alongside each `get<Name>PromptHint(id)` getter, the catalog exports a
323
+ * sibling `get<Name>Term(id)` implemented as
324
+ * `export function get<Name>Term(id: string | undefined | null): string {
325
+ * return resolveTerm(get<Name>(id))
326
+ * }`
327
+ * — same arity, same lookup, same empty-string-on-miss behavior, so the two
328
+ * getters can never disagree about which entry they are describing.
329
+ * 3. An authored `term` is:
330
+ * - lowercase,
331
+ * - at most `TERM_MAX_CHARS` characters,
332
+ * - at most 8 words,
333
+ * - with NO trailing period,
334
+ * - phrased the way a professional cinematographer / photographer /
335
+ * sound designer / stylist would write it in a prompt.
336
+ * Entries with no standard trade term (exotic morph/portal transitions and
337
+ * the like) get a short descriptive phrase instead — never a sentence, and
338
+ * never the long `promptHint`.
339
+ * 4. An entry whose `promptHint` is `""` — the no-op "auto" / "none" entries —
340
+ * injects NOTHING, so its resolved term is `""` too. `resolveTerm` enforces
341
+ * that; do not author a `term` on such an entry expecting it to be used.
342
+ *
343
+ * A guard test (`__tests__/catalog-terms.test.ts`) walks every registered
344
+ * catalog and fails for entries whose label cannot be safely lowercased into a
345
+ * term and that have no explicit `term` authored — so the convention above is
346
+ * enforced, not merely documented.
347
+ */
348
+ /** Hard cap on an authored/derived term. Longer than this is a hint, not a term. */
349
+ declare const TERM_MAX_CHARS = 60;
350
+ /**
351
+ * How verbose a picker node's injected fragment is.
352
+ *
353
+ * - `"full"` — the long `promptHint` (the historical, and still default,
354
+ * behavior; output is byte-identical to before hint modes
355
+ * existed).
356
+ * - `"compact"` — the short professional `term` instead.
357
+ *
358
+ * ONLY the base catalog fragment swaps. The user's `preText` / `postText`
359
+ * free text, the transition / camera-motion / character-fx timing and
360
+ * start-state/end-state clauses, multi-pick joining, and multi-dimension
361
+ * composition all apply exactly the same in both modes.
362
+ *
363
+ * "The same" means the same MEANING, not always the same string. Where a
364
+ * wrapper is grammatically fused to the long hint it cannot simply be reused:
365
+ * the character-fx composer names its target by rewriting the words "the
366
+ * subject" inside a full hint, and a bare term has no such words, so compact
367
+ * mode names the target with an explicit `"{target}: {effect}"` prefix. When a
368
+ * catalog's grammar IS its meaning — Material's `"made of ..."`, Held Prop's
369
+ * `"holding a ..."` — that grammar is authored into the term itself rather
370
+ * than left for a consumer to re-add, because a projected `term` is injected
371
+ * standalone by thin clients that have no composer at all.
372
+ *
373
+ * A picker node selects the mode via an optional `hintMode` field on its node
374
+ * data; absent (or any unrecognized value) means `"full"`.
375
+ */
376
+ type PickerHintMode = "full" | "compact";
377
+ /**
378
+ * The minimal shape of a catalog entry that can resolve a term: an id, the
379
+ * user-facing label, the long hint (whose emptiness marks a no-op entry), and
380
+ * the optional authored short term.
381
+ */
382
+ interface TermCarrier {
383
+ readonly id: string;
384
+ readonly label: string;
385
+ readonly promptHint: string;
386
+ readonly term?: string;
387
+ }
388
+ /**
389
+ * Mechanical label → term derivation: lowercase, drop parenthetical segments,
390
+ * collapse whitespace, trim.
391
+ *
392
+ * Deliberately NOT clever: it does not split on "/" or strip category nouns.
393
+ * A label like "None / Hard Cut" or "Fog / Mist" has to SURFACE as suspicious
394
+ * (see `isSuspiciousDerivedTerm`) so a human authors the right term — guessing
395
+ * here would quietly inject the wrong wording into every prompt.
396
+ */
397
+ declare function deriveTerm(label: string): string;
398
+ interface SuspiciousTermOptions {
399
+ /**
400
+ * Treat a single-word derived term as suspicious. Set for catalogs whose
401
+ * labels are bare MODIFIERS that only read as a professional term with
402
+ * their category noun attached — lighting "Short" → "short lighting",
403
+ * color-look "Warm" → "warm grade".
404
+ */
405
+ readonly bareWordSuspicious?: boolean;
406
+ }
407
+ /**
408
+ * Is the mechanically-derived term unsafe to inject as-is?
409
+ *
410
+ * True when the label is a UI compound or carries an annotation ("None / Hard
411
+ * Cut", "Ultra-wide (14mm)", "Key: Rembrandt"), when nothing survives the
412
+ * derivation, or — under `bareWordSuspicious` — when the result is a lone word
413
+ * that needs its category noun to mean anything to a model.
414
+ */
415
+ declare function isSuspiciousDerivedTerm(label: string, opts?: SuspiciousTermOptions): boolean;
416
+ /**
417
+ * The single resolution point every consumer reads: an explicit `term` when
418
+ * the catalog authored one, the derived label otherwise, and `""` for a no-op
419
+ * entry (missing entry, or an "auto"/"none" entry whose `promptHint` is empty
420
+ * and which therefore injects nothing).
421
+ */
422
+ declare function resolveTerm(entry: TermCarrier | undefined | null): string;
423
+
293
424
  /**
294
425
  * Dispatch by parameter-node type to its prompt-hint string. For camera-motion,
295
426
  * pass `ctx` to include the composed start/end clauses; otherwise only the
296
427
  * bare motion description is returned.
428
+ *
429
+ * VERBOSITY — a picker node may set `data.hintMode` to `"compact"` to inject
430
+ * its short professional `term` ("whip pan left", "hard cut") instead of the
431
+ * long `promptHint`. Absent, or any unrecognized value, means `"full"`, whose
432
+ * output is byte-identical to what this function returned before hint modes
433
+ * existed. ONLY the base catalog fragment swaps: `preText`/`postText`, the
434
+ * transition / camera-motion / character-fx timing and start-state/end-state
435
+ * clauses, multi-pick joining and multi-dimension composition are emitted the
436
+ * same way in both modes.
297
437
  */
298
438
  declare function getParameterPromptHint(node: HintNodeLike | undefined, ctx?: HintGraphContext): string;
299
439
 
@@ -1523,6 +1663,7 @@ declare function resolveVeoI2vInputs(args: VeoI2vInputsArgs): VeoI2vInputsResult
1523
1663
  * the prompt-hint injection on both the frontend DAG executor and the
1524
1664
  * backend orchestrator.
1525
1665
  */
1666
+
1526
1667
  type PersonDimension = "type" | "age" | "ethnicity" | "regional-aesthetic" | "frame" | "body-mass" | "bust" | "waist" | "hips" | "silhouette" | "face-shape" | "jawline" | "cheekbones" | "facial-fullness" | "eye-shape" | "eyelid-type" | "canthal-tilt" | "eye-spacing" | "eye-set-brow" | "nose" | "nose-tip" | "lip-fullness" | "lip-shape" | "lip-state" | "hair-color" | "hair-base" | "eyebrows" | "skin-tone" | "skin-texture" | "eye-color" | "eye-state" | "facial-hair" | "distinctive-features";
1527
1668
  interface Person {
1528
1669
  readonly id: string;
@@ -1539,6 +1680,17 @@ interface Person {
1539
1680
  * instead of the redundant "East Asian (any)". Node cards + tooltips
1540
1681
  * keep the full `label` / `description`. */
1541
1682
  readonly shortLabel?: string;
1683
+ /**
1684
+ * Optional authored COMPACT term — the short professional phrase a consumer
1685
+ * injects instead of the full `promptHint` ("brown hair", "aquiline nose",
1686
+ * "of nordic scandinavian descent"). Authored only where the lowercased
1687
+ * label is not already what a professional writes: Person fragments are
1688
+ * comma-joined into one compound description, so a bare dimension modifier
1689
+ * ("Brown", "Strong", "Full") has to carry its category noun to mean
1690
+ * anything. See `term.ts`; resolve via `resolveTerm` / `getPersonTerm`,
1691
+ * never by reading this field directly.
1692
+ */
1693
+ readonly term?: string;
1542
1694
  }
1543
1695
  declare const PEOPLE: ReadonlyArray<Person>;
1544
1696
  declare const PERSON_DIMENSION_ORDER: ReadonlyArray<PersonDimension>;
@@ -1678,6 +1830,14 @@ interface PersonValue {
1678
1830
  declare function getPerson(id: string | undefined | null): Person | undefined;
1679
1831
  declare function getPersonLabel(id: string | undefined | null, fallback?: string): string;
1680
1832
  declare function getPersonPromptHint(id: string | undefined | null): string;
1833
+ /**
1834
+ * The COMPACT counterpart of `getPersonPromptHint`: the short professional
1835
+ * term ("brown hair", "aquiline nose", "of nordic scandinavian descent") a
1836
+ * consumer injects instead of the full mechanism description. Same lookup,
1837
+ * same empty-string-on-miss behavior, so the two can never disagree about
1838
+ * which entry they are describing.
1839
+ */
1840
+ declare function getPersonTerm(id: string | undefined | null): string;
1681
1841
  declare const PERSON_IDS: ReadonlyArray<string>;
1682
1842
  /**
1683
1843
  * Age hint with optional custom-numeric override. When the user picks the
@@ -1689,7 +1849,14 @@ declare const PERSON_IDS: ReadonlyArray<string>;
1689
1849
  * Custom number is clamped to a sane range and rejected if non-finite.
1690
1850
  */
1691
1851
  declare function buildAgeHint(ageId: string | undefined | null, customAge: number | undefined | null): string;
1692
- declare function buildPersonHints(data: Record<string, unknown> & PersonValue): string[];
1852
+ declare function buildPersonHints(data: Record<string, unknown> & PersonValue, mode?: PickerHintMode): string[];
1853
+ /**
1854
+ * The COMPACT counterpart of `buildPersonHints`: the same per-dimension walk
1855
+ * in the same canonical order, emitting each selection's short professional
1856
+ * term ("in their 30s", "of east asian descent", "long wavy hair", "brown
1857
+ * hair", "fair skin", "green eyes") instead of its full mechanism description.
1858
+ */
1859
+ declare function buildPersonTerms(data: Record<string, unknown> & PersonValue): string[];
1693
1860
  /**
1694
1861
  * Relocate legacy single-field Person values onto the post-split fields so the
1695
1862
  * picker UI shows them in their new home:
@@ -1743,6 +1910,7 @@ declare function migratePersonValue<T extends Record<string, unknown>>(data: T):
1743
1910
  * exact same phrasing here so each option's `promptHint` is non-empty AND
1744
1911
  * matches what actually gets injected downstream.
1745
1912
  */
1913
+
1746
1914
  interface PickerOption {
1747
1915
  readonly id: string;
1748
1916
  readonly label: string;
@@ -1750,6 +1918,15 @@ interface PickerOption {
1750
1918
  /** The group id (matches `categoryOrder` / `categoryLabels`). */
1751
1919
  readonly category?: string;
1752
1920
  readonly promptHint: string;
1921
+ /**
1922
+ * The short professional term this id injects in COMPACT hint mode ("whip
1923
+ * pan left" where `promptHint` is the full mechanism sentence). Always
1924
+ * present and already RESOLVED via `resolveTerm` — an authored `term` when
1925
+ * the catalog entry carries one, the derived label otherwise, and `""` for
1926
+ * a no-op ("auto"/"none") entry that injects nothing. Consumers render
1927
+ * `label` and inject `term`; they never derive it themselves.
1928
+ */
1929
+ readonly term: string;
1753
1930
  /** Only present if the source catalog entry already carries a data icon/emoji/thumbnail field. */
1754
1931
  readonly icon?: string;
1755
1932
  }
@@ -1787,7 +1964,23 @@ interface PickerCatalog {
1787
1964
  /** multi-dim: one self-describing entry per dimension field, in `fields` order. */
1788
1965
  readonly dimensions?: readonly PickerDimension[];
1789
1966
  }
1967
+ /**
1968
+ * The frozen upstream base — the pure-data catalogs as authored, never mutated
1969
+ * in place. Deployment curation is additive-by-registration (catalog packs);
1970
+ * `getRegisteredPickerCatalogs()` is the pack-composed view every enumerating
1971
+ * consumer reads.
1972
+ */
1790
1973
  declare const PICKER_CATALOGS: readonly PickerCatalog[];
1974
+ /**
1975
+ * The pack-composed picker catalogs — the single funnel every enumerating
1976
+ * consumer (funnel getters, /v1/catalogs, MCP, completeness tests) reads.
1977
+ * Memoized on the pack registry version so late registration is reflected.
1978
+ *
1979
+ * DEFERRED PLUG-IN POINT (do not build in Phase 0): a future `CatalogPolicy`
1980
+ * filter (deny-by-tag / override, per read kind) applies HERE, after pack
1981
+ * composition, e.g. `applyCatalogPolicy(composed, runtimePolicy())`.
1982
+ */
1983
+ declare function getRegisteredPickerCatalogs(): readonly PickerCatalog[];
1791
1984
  /** Resolve a catalog by `nodeType` first, then by `catalogId`. */
1792
1985
  declare function getPickerCatalog(nodeTypeOrCatalogId: string): PickerCatalog | undefined;
1793
1986
  declare function listPickerCatalogs(): readonly PickerCatalog[];
@@ -1814,36 +2007,132 @@ interface ProjectPickerCatalogOptions {
1814
2007
  /** multi-dim: keep only this dimension field. */
1815
2008
  readonly field?: string;
1816
2009
  }
1817
- /** An option after projection — description/promptHint present only when detail="full". */
1818
- interface ProjectedPickerOption {
2010
+ type ProjectedPickerOption = ProjectedCatalogOption;
2011
+ type ProjectedPickerDimension = ProjectedCatalogDimension;
2012
+ type ProjectedPickerCatalog = ProjectedCatalog;
2013
+ /** Project a catalog to the wire shape: compact by default, optional category/field filter. */
2014
+ declare function projectPickerCatalog(c: PickerCatalog, opts?: ProjectPickerCatalogOptions): ProjectedPickerCatalog;
2015
+ /**
2016
+ * Project every REGISTERED (pack-composed) catalog to the tag-free
2017
+ * `/v1/catalogs` wire shape. This is what the `GET /v1/catalogs` route and its
2018
+ * SDK resource serve, so a deployment's vendored packs are reflected verbatim.
2019
+ */
2020
+ declare function projectAllCatalogs(opts?: {
2021
+ detail?: PickerCatalogDetail;
2022
+ }): ProjectedCatalog[];
2023
+
2024
+ /**
2025
+ * Every option that leaves this module carries a RESOLVED `term`, exactly like
2026
+ * the base registry's own options do.
2027
+ *
2028
+ * `PickerOption.term` is required at the type level, but a pack arrives from a
2029
+ * separately-compiled bundle that may have been built against a `@nodaro/prompts`
2030
+ * where the field did not exist yet — so at runtime a pack option can simply
2031
+ * not have one. Resolving at COMPOSITION (rather than at each read) is what
2032
+ * keeps the `/v1/catalogs` projection, the compact-hint read path and the
2033
+ * `replace`-mode packs agreeing; a pack-added value would otherwise inject its
2034
+ * full hint in full mode and NOTHING in compact.
2035
+ */
2036
+ /** Pack-author input shapes: identical to the registry's own types except that
2037
+ * `term` is OPTIONAL — a vendored pack may predate the field, and a new
2038
+ * required field on a published input type would be a breaking change. The
2039
+ * composition root resolves it (`withTerm`), so everything that LEAVES this
2040
+ * module still satisfies `PickerOption` with a resolved `term`. */
2041
+ type PickerOptionInput = Omit<PickerOption, "term"> & {
2042
+ readonly term?: string;
2043
+ };
2044
+ type PickerDimensionInput = Omit<PickerDimension, "options"> & {
2045
+ readonly options: readonly PickerOptionInput[];
2046
+ };
2047
+ type PickerCatalogInput = Omit<PickerCatalog, "options" | "dimensions"> & {
2048
+ readonly options?: readonly PickerOptionInput[];
2049
+ readonly dimensions?: readonly PickerDimensionInput[];
2050
+ };
2051
+ type CatalogPackMode = "replace" | "extend" | "deny";
2052
+ /**
2053
+ * A vendored curation pack applied at the picker-catalog composition root.
2054
+ * `replace` swaps a full vendored copy; `extend` appends options (single-dim)
2055
+ * or merges dimensions by field (multi-dim); `deny` removes entry ids from the
2056
+ * copy. Packs target EXISTING catalog ids only — a new catalog id is out of
2057
+ * Phase-0 scope (it drags the 5-registry parameter-picker checklist).
2058
+ *
2059
+ * DEFERRED (do not build here): a `CatalogPolicy` (tags / deny-by-tag /
2060
+ * override) plugs in downstream of this compose, at `getRegisteredPickerCatalogs`.
2061
+ */
2062
+ interface CatalogPack {
1819
2063
  readonly id: string;
1820
- readonly label: string;
1821
- readonly description?: string;
1822
- readonly category?: string;
1823
- readonly promptHint?: string;
1824
- readonly icon?: string;
2064
+ readonly catalogId: string;
2065
+ readonly mode: CatalogPackMode;
2066
+ readonly catalog?: PickerCatalogInput;
2067
+ readonly options?: readonly PickerOptionInput[];
2068
+ readonly dimensions?: readonly PickerDimensionInput[];
2069
+ readonly denyIds?: readonly string[];
2070
+ /** Localized strings for this pack's added option ids, keyed by locale → id. */
2071
+ readonly sidecars?: Partial<Record<LocaleId, LocaleCatalogMap>>;
2072
+ /** Locales deliberately not translated for this pack (reported, never failed). */
2073
+ readonly exemptSidecarLocales?: readonly LocaleId[];
1825
2074
  }
1826
- interface ProjectedPickerDimension {
1827
- readonly field: string;
1828
- readonly label: string;
1829
- readonly options: readonly ProjectedPickerOption[];
2075
+ declare function registerCatalogPack(pack: CatalogPack): void;
2076
+ declare function getRegisteredCatalogPacks(): readonly CatalogPack[];
2077
+ declare function resetCatalogPacks(): void;
2078
+ declare function catalogPacksVersion(): number;
2079
+ declare function composePickerCatalogs(base: readonly PickerCatalog[], activePacks: readonly CatalogPack[]): readonly PickerCatalog[];
2080
+
2081
+ /**
2082
+ * Sidecar-localization coverage for a curation pack's added option ids. For
2083
+ * every pack-added id, each non-English locale must either have a sidecar entry
2084
+ * or be declared exempt (`pack.exemptSidecarLocales`). Exemptions are REPORTED,
2085
+ * never treated as failures — a deployment may knowingly ship a pack with only
2086
+ * a subset of the 11 locales translated.
2087
+ */
2088
+ interface SidecarCoverageReport {
2089
+ readonly total: number;
2090
+ readonly missing: ReadonlyArray<{
2091
+ catalogId: string;
2092
+ locale: LocaleId;
2093
+ id: string;
2094
+ }>;
2095
+ readonly exempted: ReadonlyArray<{
2096
+ catalogId: string;
2097
+ locale: LocaleId;
2098
+ }>;
1830
2099
  }
1831
- interface ProjectedPickerCatalog {
1832
- readonly nodeType: string;
1833
- readonly label: string;
1834
- readonly catalogId: string;
1835
- readonly kind: "single" | "multi";
1836
- readonly valueField?: string;
1837
- readonly defaultValue?: string;
1838
- readonly categoryOrder?: readonly string[];
1839
- readonly categoryLabels?: Readonly<Record<string, string>>;
1840
- readonly options?: readonly ProjectedPickerOption[];
1841
- readonly fields?: readonly string[];
1842
- readonly dimensions?: readonly ProjectedPickerDimension[];
1843
- readonly detail: PickerCatalogDetail;
2100
+ declare function computePackSidecarCoverage(pack: CatalogPack): SidecarCoverageReport;
2101
+
2102
+ /**
2103
+ * A person-pack entry. Pack dimensions are new keys OUTSIDE the closed
2104
+ * `PersonDimension` union, so `dimension` is widened to `string`.
2105
+ */
2106
+ type RegisteredPersonEntry = Omit<Person, "dimension"> & {
2107
+ dimension: string;
2108
+ };
2109
+ interface PersonPack {
2110
+ readonly id: string;
2111
+ readonly entries: readonly RegisteredPersonEntry[];
2112
+ readonly dimensions?: readonly {
2113
+ dimension: string;
2114
+ field: string;
2115
+ label: string;
2116
+ }[];
2117
+ readonly sidecars?: Parameters<typeof registerCatalogPack>[0]["sidecars"];
2118
+ readonly exemptSidecarLocales?: Parameters<typeof registerCatalogPack>[0]["exemptSidecarLocales"];
1844
2119
  }
1845
- /** Project a catalog to the wire shape: compact by default, optional category/field filter. */
1846
- declare function projectPickerCatalog(c: PickerCatalog, opts?: ProjectPickerCatalogOptions): ProjectedPickerCatalog;
2120
+ declare function registerPersonPack(pack: PersonPack): void;
2121
+ declare function resetPersonPacks(): void;
2122
+ declare function personPacksVersion(): number;
2123
+ /**
2124
+ * The registered/composed person taxonomy: base `PEOPLE` folded with every
2125
+ * `catalogId:"person"` CatalogPack in registration order (the SAME registry
2126
+ * `composePickerCatalogs` folds for `/v1/catalogs` + MCP). `extend` appends the
2127
+ * pack's full Person entries, `deny` removes `denyIds`, `replace` swaps to a
2128
+ * reconstruction of the vendored catalog. This is the single funnel the
2129
+ * picker-ui grids read, so a deploy's deny/replace curation hides base entries
2130
+ * in the picker exactly as it hides them in the catalogs projection.
2131
+ */
2132
+ declare function getRegisteredPeople(): readonly RegisteredPersonEntry[];
2133
+ declare function getRegisteredPersonDimensionOrder(): readonly string[];
2134
+ declare function getRegisteredPersonFieldByDimension(): Readonly<Record<string, string>>;
2135
+ declare function getRegisteredPersonDimensionLabels(): Readonly<Record<string, string>>;
1847
2136
 
1848
2137
  /** A catalog entry as the analyzer consumes it. Flat catalogs lack
1849
2138
  * dimension/category; discriminated catalogs carry exactly one. */
@@ -2377,6 +2666,7 @@ declare function pickerFanoutTargets(producerId: string, edges: ReadonlyArray<{
2377
2666
  * zero API calls. Shared between picker UI and prompt-hint injection on
2378
2667
  * frontend DAG executor + backend orchestrator.
2379
2668
  */
2669
+
2380
2670
  type ActionFxCategory = "disaster" | "fire-blasts" | "electric" | "combat" | "sci-fi" | "magic";
2381
2671
  interface ActionFx {
2382
2672
  readonly id: string;
@@ -2384,6 +2674,8 @@ interface ActionFx {
2384
2674
  readonly category: ActionFxCategory;
2385
2675
  readonly description: string;
2386
2676
  readonly promptHint: string;
2677
+ /** Optional authored compact term (see `term.ts` for the convention). */
2678
+ readonly term?: string;
2387
2679
  }
2388
2680
  declare const ACTION_FX_CATEGORY_ORDER: ReadonlyArray<ActionFxCategory>;
2389
2681
  declare const ACTION_FX_CATEGORY_LABELS: Readonly<Record<ActionFxCategory, string>>;
@@ -2392,6 +2684,16 @@ declare const ACTION_FX_IDS: ReadonlyArray<string>;
2392
2684
  declare function getActionFx(id: string | undefined | null): ActionFx | undefined;
2393
2685
  declare function getActionFxLabel(id: string | undefined | null, fallback?: string): string;
2394
2686
  declare function getActionFxPromptHint(id: string | undefined | null): string;
2687
+ /**
2688
+ * Compact professional TERM for an id — the short phrase a VFX supervisor
2689
+ * would write in a prompt ("haboob dust storm", "metal-on-metal friction
2690
+ * sparks"), as opposed to the paragraph-length `promptHint`.
2691
+ *
2692
+ * Same lookup and same empty-string-on-miss behavior as
2693
+ * `getActionFxPromptHint`, so the two can never disagree about which entry
2694
+ * they describe.
2695
+ */
2696
+ declare function getActionFxTerm(id: string | undefined | null): string;
2395
2697
  /**
2396
2698
  * Multi-pick: 1–2 ids → composite FX clause.
2397
2699
  *
@@ -2401,7 +2703,12 @@ declare function getActionFxPromptHint(id: string | undefined | null): string;
2401
2703
  * cap, but the cap here keeps the contract robust against stale workflow
2402
2704
  * data. Duplicate ids are deduplicated before the cap is applied.
2403
2705
  */
2404
- declare function buildActionFxHints(value: unknown): string[];
2706
+ declare function buildActionFxHints(value: unknown, mode?: PickerHintMode): string[];
2707
+ /**
2708
+ * Compact-mode mirror of `buildActionFxHints`: the same 1–2 ids, resolved to
2709
+ * their short professional terms instead of their paragraph-length hints.
2710
+ */
2711
+ declare function buildActionFxTerms(value: unknown): string[];
2405
2712
 
2406
2713
  /**
2407
2714
  * Canonical catalog of Aesthetic / Microtrend choices.
@@ -2423,6 +2730,7 @@ declare function buildActionFxHints(value: unknown): string[];
2423
2730
  * and the prompt-hint injection on both the frontend DAG executor and the
2424
2731
  * backend orchestrator.
2425
2732
  */
2733
+
2426
2734
  type AestheticCategory = "mainstream" | "niche" | "era" | "mood";
2427
2735
  interface Aesthetic {
2428
2736
  readonly id: string;
@@ -2430,17 +2738,32 @@ interface Aesthetic {
2430
2738
  readonly category: AestheticCategory;
2431
2739
  readonly description: string;
2432
2740
  readonly promptHint: string;
2741
+ /**
2742
+ * Compact professional term (see `term.ts`). Authored only where the
2743
+ * lowercased label is not the phrase a stylist would write in a prompt —
2744
+ * UI compounds ("Techwear / Gorpcore") and the fashion-era labels whose
2745
+ * bare nouns name an art movement rather than the look.
2746
+ */
2747
+ readonly term?: string;
2433
2748
  }
2434
2749
  declare const AESTHETICS: ReadonlyArray<Aesthetic>;
2435
2750
  declare function getAesthetic(id: string | undefined | null): Aesthetic | undefined;
2436
2751
  declare function getAestheticLabel(id: string | undefined | null, fallback?: string): string;
2437
2752
  declare function getAestheticPromptHint(id: string | undefined | null): string;
2753
+ /** Compact-mode sibling of `getAestheticPromptHint` (see `term.ts`). */
2754
+ declare function getAestheticTerm(id: string | undefined | null): string;
2438
2755
  /**
2439
2756
  * Multi-pick variant: 1-2 aesthetic ids → blended hint. Single → entry's
2440
2757
  * own promptHint. Two → "styled in a {A} + {B} aesthetic blend" with
2441
2758
  * canonical entry labels (Y2K, dark academia, etc. stay as written).
2442
2759
  */
2443
- declare function buildAestheticHints(value: unknown): string;
2760
+ declare function buildAestheticHints(value: unknown, mode?: PickerHintMode): string;
2761
+ /**
2762
+ * Compact-mode sibling of `buildAestheticHints`: same 1-2 id shape, same
2763
+ * blend structure, but composed from the entries' short terms instead of
2764
+ * their paragraph-length hints.
2765
+ */
2766
+ declare function buildAestheticTerms(value: unknown): string;
2444
2767
  declare const AESTHETIC_IDS: ReadonlyArray<string>;
2445
2768
  declare const AESTHETIC_CATEGORY_LABELS: Readonly<Record<AestheticCategory, string>>;
2446
2769
  declare const AESTHETIC_CATEGORY_ORDER: ReadonlyArray<AestheticCategory>;
@@ -2457,23 +2780,44 @@ declare const AESTHETIC_CATEGORY_ORDER: ReadonlyArray<AestheticCategory>;
2457
2780
  * Shared between the picker UI and the prompt-hint injection on both the
2458
2781
  * frontend DAG executor and the backend orchestrator.
2459
2782
  */
2783
+
2460
2784
  interface Atmosphere {
2461
2785
  readonly id: string;
2462
2786
  readonly label: string;
2463
2787
  readonly description: string;
2464
2788
  readonly promptHint: string;
2789
+ /**
2790
+ * Compact professional term for this atmosphere ("dense fog", "sparks and
2791
+ * embers") — authored only where the lowercased label is not what a DP or
2792
+ * VFX supervisor would write in a prompt. See `term.ts`.
2793
+ */
2794
+ readonly term?: string;
2465
2795
  }
2466
2796
  declare const ATMOSPHERES: ReadonlyArray<Atmosphere>;
2467
2797
  declare function getAtmosphere(id: string | undefined | null): Atmosphere | undefined;
2468
2798
  declare function getAtmosphereLabel(id: string | undefined | null, fallback?: string): string;
2469
2799
  declare function getAtmospherePromptHint(id: string | undefined | null): string;
2800
+ /**
2801
+ * Compact counterpart of `getAtmospherePromptHint`: the short professional
2802
+ * term this atmosphere injects in compact hint mode ("dense fog" where the
2803
+ * hint is the full sentence). Empty string for an unknown id and for any
2804
+ * entry that injects no hint at all.
2805
+ */
2806
+ declare function getAtmosphereTerm(id: string | undefined | null): string;
2470
2807
  /**
2471
2808
  * Multi-pick: 1-2 atmosphere ids → composite atmospheric clause. Single →
2472
2809
  * entry's own promptHint. Two → emit independently and join — atmospheres
2473
2810
  * are particle-effect descriptions that compose naturally
2474
2811
  * ("fog drifting in soft cool clouds, with golden god-rays cutting through").
2475
2812
  */
2476
- declare function buildAtmosphereHints(value: unknown): string[];
2813
+ declare function buildAtmosphereHints(value: unknown, mode?: PickerHintMode): string[];
2814
+ /**
2815
+ * Compact counterpart of `buildAtmosphereHints`: the same 1-2 id multi-pick,
2816
+ * emitted as short professional terms instead of full mechanism sentences
2817
+ * ("dense fog", "god rays"). Same collection order, same skip-the-no-ops
2818
+ * behavior.
2819
+ */
2820
+ declare function buildAtmosphereTerms(value: unknown): string[];
2477
2821
  declare const ATMOSPHERE_IDS: ReadonlyArray<string>;
2478
2822
 
2479
2823
  /**
@@ -2506,11 +2850,20 @@ interface Backdrop {
2506
2850
  readonly category: BackdropCategory;
2507
2851
  readonly description: string;
2508
2852
  readonly promptHint: string;
2853
+ /**
2854
+ * Compact professional term injected in compact hint mode — authored only
2855
+ * where the lowercased label would not read as the backdrop a photographer
2856
+ * means (bare colors that describe the SUBJECT instead of the wall, UI
2857
+ * shorthand like "Muslin" or "Paper Roll Seamless"). See `term.ts`.
2858
+ */
2859
+ readonly term?: string;
2509
2860
  }
2510
2861
  declare const BACKDROPS: ReadonlyArray<Backdrop>;
2511
2862
  declare function getBackdrop(id: string | undefined | null): Backdrop | undefined;
2512
2863
  declare function getBackdropLabel(id: string | undefined | null, fallback?: string): string;
2513
2864
  declare function getBackdropPromptHint(id: string | undefined | null): string;
2865
+ /** Compact professional term for a backdrop id — the short form of the hint. */
2866
+ declare function getBackdropTerm(id: string | undefined | null): string;
2514
2867
  declare const BACKDROP_IDS: ReadonlyArray<string>;
2515
2868
  declare const BACKDROP_CATEGORY_LABELS: Readonly<Record<BackdropCategory, string>>;
2516
2869
  declare const BACKDROP_CATEGORY_ORDER: ReadonlyArray<BackdropCategory>;
@@ -2530,11 +2883,28 @@ interface CameraFormat {
2530
2883
  readonly label: string;
2531
2884
  readonly description: string;
2532
2885
  readonly promptHint: string;
2886
+ /**
2887
+ * Compact professional term (see `term.ts`). Authored only where the
2888
+ * lowercased label is not what a cinematographer would write in a prompt:
2889
+ * a UI compound ("Webcam / FaceTime", "Tintype / Wet Plate", "B&W Film"),
2890
+ * a parenthetical whose annotation carries the meaning ("Drone (Aerial)",
2891
+ * "Toy Camera (Holga)", "Security Cam (CCTV)"), a bare name that reads as
2892
+ * a subject rather than a capture medium once lowercased ("red komodo" is
2893
+ * a lizard, "iphone" is a phone in frame), or a correct-but-underspecified
2894
+ * name whose `promptHint` carries the distinguishing detail ("Camcorder" →
2895
+ * "90s consumer camcorder", "Voigtlander" → "voigtlander rangefinder",
2896
+ * "Super 8" → "super 8mm film"). Remaining labels are already the trade
2897
+ * term ("35mm film", "vhs", "polaroid", "daguerreotype") and carry no
2898
+ * `term`.
2899
+ */
2900
+ readonly term?: string;
2533
2901
  }
2534
2902
  declare const CAMERA_FORMATS: ReadonlyArray<CameraFormat>;
2535
2903
  declare function getCameraFormat(id: string | undefined | null): CameraFormat | undefined;
2536
2904
  declare function getCameraFormatLabel(id: string | undefined | null, fallback?: string): string;
2537
2905
  declare function getCameraFormatPromptHint(id: string | undefined | null): string;
2906
+ /** Compact-mode sibling of `getCameraFormatPromptHint` — same lookup, short form. */
2907
+ declare function getCameraFormatTerm(id: string | undefined | null): string;
2538
2908
  declare const CAMERA_FORMAT_IDS: ReadonlyArray<string>;
2539
2909
 
2540
2910
  /**
@@ -2545,6 +2915,7 @@ declare const CAMERA_FORMAT_IDS: ReadonlyArray<string>;
2545
2915
  * cue that gets appended to the user prompt when the node has camera
2546
2916
  * motion enabled.
2547
2917
  */
2918
+
2548
2919
  type CameraMotionCategory = "default" | "pan" | "tilt" | "zoom" | "dolly" | "truck" | "pedestal" | "roll" | "orbit" | "crane" | "tracking" | "special";
2549
2920
  interface CameraMotion {
2550
2921
  readonly id: string;
@@ -2552,6 +2923,12 @@ interface CameraMotion {
2552
2923
  readonly category: CameraMotionCategory;
2553
2924
  readonly description: string;
2554
2925
  readonly promptHint: string;
2926
+ /**
2927
+ * Compact professional term for this move ("whip pan left", "push-pull
2928
+ * swing") — authored only where the lowercased label is not what a
2929
+ * cinematographer would write in a prompt. See `term.ts`.
2930
+ */
2931
+ readonly term?: string;
2555
2932
  }
2556
2933
  declare const CAMERA_MOTIONS: ReadonlyArray<CameraMotion>;
2557
2934
  declare const CAMERA_MOTION_CATEGORY_ORDER: ReadonlyArray<CameraMotionCategory>;
@@ -2561,6 +2938,15 @@ declare function getCameraMotion(id: string | undefined | null): CameraMotion |
2561
2938
  declare function getCameraMotionLabel(id: string | undefined | null, fallback?: string): string;
2562
2939
  /** Descriptive prompt hint for the given motion id. Empty string when motion is "auto" or unknown. */
2563
2940
  declare function getCameraMotionPromptHint(id: string | undefined | null): string;
2941
+ /**
2942
+ * Compact counterpart of `getCameraMotionPromptHint`: the short professional
2943
+ * term a cinematographer would write for this move ("whip pan left",
2944
+ * "push-pull swing") where the hint is the full mechanism sentence. Same
2945
+ * lookup and same empty-string-on-miss behavior, so the two getters can never
2946
+ * disagree about which motion they describe; "auto" (which injects nothing)
2947
+ * resolves to "" here too.
2948
+ */
2949
+ declare function getCameraMotionTerm(id: string | undefined | null): string;
2564
2950
  declare const CAMERA_MOTION_IDS: ReadonlyArray<string>;
2565
2951
  /**
2566
2952
  * Compose a structural prompt-hint sentence from a camera-motion id plus
@@ -2576,8 +2962,24 @@ declare const CAMERA_MOTION_IDS: ReadonlyArray<string>;
2576
2962
  * Hints within each side are joined with " and " for grammatical flow.
2577
2963
  * If multiple nodes are connected (e.g. Framing + Lighting + Tone), all
2578
2964
  * three contribute their hint to the clause.
2965
+ *
2966
+ * @param mode `"compact"` delegates to `composeCameraMotionTermFromConnections`
2967
+ * — the same start/end structure built from the motion's short professional
2968
+ * `term`. The caller is expected to have resolved the connected nodes to
2969
+ * THEIR terms too, so the whole fragment stays at one level of detail.
2970
+ */
2971
+ declare function composeCameraMotionHintFromConnections(motionId: string | undefined, startHints: ReadonlyArray<string>, endHints: ReadonlyArray<string>, mode?: PickerHintMode): string;
2972
+ /**
2973
+ * Compact-mode mirror of `composeCameraMotionHintFromConnections`: the same
2974
+ * start/end structure, built from the motion's short `term` and the connected
2975
+ * parameter nodes' terms instead of their full promptHints
2976
+ * ("dolly in, beginning with wide shot, ending with medium close-up").
2977
+ *
2978
+ * Same shape in every respect — empty base (an "auto" or unknown motion) still
2979
+ * yields "", each side is joined with " and ", and the clauses are appended in
2980
+ * start-then-end order.
2579
2981
  */
2580
- declare function composeCameraMotionHintFromConnections(motionId: string | undefined, startHints: ReadonlyArray<string>, endHints: ReadonlyArray<string>): string;
2982
+ declare function composeCameraMotionTermFromConnections(motionId: string | undefined, startTerms: ReadonlyArray<string>, endTerms: ReadonlyArray<string>): string;
2581
2983
 
2582
2984
  /**
2583
2985
  * Canonical catalog of character-driven effects for AI-video generation.
@@ -2598,6 +3000,7 @@ declare function composeCameraMotionHintFromConnections(motionId: string | undef
2598
3000
  *
2599
3001
  * null input is treated like undefined (falsy short-circuit → returns "")
2600
3002
  */
3003
+
2601
3004
  type CharacterFxCategory = "transformation" | "power" | "body-mod" | "face-expression" | "aura-ambient";
2602
3005
  interface CharacterFx {
2603
3006
  readonly id: string;
@@ -2605,6 +3008,8 @@ interface CharacterFx {
2605
3008
  readonly category: CharacterFxCategory;
2606
3009
  readonly description: string;
2607
3010
  readonly promptHint: string;
3011
+ /** Optional authored compact term (see `term.ts` for the convention). */
3012
+ readonly term?: string;
2608
3013
  }
2609
3014
  type CharacterFxPosition = "auto" | "start" | "middle" | "end" | "full";
2610
3015
  type CharacterFxDuration = "auto" | "instant" | "short" | "medium" | "long";
@@ -2620,6 +3025,14 @@ declare const CHARACTER_FX_CATEGORY_LABELS: Readonly<Record<CharacterFxCategory,
2620
3025
  declare function getCharacterFx(id: string | undefined | null): CharacterFx | undefined;
2621
3026
  declare function getCharacterFxLabel(id: string | undefined | null, fallback?: string): string;
2622
3027
  declare function getCharacterFxPromptHint(id: string | undefined | null): string;
3028
+ /**
3029
+ * Compact counterpart of `getCharacterFxPromptHint`: the short professional
3030
+ * term this effect injects in compact hint mode ("werewolf transformation"
3031
+ * where the hint is the full shot description). Same lookup and same
3032
+ * empty-string-on-miss behavior — including the no-op "auto"/"none" entries,
3033
+ * which inject nothing at either detail level.
3034
+ */
3035
+ declare function getCharacterFxTerm(id: string | undefined | null): string;
2623
3036
  declare const CHARACTER_FX_IDS: ReadonlyArray<string>;
2624
3037
  /**
2625
3038
  * Compose a character-fx prompt-hint sentence from an effect id (or array
@@ -2629,9 +3042,21 @@ declare const CHARACTER_FX_IDS: ReadonlyArray<string>;
2629
3042
  *
2630
3043
  * Substitution: each base hint has every `"the subject"` occurrence
2631
3044
  * rewritten to the target name BEFORE the join. Empty targetHints leaves
2632
- * "the subject" intact in the prompt.
2633
- */
2634
- declare function composeCharacterFxHintFromConnections(effectId: string | ReadonlyArray<string> | undefined, targetHints: ReadonlyArray<string>, timing?: CharacterFxTiming): string;
3045
+ * "the subject" intact in the prompt. In compact hint mode the base is a bare
3046
+ * `term` with no "the subject" to rewrite, so the target is named by an
3047
+ * explicit `"{target}: {effects}"` prefix instead — the character is named in
3048
+ * both modes.
3049
+ *
3050
+ * @param mode `"compact"` builds the base from each effect's short
3051
+ * professional `term` instead of its full shot description. The ", and "
3052
+ * multi-pick join and the position/duration/intensity clauses are emitted
3053
+ * identically in both modes. The TARGET is not: no `term` contains the
3054
+ * words "the subject" (a term names the effect, not a sentence about a
3055
+ * subject), so compact mode names the target with an explicit
3056
+ * `"{target}: {effects}"` prefix instead of substituting into the base.
3057
+ * Either way the wired character is always named.
3058
+ */
3059
+ declare function composeCharacterFxHintFromConnections(effectId: string | ReadonlyArray<string> | undefined, targetHints: ReadonlyArray<string>, timing?: CharacterFxTiming, mode?: PickerHintMode): string;
2635
3060
 
2636
3061
  /**
2637
3062
  * Canonical catalog of color/look choices.
@@ -2652,6 +3077,16 @@ interface ColorLook {
2652
3077
  readonly category: ColorLookCategory;
2653
3078
  readonly description: string;
2654
3079
  readonly promptHint: string;
3080
+ /**
3081
+ * Compact professional form injected in COMPACT hint mode ("warm color
3082
+ * grade" where `promptHint` is the full sentence). Authored only where the
3083
+ * lowercased label is not already what a colorist would write — e.g. bare
3084
+ * grade adjectives ("Warm", "Sepia"), UI compounds ("Teal & Orange",
3085
+ * "Agfa / ORWO"), annotated stock names ("Kodak Tri-X 400 (B&W)") and
3086
+ * stacked modifiers with no head noun ("MTV 90s VHS"). See `term.ts`;
3087
+ * resolve via `resolveTerm`.
3088
+ */
3089
+ readonly term?: string;
2655
3090
  }
2656
3091
  declare const COLOR_LOOKS: ReadonlyArray<ColorLook>;
2657
3092
  declare const COLOR_LOOK_CATEGORY_ORDER: ReadonlyArray<ColorLookCategory>;
@@ -2659,6 +3094,8 @@ declare const COLOR_LOOK_CATEGORY_LABELS: Record<ColorLookCategory, string>;
2659
3094
  declare function getColorLook(id: string | undefined | null): ColorLook | undefined;
2660
3095
  declare function getColorLookLabel(id: string | undefined | null, fallback?: string): string;
2661
3096
  declare function getColorLookPromptHint(id: string | undefined | null): string;
3097
+ /** Compact sibling of `getColorLookPromptHint` — the short colorist term. */
3098
+ declare function getColorLookTerm(id: string | undefined | null): string;
2662
3099
  declare const COLOR_LOOK_IDS: ReadonlyArray<string>;
2663
3100
 
2664
3101
  /**
@@ -2682,11 +3119,20 @@ interface CompositionEffect {
2682
3119
  readonly label: string;
2683
3120
  readonly description: string;
2684
3121
  readonly promptHint: string;
3122
+ /**
3123
+ * Optional authored compact term (see `term.ts`). Authored only where the
3124
+ * lowercased label is not the phrase a retoucher / VFX artist would write in
3125
+ * a prompt — "Doubled Mirror" reads as a doubled mirror, not as a mirrored
3126
+ * duplicate of the subject. Everywhere else the label IS the term.
3127
+ */
3128
+ readonly term?: string;
2685
3129
  }
2686
3130
  declare const COMPOSITION_EFFECTS: ReadonlyArray<CompositionEffect>;
2687
3131
  declare function getCompositionEffect(id: string | undefined | null): CompositionEffect | undefined;
2688
3132
  declare function getCompositionEffectLabel(id: string | undefined | null, fallback?: string): string;
2689
3133
  declare function getCompositionEffectPromptHint(id: string | undefined | null): string;
3134
+ /** The compact professional term for a composition effect (see `term.ts`). */
3135
+ declare function getCompositionEffectTerm(id: string | undefined | null): string;
2690
3136
  declare const COMPOSITION_EFFECT_IDS: ReadonlyArray<string>;
2691
3137
 
2692
3138
  /**
@@ -2714,11 +3160,23 @@ interface Era {
2714
3160
  readonly category: EraCategory;
2715
3161
  readonly description: string;
2716
3162
  readonly promptHint: string;
3163
+ /**
3164
+ * Compact period name for prompt injection, authored only where the
3165
+ * lowercased label is not what a period stylist would write: UI compounds
3166
+ * ("1950s Diner / Pin-up"), annotated labels ("Fin-de-siècle (1895-1905)"),
3167
+ * and decade names whose word order reads as a menu entry rather than an era
3168
+ * ("Atomic Age 50s", "Pre-War Roaring"). Proper era names — medieval,
3169
+ * renaissance, victorian, dieselpunk — need nothing; the label already IS
3170
+ * the term.
3171
+ */
3172
+ readonly term?: string;
2717
3173
  }
2718
3174
  declare const ERAS: ReadonlyArray<Era>;
2719
3175
  declare function getEra(id: string | undefined | null): Era | undefined;
2720
3176
  declare function getEraLabel(id: string | undefined | null, fallback?: string): string;
2721
3177
  declare function getEraPromptHint(id: string | undefined | null): string;
3178
+ /** Compact counterpart of `getEraPromptHint` — the short period name. */
3179
+ declare function getEraTerm(id: string | undefined | null): string;
2722
3180
  declare const ERA_IDS: ReadonlyArray<string>;
2723
3181
  declare const ERA_CATEGORY_LABELS: Readonly<Record<EraCategory, string>>;
2724
3182
  declare const ERA_CATEGORY_ORDER: ReadonlyArray<EraCategory>;
@@ -2743,6 +3201,7 @@ declare const ERA_CATEGORY_ORDER: ReadonlyArray<EraCategory>;
2743
3201
  * node, and the prompt-hint injection on both the frontend DAG executor and
2744
3202
  * the backend orchestrator.
2745
3203
  */
3204
+
2746
3205
  type ExposureCategory = "aperture" | "shutter-speed" | "iso";
2747
3206
  interface ExposureSettings {
2748
3207
  readonly id: string;
@@ -2750,6 +3209,25 @@ interface ExposureSettings {
2750
3209
  readonly category: ExposureCategory;
2751
3210
  readonly description: string;
2752
3211
  readonly promptHint: string;
3212
+ /**
3213
+ * Optional authored compact term (see `term.ts`). Authored on nearly every
3214
+ * dial value, because the mechanical derivation mangles all three
3215
+ * categories — the f-stop slash reads as a UI compound ("f/1.2"), the
3216
+ * shutter fraction loses its unit and its annotation ("1/1000 (action
3217
+ * freeze)" → "1/1000"), and the ISO annotation is stripped ("ISO 3200
3218
+ * (heavy grain)" → "iso 3200").
3219
+ *
3220
+ * Each term is the terse trade phrase a photographer writes — the dial
3221
+ * value plus its category noun ("f/2.8 aperture", "1/500s shutter speed",
3222
+ * "iso 1600 film speed") — and NOT the visual consequence: that is what
3223
+ * `promptHint` is for, and a comma-bearing term would split into unrelated
3224
+ * items once compact terms are joined into a comma-delimited list.
3225
+ *
3226
+ * ISO 400 / ISO 800 need nothing: their labels already read as the term.
3227
+ * The three annotated ISO labels carry the category noun only because the
3228
+ * guard requires an authored term to differ from the derivation.
3229
+ */
3230
+ readonly term?: string;
2753
3231
  }
2754
3232
  declare const EXPOSURE_SETTINGS: ReadonlyArray<ExposureSettings>;
2755
3233
  declare const EXPOSURE_CATEGORY_ORDER: ReadonlyArray<ExposureCategory>;
@@ -2757,6 +3235,16 @@ declare const EXPOSURE_CATEGORY_LABELS: Record<ExposureCategory, string>;
2757
3235
  declare function getExposure(id: string | undefined | null): ExposureSettings | undefined;
2758
3236
  declare function getExposureLabel(id: string | undefined | null, fallback?: string): string;
2759
3237
  declare function getExposurePromptHint(id: string | undefined | null): string;
3238
+ /**
3239
+ * Compact professional TERM for an exposure id — the short phrase a
3240
+ * photographer would write in a prompt ("f/1.4 aperture"), as opposed to the
3241
+ * sentence-long `promptHint`.
3242
+ *
3243
+ * Same lookup and same empty-string-on-miss behavior as
3244
+ * `getExposurePromptHint`, so the two can never disagree about which entry
3245
+ * they describe.
3246
+ */
3247
+ declare function getExposureTerm(id: string | undefined | null): string;
2760
3248
  declare const EXPOSURE_IDS: ReadonlyArray<string>;
2761
3249
  /**
2762
3250
  * Maps each ExposureCategory to the consumer data field name that holds the
@@ -2782,6 +3270,16 @@ declare function buildExposureHints(data: Record<string, unknown> & {
2782
3270
  aperture?: unknown;
2783
3271
  shutterSpeed?: unknown;
2784
3272
  isoValue?: unknown;
3273
+ }, mode?: PickerHintMode): string[];
3274
+ /**
3275
+ * Compact-mode mirror of `buildExposureHints`: the same per-category fields in
3276
+ * the same canonical order (aperture, shutter-speed, iso), resolved to their
3277
+ * short professional terms instead of their sentence-long hints.
3278
+ */
3279
+ declare function buildExposureTerms(data: Record<string, unknown> & {
3280
+ aperture?: unknown;
3281
+ shutterSpeed?: unknown;
3282
+ isoValue?: unknown;
2785
3283
  }): string[];
2786
3284
 
2787
3285
  /**
@@ -2794,6 +3292,7 @@ declare function buildExposureHints(data: Record<string, unknown> & {
2794
3292
  * Shared between the picker UI and the prompt-hint injection on both the
2795
3293
  * frontend DAG executor and the backend orchestrator.
2796
3294
  */
3295
+
2797
3296
  type FramingCategory = "shot-size" | "angle" | "coverage" | "composition" | "vantage";
2798
3297
  interface Framing {
2799
3298
  readonly id: string;
@@ -2801,6 +3300,18 @@ interface Framing {
2801
3300
  readonly category: FramingCategory;
2802
3301
  readonly description: string;
2803
3302
  readonly promptHint: string;
3303
+ /**
3304
+ * Optional authored compact term (see `term.ts`). Authored only where the
3305
+ * lowercased label is not the phrase a cinematographer would write in a
3306
+ * prompt — a UI compound ("Golden Spiral / Fibonacci"), an annotation
3307
+ * ("ECU: Eye"), a reversed pair ("Headroom Tight" → "tight headroom"), a
3308
+ * bare word that needs its shot noun ("Insert" → "insert shot"), or a trade
3309
+ * phrase whose bare form reads as something else entirely once the trade
3310
+ * context is stripped ("Choker" the neckwear, "Dirty Single" the grime,
3311
+ * "Single" the continuous take). Everywhere else the label IS the term and
3312
+ * nothing is authored.
3313
+ */
3314
+ readonly term?: string;
2804
3315
  }
2805
3316
  declare const FRAMINGS: ReadonlyArray<Framing>;
2806
3317
  declare const FRAMING_CATEGORY_ORDER: ReadonlyArray<FramingCategory>;
@@ -2808,6 +3319,13 @@ declare const FRAMING_CATEGORY_LABELS: Record<FramingCategory, string>;
2808
3319
  declare function getFraming(id: string | undefined | null): Framing | undefined;
2809
3320
  declare function getFramingLabel(id: string | undefined | null, fallback?: string): string;
2810
3321
  declare function getFramingPromptHint(id: string | undefined | null): string;
3322
+ /**
3323
+ * The compact professional term for a framing id (see `term.ts`): the short
3324
+ * phrase this framing injects in compact hint mode ("tight headroom" where the
3325
+ * hint is the full clause). Empty string for an unknown id and for any entry
3326
+ * that injects no hint at all.
3327
+ */
3328
+ declare function getFramingTerm(id: string | undefined | null): string;
2811
3329
  declare const FRAMING_IDS: ReadonlyArray<string>;
2812
3330
  declare function isVantageFraming(id: string | undefined | null): boolean;
2813
3331
  /**
@@ -2856,6 +3374,19 @@ declare function buildFramingHints(data: Record<string, unknown> & {
2856
3374
  coverage?: unknown;
2857
3375
  composition?: unknown;
2858
3376
  vantage?: unknown;
3377
+ }, skipVantage?: boolean, mode?: PickerHintMode): string[];
3378
+ /**
3379
+ * Compact counterpart of `buildFramingHints`: the same per-category walk in the
3380
+ * same canonical order and with the same `skipVantage` gate, emitted as short
3381
+ * professional terms instead of full mechanism clauses ("medium close-up",
3382
+ * "tight headroom"). Entries that inject no hint contribute no term either.
3383
+ */
3384
+ declare function buildFramingTerms(data: Record<string, unknown> & {
3385
+ shotSize?: unknown;
3386
+ angle?: unknown;
3387
+ coverage?: unknown;
3388
+ composition?: unknown;
3389
+ vantage?: unknown;
2859
3390
  }, skipVantage?: boolean): string[];
2860
3391
 
2861
3392
  /**
@@ -2881,6 +3412,7 @@ declare function buildFramingHints(data: Record<string, unknown> & {
2881
3412
  * node, and the prompt-hint injection on both the frontend DAG executor
2882
3413
  * and the backend orchestrator.
2883
3414
  */
3415
+
2884
3416
  type HeldPropCategory = "device" | "drink" | "smoking" | "reading-writing" | "bag-accessory" | "floral-nature" | "instrument" | "companion" | "occupational";
2885
3417
  interface HeldProp {
2886
3418
  readonly id: string;
@@ -2888,18 +3420,57 @@ interface HeldProp {
2888
3420
  readonly category: HeldPropCategory;
2889
3421
  readonly description: string;
2890
3422
  readonly promptHint: string;
3423
+ /**
3424
+ * Compact professional term for hint-compact mode (see `term.ts`). Authored
3425
+ * on EVERY entry, and always with the held-in-hand VERB the catalog exists
3426
+ * to encode ("holding a lit cigarette", "cradling a cat", "carrying a
3427
+ * hard-shell briefcase"): the bare prop noun would say only that the object
3428
+ * is somewhere in the scene, which is exactly the Object-node meaning this
3429
+ * catalog is distinct from. Beyond the verb, each term also carries the
3430
+ * qualifier the label drops where the bare noun would inject the wrong prop
3431
+ * — homonym traps ("Lighter", "Joint", "Compass", "Marker", "Apple"), a
3432
+ * trade meaning that collides with a sibling ("Cocktail Glass" is the
3433
+ * conical glass in the trade; this entry is a rocks glass), and the state
3434
+ * that decides what actually RENDERS ("Umbrella" -> open black umbrella,
3435
+ * "Book" -> open hardback book).
3436
+ */
3437
+ readonly term?: string;
2891
3438
  }
2892
3439
  declare const HELD_PROPS: ReadonlyArray<HeldProp>;
2893
3440
  declare function getHeldProp(id: string | undefined | null): HeldProp | undefined;
2894
3441
  declare function getHeldPropLabel(id: string | undefined | null, fallback?: string): string;
2895
3442
  declare function getHeldPropPromptHint(id: string | undefined | null): string;
3443
+ /**
3444
+ * Compact professional TERM for an id — the short prop phrase a stylist would
3445
+ * write in a prompt ("holding a lit chrome lighter", "cradling a cat"), as
3446
+ * opposed to the pose-carrying paragraph in `promptHint`.
3447
+ *
3448
+ * KEEPS the catalog's held-in-hand verb ("holding a…", "cradling a…",
3449
+ * "carrying a…"). No consumer re-adds it — the orchestrator and the frontend
3450
+ * resolver append the fragment verbatim, and a thin client injects the
3451
+ * projected `term` standalone — so dropping the verb would turn "the subject
3452
+ * is holding X" into "X is somewhere in the scene".
3453
+ *
3454
+ * Same lookup and same empty-string-on-miss behavior as
3455
+ * `getHeldPropPromptHint`, so the two can never disagree about which entry
3456
+ * they describe.
3457
+ */
3458
+ declare function getHeldPropTerm(id: string | undefined | null): string;
2896
3459
  /**
2897
3460
  * Multi-pick: 1-2 prop ids → composite held-prop clause. Single → entry's
2898
3461
  * own promptHint (which already starts with "holding..." / "carrying..."
2899
3462
  * grammar). Two → emit independently, joined by buildPersonHints-style
2900
3463
  * comma-join. Common combos: book + coffee, cigarette + drink, phone + bag.
2901
3464
  */
2902
- declare function buildHeldPropHints(value: unknown): string[];
3465
+ declare function buildHeldPropHints(value: unknown, mode?: PickerHintMode): string[];
3466
+ /**
3467
+ * Compact-mode mirror of `buildHeldPropHints`: the same ids in the same order,
3468
+ * resolved to their short professional terms — verb included — instead of
3469
+ * their pose-carrying paragraph hints. The caller joins the array exactly as
3470
+ * it joins the full hints, so each term carrying its own verb is what keeps a
3471
+ * two-prop pick reading correctly.
3472
+ */
3473
+ declare function buildHeldPropTerms(value: unknown): string[];
2903
3474
  declare const HELD_PROP_IDS: ReadonlyArray<string>;
2904
3475
  declare const HELD_PROP_CATEGORY_LABELS: Readonly<Record<HeldPropCategory, string>>;
2905
3476
  declare const HELD_PROP_CATEGORY_ORDER: ReadonlyArray<HeldPropCategory>;
@@ -2916,6 +3487,7 @@ declare const HELD_PROP_CATEGORY_ORDER: ReadonlyArray<HeldPropCategory>;
2916
3487
  * (https://splice.com/sounds/instruments) — Drums / Percussion / Keys /
2917
3488
  * Synth / Guitar / Bass / Brass / Woodwinds / Strings / World.
2918
3489
  */
3490
+
2919
3491
  type InstrumentCategory = "drums" | "percussion" | "keys" | "synth" | "guitar" | "bass" | "brass" | "woodwinds" | "strings" | "world" | "middle-eastern";
2920
3492
  declare const INSTRUMENT_CATEGORY_ORDER: ReadonlyArray<InstrumentCategory>;
2921
3493
  declare const INSTRUMENT_CATEGORY_LABELS: Readonly<Record<InstrumentCategory, string>>;
@@ -2924,7 +3496,18 @@ interface InstrumentationEntry {
2924
3496
  readonly label: string;
2925
3497
  readonly description: string;
2926
3498
  readonly promptHint: string;
3499
+ /**
3500
+ * Optional authored compact term (see `term.ts` for the convention).
3501
+ * Authored only where the lowercased label is NOT what a producer would
3502
+ * write in a prompt — bare modifiers whose trade term carries a category
3503
+ * noun ("Stab" → "synth stab", "Polished" → "polished production"), bare
3504
+ * genre words in the singing-style slot ("Pop" → "pop singing"), and
3505
+ * annotated labels ("Trap (Melodic)" → "melodic trap singing"). Everywhere
3506
+ * else the lowercased label IS the term and nothing is authored.
3507
+ */
3508
+ readonly term?: string;
2927
3509
  }
3510
+ /** Inherits the optional `term` from `InstrumentationEntry`. */
2928
3511
  interface CategorizedInstrument extends InstrumentationEntry {
2929
3512
  readonly category: InstrumentCategory;
2930
3513
  }
@@ -2940,6 +3523,17 @@ declare function getInstrument(id: string | undefined): CategorizedInstrument |
2940
3523
  declare function getProductionStyle(id: string | undefined): InstrumentationEntry | undefined;
2941
3524
  declare function getVocalPresence(id: string | undefined): InstrumentationEntry | undefined;
2942
3525
  declare function getSingingStyle(id: string | undefined): InstrumentationEntry | undefined;
3526
+ /**
3527
+ * The COMPACT counterparts of the `promptHint` lookups: the short professional
3528
+ * term a consumer injects instead of the entry's full fragment ("synth stab",
3529
+ * "pristine studio production", "melodic trap singing"). Same lookup as the
3530
+ * getters above, same empty-string-on-miss behavior, so hint mode and term
3531
+ * mode can never disagree about WHICH entry they are describing.
3532
+ */
3533
+ declare function getInstrumentTerm(id: string | undefined | null): string;
3534
+ declare function getProductionStyleTerm(id: string | undefined | null): string;
3535
+ declare function getVocalPresenceTerm(id: string | undefined | null): string;
3536
+ declare function getSingingStyleTerm(id: string | undefined | null): string;
2943
3537
  declare function buildInstrumentationHints(data: {
2944
3538
  readonly preText?: string;
2945
3539
  readonly postText?: string;
@@ -2947,6 +3541,21 @@ declare function buildInstrumentationHints(data: {
2947
3541
  readonly production?: string;
2948
3542
  readonly vocalPresence?: string | ReadonlyArray<string>;
2949
3543
  readonly singingStyle?: string | ReadonlyArray<string>;
3544
+ }, mode?: PickerHintMode): string;
3545
+ /**
3546
+ * Compact-mode mirror of `buildInstrumentationHints`: the same preText /
3547
+ * [production] [instruments] / "with <vocals>" / "in <style> style" / postText
3548
+ * structure, in the same canonical field order, built from each entry's short
3549
+ * `term` instead of its full `promptHint`. preText / postText are user free
3550
+ * text rather than catalog copy, so they pass through untouched in both modes.
3551
+ */
3552
+ declare function buildInstrumentationTerms(data: {
3553
+ readonly preText?: string;
3554
+ readonly postText?: string;
3555
+ readonly instruments?: ReadonlyArray<string>;
3556
+ readonly production?: string;
3557
+ readonly vocalPresence?: string | ReadonlyArray<string>;
3558
+ readonly singingStyle?: string | ReadonlyArray<string>;
2950
3559
  }): string;
2951
3560
  declare function isInstrumentalVocal(value: unknown): boolean;
2952
3561
  declare const INSTRUMENTATION_DEFAULT_DATA: {
@@ -2974,11 +3583,22 @@ interface Lens {
2974
3583
  readonly label: string;
2975
3584
  readonly description: string;
2976
3585
  readonly promptHint: string;
3586
+ /**
3587
+ * Optional authored compact term (see `term.ts`). Authored where the
3588
+ * lowercased label is not what a cinematographer would write in a prompt —
3589
+ * the focal length lives in a parenthetical the derivation drops
3590
+ * ("Wide (24mm)" → "wide"), or the bare optic name needs its category noun
3591
+ * ("Macro" → "macro lens", "Shallow DOF" → "shallow depth of field").
3592
+ * Everywhere else the label IS the term.
3593
+ */
3594
+ readonly term?: string;
2977
3595
  }
2978
3596
  declare const LENSES: ReadonlyArray<Lens>;
2979
3597
  declare function getLens(id: string | undefined | null): Lens | undefined;
2980
3598
  declare function getLensLabel(id: string | undefined | null, fallback?: string): string;
2981
3599
  declare function getLensPromptHint(id: string | undefined | null): string;
3600
+ /** The compact professional term for a lens (see `term.ts`). */
3601
+ declare function getLensTerm(id: string | undefined | null): string;
2982
3602
  declare const LENS_IDS: ReadonlyArray<string>;
2983
3603
 
2984
3604
  /**
@@ -2992,6 +3612,7 @@ declare const LENS_IDS: ReadonlyArray<string>;
2992
3612
  * Shared between the picker UI and the prompt-hint injection on both the
2993
3613
  * frontend DAG executor and the backend orchestrator.
2994
3614
  */
3615
+
2995
3616
  type LightingCategory = "time-of-day" | "style" | "direction" | "lighting-ratio" | "color-temperature";
2996
3617
  interface Lighting {
2997
3618
  readonly id: string;
@@ -2999,6 +3620,15 @@ interface Lighting {
2999
3620
  readonly category: LightingCategory;
3000
3621
  readonly description: string;
3001
3622
  readonly promptHint: string;
3623
+ /**
3624
+ * Compact professional term injected in compact hint mode (see `term.ts`).
3625
+ *
3626
+ * Lighting labels are bare MODIFIERS — "Short", "Broad", "Loop", "Split",
3627
+ * "Hard" mean nothing on their own and collide head-on with common English
3628
+ * words, so nearly every entry here authors the trade phrasing that carries
3629
+ * its category noun ("short lighting", "1:4 lighting ratio").
3630
+ */
3631
+ readonly term?: string;
3002
3632
  }
3003
3633
  declare const LIGHTINGS: ReadonlyArray<Lighting>;
3004
3634
  declare const LIGHTING_CATEGORY_ORDER: ReadonlyArray<LightingCategory>;
@@ -3006,6 +3636,13 @@ declare const LIGHTING_CATEGORY_LABELS: Record<LightingCategory, string>;
3006
3636
  declare function getLighting(id: string | undefined | null): Lighting | undefined;
3007
3637
  declare function getLightingLabel(id: string | undefined | null, fallback?: string): string;
3008
3638
  declare function getLightingPromptHint(id: string | undefined | null): string;
3639
+ /**
3640
+ * The COMPACT counterpart of `getLightingPromptHint`: the short professional
3641
+ * term ("rembrandt lighting", "1:4 lighting ratio", "rim backlight") a
3642
+ * consumer injects instead of the full mechanism description. Same lookup,
3643
+ * same empty-string-on-miss behavior.
3644
+ */
3645
+ declare function getLightingTerm(id: string | undefined | null): string;
3009
3646
  declare const LIGHTING_IDS: ReadonlyArray<string>;
3010
3647
  /**
3011
3648
  * Maps each LightingCategory to the consumer data field name that holds the
@@ -3049,6 +3686,22 @@ declare function buildLightingHints(data: Record<string, unknown> & {
3049
3686
  lightingDirection?: unknown;
3050
3687
  lightingRatio?: unknown;
3051
3688
  colorTemperature?: unknown;
3689
+ }, mode?: PickerHintMode): string[];
3690
+ /**
3691
+ * The COMPACT counterpart of `buildLightingHints`: the same per-category walk
3692
+ * in the same canonical order, emitting each selection's short professional
3693
+ * term ("dusk lighting", "rembrandt lighting", "1:4 lighting ratio") instead
3694
+ * of its full mechanism description.
3695
+ *
3696
+ * @param data the consumer data record (must include optional timeOfDay /
3697
+ * lightingStyle / lightingDirection fields)
3698
+ */
3699
+ declare function buildLightingTerms(data: Record<string, unknown> & {
3700
+ timeOfDay?: unknown;
3701
+ lightingStyle?: unknown;
3702
+ lightingDirection?: unknown;
3703
+ lightingRatio?: unknown;
3704
+ colorTemperature?: unknown;
3052
3705
  }): string[];
3053
3706
 
3054
3707
  /**
@@ -3079,13 +3732,25 @@ interface LoopSubject {
3079
3732
  /** Drop-in prompt text for Generate Image. Wired into the prompt input
3080
3733
  * via FieldMappings, same as Setting / Motion / Mood Parameter nodes. */
3081
3734
  readonly promptHint: string;
3735
+ /** Compact professional term for hint-compact mode (see `term.ts`). Authored
3736
+ * only where the lowercased label is not what a professional would write —
3737
+ * the "Tunnel — Exciting" style UI compounds and the generic subject
3738
+ * labels ("Galaxy", "Underwater Light") that need their trade wording. */
3739
+ readonly term?: string;
3082
3740
  }
3083
3741
  declare const LOOP_SUBJECT_CATEGORY_ORDER: ReadonlyArray<LoopSubjectCategory>;
3084
3742
  declare const LOOP_SUBJECT_CATEGORY_LABELS: Readonly<Record<LoopSubjectCategory, string>>;
3085
3743
  declare const LOOP_SUBJECTS: ReadonlyArray<LoopSubject>;
3086
- declare function getLoopSubject(id: string): LoopSubject | undefined;
3744
+ declare function getLoopSubject(id: string | undefined | null): LoopSubject | undefined;
3087
3745
  declare function getLoopSubjectLabel(id: string): string;
3088
3746
  declare function getLoopSubjectPromptHint(id: string): string;
3747
+ /**
3748
+ * Compact professional term for the subject — the short phrase a VJ or
3749
+ * cinematographer would write when the consumer wants a term instead of the
3750
+ * full scene paragraph. Mirrors `getLoopSubjectPromptHint`'s lookup so the two
3751
+ * can never describe different entries.
3752
+ */
3753
+ declare function getLoopSubjectTerm(id: string | undefined | null): string;
3089
3754
 
3090
3755
  /**
3091
3756
  * Canonical catalog of material presets ("Material").
@@ -3097,7 +3762,10 @@ declare function getLoopSubjectPromptHint(id: string): string;
3097
3762
  *
3098
3763
  * Grammar: every entry's `promptHint` begins with `"made of ..."` — this reads
3099
3764
  * correctly regardless of target ("a dress made of silk", "a human made of
3100
- * glass", "a pillow made of leather", "a train made of plastic").
3765
+ * glass", "a pillow made of leather", "a train made of plastic"). The compact
3766
+ * `term` keeps that same head ("made of polished gold"): without it the
3767
+ * fragment stops saying what the subject IS and merely names a material
3768
+ * present in the scene, which is a different image.
3101
3769
  *
3102
3770
  * For clothing-specific phrasing ("wearing silk"), see the `fabric` dimension
3103
3771
  * on the Styling node. There is intentional overlap in vocabulary (leather,
@@ -3108,6 +3776,7 @@ declare function getLoopSubjectPromptHint(id: string): string;
3108
3776
  * the prompt-hint injection on both the frontend DAG executor and the
3109
3777
  * backend orchestrator.
3110
3778
  */
3779
+
3111
3780
  type MaterialCategory = "fabric" | "metal" | "stone" | "wood" | "glass-ceramic" | "natural" | "exotic";
3112
3781
  interface Material {
3113
3782
  readonly id: string;
@@ -3115,17 +3784,48 @@ interface Material {
3115
3784
  readonly category: MaterialCategory;
3116
3785
  readonly description: string;
3117
3786
  readonly promptHint: string;
3787
+ /**
3788
+ * Compact professional term (see `term.ts`). Authored on EVERY material, and
3789
+ * always in the catalog's `"made of ..."` grammar — that grammar is what
3790
+ * makes the fragment mean "the subject IS this material" rather than "this
3791
+ * material is somewhere in the scene", so it belongs to the term as much as
3792
+ * to the hint. It also carries the qualifier the label drops where the bare
3793
+ * noun would mislead: "gold"/"silver" alone read as COLORS, "mesh" as 3D
3794
+ * geometry, "Subsurface Glow" is a UI label for subsurface scattering.
3795
+ */
3796
+ readonly term?: string;
3118
3797
  }
3119
3798
  declare const MATERIALS: ReadonlyArray<Material>;
3120
3799
  declare function getMaterial(id: string | undefined | null): Material | undefined;
3121
3800
  declare function getMaterialLabel(id: string | undefined | null, fallback?: string): string;
3122
3801
  declare function getMaterialPromptHint(id: string | undefined | null): string;
3802
+ /**
3803
+ * Compact counterpart of `getMaterialPromptHint`: the short professional term
3804
+ * this material injects in compact hint mode ("made of brushed stainless
3805
+ * steel" where the hint is the full "made of ..." paragraph). The `"made of"`
3806
+ * grammar is part of the TERM, not a wrapper the consumer adds — it is what
3807
+ * distinguishes "the subject is made of glass" from "there is glass in the
3808
+ * scene", and a thin client injecting `term` standalone (see
3809
+ * `ProjectedCatalogOption`) has nothing else to reconstruct it from. Empty
3810
+ * string for an unknown id.
3811
+ */
3812
+ declare function getMaterialTerm(id: string | undefined | null): string;
3123
3813
  /**
3124
3814
  * Multi-pick: 1-2 material ids → composite material clause. Single → entry's
3125
3815
  * own promptHint. Two → "made of {A} and {B}" using lowercased entry labels.
3126
3816
  * Covers leather+brass handbag, wood+steel chair, glass+chrome lamp, etc.
3817
+ *
3818
+ * @param mode `"compact"` emits the bare material term(s) instead (delegates
3819
+ * to `buildMaterialTerms`).
3127
3820
  */
3128
- declare function buildMaterialHints(value: unknown): string;
3821
+ declare function buildMaterialHints(value: unknown, mode?: PickerHintMode): string;
3822
+ /**
3823
+ * Compact counterpart of `buildMaterialHints`: one material's term, or two
3824
+ * joined with " and " ("made of polished gold and made of walnut"). Each term
3825
+ * carries its own "made of" grammar, so the join needs no wrapper and a
3826
+ * pack-added entry whose term is only the derived label still reads correctly.
3827
+ */
3828
+ declare function buildMaterialTerms(value: unknown): string;
3129
3829
  declare const MATERIAL_IDS: ReadonlyArray<string>;
3130
3830
  declare const MATERIAL_CATEGORY_LABELS: Readonly<Record<MaterialCategory, string>>;
3131
3831
  declare const MATERIAL_CATEGORY_ORDER: ReadonlyArray<MaterialCategory>;
@@ -3154,6 +3854,7 @@ declare const MATERIAL_CATEGORY_ORDER: ReadonlyArray<MaterialCategory>;
3154
3854
  * the prompt-hint injection on both the frontend DAG executor and the
3155
3855
  * backend orchestrator.
3156
3856
  */
3857
+
3157
3858
  type MoodCategory = "positive" | "negative" | "neutral" | "intense";
3158
3859
  interface Mood {
3159
3860
  readonly id: string;
@@ -3161,11 +3862,27 @@ interface Mood {
3161
3862
  readonly category: MoodCategory;
3162
3863
  readonly description: string;
3163
3864
  readonly promptHint: string;
3865
+ /**
3866
+ * Compact professional term injected in compact hint mode (see `term.ts`).
3867
+ *
3868
+ * Written in the SAME register as the `promptHint`: this catalog describes
3869
+ * the SUBJECT's emotional state, so a term names the expression / demeanor
3870
+ * ("melancholic expression", "cocky smirk", "fierce, commanding intensity"),
3871
+ * never the scene's mood — "melancholic mood" would instruct a different
3872
+ * picture from the one full mode asks for.
3873
+ */
3874
+ readonly term?: string;
3164
3875
  }
3165
3876
  declare const MOODS: ReadonlyArray<Mood>;
3166
3877
  declare function getMood(id: string | undefined | null): Mood | undefined;
3167
3878
  declare function getMoodLabel(id: string | undefined | null, fallback?: string): string;
3168
3879
  declare function getMoodPromptHint(id: string | undefined | null): string;
3880
+ /**
3881
+ * The COMPACT counterpart of `getMoodPromptHint`: the short professional term
3882
+ * ("melancholic expression", "cocky smirk") a consumer injects instead of the
3883
+ * full expression clause. Same lookup, same empty-string-on-miss behavior.
3884
+ */
3885
+ declare function getMoodTerm(id: string | undefined | null): string;
3169
3886
  declare const MOOD_IDS: ReadonlyArray<string>;
3170
3887
  declare const MOOD_CATEGORY_LABELS: Readonly<Record<MoodCategory, string>>;
3171
3888
  declare const MOOD_CATEGORY_ORDER: ReadonlyArray<MoodCategory>;
@@ -3182,8 +3899,18 @@ interface MoodValue {
3182
3899
  * Build prompt hints from MoodData: optional pre-text, the selected mood's
3183
3900
  * hint (single or mixed), optional post-text. Returns array — caller joins
3184
3901
  * with ", ".
3902
+ *
3903
+ * @param mode `"compact"` swaps the mood fragment for its short professional
3904
+ * term (delegates to `buildMoodTerms`); pre/post free text is unaffected.
3905
+ */
3906
+ declare function buildMoodHints(data: Record<string, unknown> & MoodValue, mode?: PickerHintMode): string[];
3907
+ /**
3908
+ * Compact counterpart of `buildMoodHints`: the same pre-text → mood →
3909
+ * post-text order, emitting the mood's short professional term ("melancholic
3910
+ * expression", "cocky smirk") instead of the full expression clause. Free-text
3911
+ * pre/post fields are user prose and pass through unchanged in both modes.
3185
3912
  */
3186
- declare function buildMoodHints(data: Record<string, unknown> & MoodValue): string[];
3913
+ declare function buildMoodTerms(data: Record<string, unknown> & MoodValue): string[];
3187
3914
 
3188
3915
  /**
3189
3916
  * Canonical catalog of music genres for Suno / MiniMax / Text-to-Audio
@@ -3198,6 +3925,7 @@ declare function buildMoodHints(data: Record<string, unknown> & MoodValue): stri
3198
3925
  * are Splice-aligned (https://splice.com/sounds/genres) so the taxonomy
3199
3926
  * matches industry conventions.
3200
3927
  */
3928
+
3201
3929
  type MusicGenreCategory = "hip-hop-rnb" | "electronic" | "pop" | "rock-metal" | "acoustic" | "global" | "cinematic";
3202
3930
  declare const MUSIC_GENRE_CATEGORY_ORDER: ReadonlyArray<MusicGenreCategory>;
3203
3931
  declare const MUSIC_GENRE_CATEGORY_LABELS: Readonly<Record<MusicGenreCategory, string>>;
@@ -3205,12 +3933,28 @@ interface MusicSubgenre {
3205
3933
  readonly id: string;
3206
3934
  readonly label: string;
3207
3935
  readonly promptHint: string;
3936
+ /**
3937
+ * Compact professional form injected in COMPACT hint mode (see `term.ts`).
3938
+ * Authored where the lowercased label is not the genre name a producer would
3939
+ * write — the picker drops the parent genre from the label to keep the tile
3940
+ * short ("Conscious" → "conscious hip hop", "Beats" → "lo-fi beats"), the
3941
+ * label is a UI compound the derivation mangles ("Drum & Bass",
3942
+ * "Trap (EDM)"), or the bare word means something else entirely outside
3943
+ * music ("Dub", "Swing", "Romantic"). Everywhere else the label IS the term.
3944
+ */
3945
+ readonly term?: string;
3208
3946
  }
3209
3947
  interface MusicGenre {
3210
3948
  readonly id: string;
3211
3949
  readonly label: string;
3212
3950
  readonly description: string;
3213
3951
  readonly promptHint: string;
3952
+ /**
3953
+ * Compact professional form (see `term.ts`), authored where the lowercased
3954
+ * label does not read as a music genre on its own — "World" → "world music",
3955
+ * "R&B" → "rhythm and blues". Everywhere else the label IS the term.
3956
+ */
3957
+ readonly term?: string;
3214
3958
  readonly category: MusicGenreCategory;
3215
3959
  readonly subgenres: ReadonlyArray<MusicSubgenre>;
3216
3960
  }
@@ -3219,6 +3963,12 @@ interface MusicEra {
3219
3963
  readonly label: string;
3220
3964
  readonly description: string;
3221
3965
  readonly promptHint: string;
3966
+ /**
3967
+ * Compact professional form (see `term.ts`). The decade labels already ARE
3968
+ * the term; authored only for the named eras whose label is not what a
3969
+ * producer writes ("Futurist" → "futuristic").
3970
+ */
3971
+ readonly term?: string;
3222
3972
  }
3223
3973
  declare const MUSIC_GENRES: ReadonlyArray<MusicGenre>;
3224
3974
  declare const MUSIC_ERAS: ReadonlyArray<MusicEra>;
@@ -3226,6 +3976,21 @@ declare function getMusicGenre(id: string | undefined): MusicGenre | undefined;
3226
3976
  declare function getMusicGenreLabel(id: string | undefined): string;
3227
3977
  declare function getMusicSubgenre(genreId: string | undefined, subgenreId: string | undefined): MusicSubgenre | undefined;
3228
3978
  declare function getMusicEra(id: string | undefined): MusicEra | undefined;
3979
+ /**
3980
+ * Compact counterpart of a genre's `promptHint`: the short genre name a
3981
+ * producer would write ("rhythm and blues", "world music"). Same lookup and
3982
+ * same empty-string-on-miss behavior as `getMusicGenre`, so hint mode and
3983
+ * compact mode can never disagree about which genre they describe.
3984
+ */
3985
+ declare function getMusicGenreTerm(id: string | undefined | null): string;
3986
+ /**
3987
+ * Compact counterpart for a subgenre. Keeps `getMusicSubgenre`'s two-argument
3988
+ * lookup — a subgenre id is unique only within its parent genre, so a
3989
+ * single-id term getter could not resolve one.
3990
+ */
3991
+ declare function getMusicSubgenreTerm(genreId: string | undefined | null, subgenreId: string | undefined | null): string;
3992
+ /** Compact counterpart of an era's `promptHint` — the short period name. */
3993
+ declare function getMusicEraTerm(id: string | undefined | null): string;
3229
3994
  /**
3230
3995
  * Compose hints from MusicGenreData: optional preText, structured
3231
3996
  * [era] [subgenre|genre] (or " / "-joined genres for multi), optional
@@ -3242,6 +4007,20 @@ declare function buildMusicGenreHints(data: {
3242
4007
  readonly genre?: string | ReadonlyArray<string>;
3243
4008
  readonly subgenre?: string;
3244
4009
  readonly era?: string;
4010
+ }, mode?: PickerHintMode): string;
4011
+ /**
4012
+ * Compact-mode mirror of `buildMusicGenreHints`: the same preText / [era]
4013
+ * [subgenre|genre] / postText structure, built from each entry's short `term`
4014
+ * instead of its `promptHint` ("1980s synth pop"). Multi-genre still joins
4015
+ * with " / " and still ignores the subgenre, and preText / postText — user
4016
+ * free text, not catalog copy — pass through untouched.
4017
+ */
4018
+ declare function buildMusicGenreTerms(data: {
4019
+ readonly preText?: string;
4020
+ readonly postText?: string;
4021
+ readonly genre?: string | ReadonlyArray<string>;
4022
+ readonly subgenre?: string;
4023
+ readonly era?: string;
3245
4024
  }): string;
3246
4025
  /** Default data when a music-genre node is dropped on canvas. Empty by design — forces a deliberate pick. */
3247
4026
  declare const MUSIC_GENRE_DEFAULT_DATA: {
@@ -3256,11 +4035,22 @@ declare const MUSIC_GENRE_DEFAULT_DATA: {
3256
4035
  * Music mood catalog: energy + emotion + vibe sub-fields.
3257
4036
  * Composed by buildMusicMoodHints into "[energy] [emotion] [vibe]".
3258
4037
  */
4038
+
3259
4039
  interface MusicMoodEntry {
3260
4040
  readonly id: string;
3261
4041
  readonly label: string;
3262
4042
  readonly description: string;
3263
4043
  readonly promptHint: string;
4044
+ /**
4045
+ * Compact professional term injected in compact hint mode (see `term.ts`).
4046
+ *
4047
+ * Authored only where the lowercased label is NOT the phrase a music
4048
+ * supervisor would write — the bare-degree energies ("Low"/"Moderate"/
4049
+ * "High" mean nothing without "energy" attached) and the noun-shaped
4050
+ * "Awe". Everywhere else the label already IS the trade descriptor and
4051
+ * `resolveTerm` derives it.
4052
+ */
4053
+ readonly term?: string;
3264
4054
  }
3265
4055
  declare const MUSIC_ENERGIES: ReadonlyArray<MusicMoodEntry>;
3266
4056
  declare const MUSIC_EMOTIONS: ReadonlyArray<MusicMoodEntry>;
@@ -3268,13 +4058,30 @@ declare const MUSIC_VIBES: ReadonlyArray<MusicMoodEntry>;
3268
4058
  declare function getMusicEnergy(id: string | undefined): MusicMoodEntry | undefined;
3269
4059
  declare function getMusicEmotion(id: string | undefined): MusicMoodEntry | undefined;
3270
4060
  declare function getMusicVibe(id: string | undefined): MusicMoodEntry | undefined;
3271
- declare function buildMusicMoodHints(data: {
4061
+ /**
4062
+ * The COMPACT counterparts of the `promptHint` lookups: the short professional
4063
+ * term a consumer injects instead of the entry's full fragment ("low-energy",
4064
+ * "building energy", "awe-inspiring"). Same lookup as the getters above, same
4065
+ * empty-string-on-miss behavior, so hint mode and term mode can never disagree
4066
+ * about WHICH entry they are describing.
4067
+ */
4068
+ declare function getMusicEnergyTerm(id: string | undefined | null): string;
4069
+ declare function getMusicEmotionTerm(id: string | undefined | null): string;
4070
+ declare function getMusicVibeTerm(id: string | undefined | null): string;
4071
+ interface MusicMoodData {
3272
4072
  readonly preText?: string;
3273
4073
  readonly postText?: string;
3274
4074
  readonly energy?: string;
3275
4075
  readonly emotion?: string | ReadonlyArray<string>;
3276
4076
  readonly vibe?: string | ReadonlyArray<string>;
3277
- }): string;
4077
+ }
4078
+ declare function buildMusicMoodHints(data: MusicMoodData, mode?: PickerHintMode): string;
4079
+ /**
4080
+ * The COMPACT counterpart of `buildMusicMoodHints`: the same field walk in the
4081
+ * same canonical order, emitting each selection's short professional term
4082
+ * instead of its full prompt fragment.
4083
+ */
4084
+ declare function buildMusicMoodTerms(data: MusicMoodData): string;
3278
4085
  declare const MUSIC_MOOD_DEFAULT_DATA: {
3279
4086
  preText?: string;
3280
4087
  postText?: string;
@@ -3318,11 +4125,21 @@ interface PhotoGenre {
3318
4125
  readonly category: PhotoGenreCategory;
3319
4126
  readonly description: string;
3320
4127
  readonly promptHint: string;
4128
+ /**
4129
+ * Compact professional term (see `term.ts`). Authored only where the
4130
+ * lowercased label is not what a photographer would write in a prompt —
4131
+ * UI compounds ("Campaign / Ad"), the "Signature" brand framing, and bare
4132
+ * nouns that read as the SUBJECT rather than the genre ("documentary",
4133
+ * "real estate", "advertising"). Elsewhere the label IS the term.
4134
+ */
4135
+ readonly term?: string;
3321
4136
  }
3322
4137
  declare const PHOTO_GENRES: ReadonlyArray<PhotoGenre>;
3323
4138
  declare function getPhotoGenre(id: string | undefined | null): PhotoGenre | undefined;
3324
4139
  declare function getPhotoGenreLabel(id: string | undefined | null, fallback?: string): string;
3325
4140
  declare function getPhotoGenrePromptHint(id: string | undefined | null): string;
4141
+ /** Compact-mode sibling of `getPhotoGenrePromptHint` — the short trade term. */
4142
+ declare function getPhotoGenreTerm(id: string | undefined | null): string;
3326
4143
  declare const PHOTO_GENRE_IDS: ReadonlyArray<string>;
3327
4144
  declare const PHOTO_GENRE_CATEGORY_LABELS: Readonly<Record<PhotoGenreCategory, string>>;
3328
4145
  declare const PHOTO_GENRE_CATEGORY_ORDER: ReadonlyArray<PhotoGenreCategory>;
@@ -3347,6 +4164,7 @@ declare const PHOTO_GENRE_CATEGORY_ORDER: ReadonlyArray<PhotoGenreCategory>;
3347
4164
  * and the prompt-hint injection on both the frontend DAG executor and the
3348
4165
  * backend orchestrator.
3349
4166
  */
4167
+
3350
4168
  type PhotographerCategory = "editorial" | "documentary" | "cinematographer" | "concept" | "illustrator";
3351
4169
  interface Photographer {
3352
4170
  readonly id: string;
@@ -3354,17 +4172,55 @@ interface Photographer {
3354
4172
  readonly category: PhotographerCategory;
3355
4173
  readonly description: string;
3356
4174
  readonly promptHint: string;
4175
+ /**
4176
+ * Compact-mode term (see `term.ts`). Authored on EVERY entry here, which is
4177
+ * the exception rather than the rule for a catalog — two reasons specific to
4178
+ * artist styles:
4179
+ *
4180
+ * 1. The derived term would be a bare person's name. Injected raw into a
4181
+ * generation prompt, "annie leibovitz" reads as the SUBJECT to render,
4182
+ * not as an attribution — it asks for a picture OF the photographer.
4183
+ * Consumers inject `term` verbatim (they render `label` and inject
4184
+ * `term`), so the framing has to live in the term itself.
4185
+ * 2. Per this file's own premise, the name token alone is too vague; the
4186
+ * model needs a little of the surrounding visual vocabulary to lock onto
4187
+ * the signature. So each term is `by <name>, <2-3 signature cues>` — a
4188
+ * compression of the promptHint's own shape, never a copy of it.
4189
+ * Cinematographers take the DP credit "shot by" instead.
4190
+ *
4191
+ * Optional per the `term.ts` convention, but in THIS catalog a new entry
4192
+ * that omits it falls back to the bare-name derivation described above —
4193
+ * author one alongside the promptHint.
4194
+ */
4195
+ readonly term?: string;
3357
4196
  }
3358
4197
  declare const PHOTOGRAPHERS: ReadonlyArray<Photographer>;
3359
4198
  declare function getPhotographer(id: string | undefined | null): Photographer | undefined;
3360
4199
  declare function getPhotographerLabel(id: string | undefined | null, fallback?: string): string;
3361
4200
  declare function getPhotographerPromptHint(id: string | undefined | null): string;
4201
+ /**
4202
+ * Compact-mode sibling of `getPhotographerPromptHint` — same arity, same
4203
+ * lookup, same empty-string-on-miss behavior, so the two can never disagree
4204
+ * about which entry they are describing.
4205
+ */
4206
+ declare function getPhotographerTerm(id: string | undefined | null): string;
3362
4207
  /**
3363
4208
  * Multi-pick variant: 1-2 photographer ids → blended hint. Single → entry's
3364
4209
  * own promptHint. Two → "shot in the blended language of {A} and {B}" — the
3365
4210
  * model interprets this as referencing both creators' visual signatures.
3366
4211
  */
3367
- declare function buildPhotographerHints(value: unknown): string;
4212
+ declare function buildPhotographerHints(value: unknown, mode?: PickerHintMode): string;
4213
+ /**
4214
+ * Compact-mode sibling of `buildPhotographerHints`, mirroring its structure:
4215
+ * one id → that entry's term, two → a blend. The blend drops the per-entry
4216
+ * signature cues and keeps only the credited names, because stacking two
4217
+ * `by <name>, <cues>` fragments is longer than the compact mode exists to be.
4218
+ *
4219
+ * The credit verb is READ OFF the resolved terms rather than hardcoded, so a
4220
+ * cinematographer's "shot by" survives the blend and the one-pick and two-pick
4221
+ * paths can never disagree about how the same entry is credited.
4222
+ */
4223
+ declare function buildPhotographerTerms(value: unknown): string;
3368
4224
  declare const PHOTOGRAPHER_IDS: ReadonlyArray<string>;
3369
4225
  declare const PHOTOGRAPHER_CATEGORY_LABELS: Readonly<Record<PhotographerCategory, string>>;
3370
4226
  declare const PHOTOGRAPHER_CATEGORY_ORDER: ReadonlyArray<PhotographerCategory>;
@@ -3390,6 +4246,7 @@ declare const PHOTOGRAPHER_CATEGORY_ORDER: ReadonlyArray<PhotographerCategory>;
3390
4246
  * the prompt-hint injection on both the frontend DAG executor and the
3391
4247
  * backend orchestrator.
3392
4248
  */
4249
+
3393
4250
  type PoseCategory = "standing" | "seated" | "movement" | "action" | "resting" | "hand-position" | "body-lean" | "head-tilt" | "activity";
3394
4251
  interface Pose {
3395
4252
  readonly id: string;
@@ -3397,11 +4254,27 @@ interface Pose {
3397
4254
  readonly category: PoseCategory;
3398
4255
  readonly description: string;
3399
4256
  readonly promptHint: string;
4257
+ /**
4258
+ * Compact professional term injected instead of `promptHint` in compact hint
4259
+ * mode. Authored only where the lowercased label is not what a photographer
4260
+ * would write for the pose — bare sub-dimension modifiers ("Tilted Side"),
4261
+ * labels that collide with a different meaning in a generation prompt
4262
+ * ("Painting"), and telegraphic UI phrasings ("Head Over Shoulder").
4263
+ * Everywhere else the derived label already IS the term.
4264
+ */
4265
+ readonly term?: string;
3400
4266
  }
3401
4267
  declare const POSES: ReadonlyArray<Pose>;
3402
4268
  declare function getPose(id: string | undefined | null): Pose | undefined;
3403
4269
  declare function getPoseLabel(id: string | undefined | null, fallback?: string): string;
3404
4270
  declare function getPosePromptHint(id: string | undefined | null): string;
4271
+ /**
4272
+ * Compact counterpart of `getPosePromptHint`: the short professional term this
4273
+ * pose injects in compact hint mode ("mid-throw" where the hint is the full
4274
+ * body-mechanics sentence). Empty string for an unknown id and for any entry
4275
+ * that injects no hint at all.
4276
+ */
4277
+ declare function getPoseTerm(id: string | undefined | null): string;
3405
4278
  declare const POSE_IDS: ReadonlyArray<string>;
3406
4279
  declare const POSE_CATEGORY_LABELS: Readonly<Record<PoseCategory, string>>;
3407
4280
  declare const POSE_CATEGORY_ORDER: ReadonlyArray<PoseCategory>;
@@ -3430,7 +4303,15 @@ interface PoseValue {
3430
4303
  * hint, the orthogonal hand-position / body-lean / head-tilt hints,
3431
4304
  * optional post-text. Returns array — caller joins with ", ".
3432
4305
  */
3433
- declare function buildPoseHints(data: Record<string, unknown> & PoseValue): string[];
4306
+ declare function buildPoseHints(data: Record<string, unknown> & PoseValue, mode?: PickerHintMode): string[];
4307
+ /**
4308
+ * Compact counterpart of `buildPoseHints`: the same pre-text → pose →
4309
+ * hand-position → body-lean → head-tilt → activity → post-text order, emitted
4310
+ * as short professional terms instead of full mechanism sentences
4311
+ * ("mid-throw, hands clasped behind the head"). Free-text pre/post fields are
4312
+ * user prose and pass through unchanged in both modes.
4313
+ */
4314
+ declare function buildPoseTerms(data: Record<string, unknown> & PoseValue): string[];
3434
4315
 
3435
4316
  /**
3436
4317
  * Canonical catalog of Post-Process Effects choices.
@@ -3454,23 +4335,46 @@ declare function buildPoseHints(data: Record<string, unknown> & PoseValue): stri
3454
4335
  * Shared between picker UI and prompt-hint injection in the frontend DAG
3455
4336
  * executor and the backend orchestrator.
3456
4337
  */
4338
+
3457
4339
  interface PostProcessEffect {
3458
4340
  readonly id: string;
3459
4341
  readonly label: string;
3460
4342
  readonly description: string;
3461
4343
  readonly promptHint: string;
4344
+ /**
4345
+ * Optional authored compact term (see `term.ts`). Authored only where the
4346
+ * lowercased label is not the phrase a colorist / retoucher would write in a
4347
+ * prompt — "Bloom Glow" and "Color Fringe" are UI compounds, the trade terms
4348
+ * are "highlight bloom" and "color fringing". Everywhere else the label IS
4349
+ * the term.
4350
+ */
4351
+ readonly term?: string;
3462
4352
  }
3463
4353
  declare const POST_PROCESS_EFFECTS: ReadonlyArray<PostProcessEffect>;
3464
4354
  declare function getPostProcessEffect(id: string | undefined | null): PostProcessEffect | undefined;
3465
4355
  declare function getPostProcessEffectLabel(id: string | undefined | null, fallback?: string): string;
3466
4356
  declare function getPostProcessEffectPromptHint(id: string | undefined | null): string;
4357
+ /**
4358
+ * Compact counterpart of `getPostProcessEffectPromptHint`: the short
4359
+ * professional term this pass injects in compact hint mode ("dodge and burn"
4360
+ * where the hint is the full mechanism sentence). Empty string for an unknown
4361
+ * id and for any entry that injects no hint at all.
4362
+ */
4363
+ declare function getPostProcessEffectTerm(id: string | undefined | null): string;
3467
4364
  /**
3468
4365
  * Multi-pick: 1-2 post-process effect ids → composite grading clause.
3469
4366
  * Common pairs: vignette + film-grain, halation + bloom, dodge-burn +
3470
4367
  * chromatic-aberration. Each entry already describes a complete grading
3471
4368
  * pass, so we emit independently and let the comma-join compose them.
3472
4369
  */
3473
- declare function buildPostProcessHints(value: unknown): string[];
4370
+ declare function buildPostProcessHints(value: unknown, mode?: PickerHintMode): string[];
4371
+ /**
4372
+ * Compact counterpart of `buildPostProcessHints`: the same 1-2 id multi-pick,
4373
+ * emitted as short professional terms instead of full mechanism sentences
4374
+ * ("soft vignette", "fine film grain"). Same collection order, same
4375
+ * skip-the-no-ops behavior.
4376
+ */
4377
+ declare function buildPostProcessTerms(value: unknown): string[];
3474
4378
  declare const POST_PROCESS_EFFECT_IDS: ReadonlyArray<string>;
3475
4379
 
3476
4380
  /**
@@ -3502,11 +4406,24 @@ interface RenderQuality {
3502
4406
  readonly label: string;
3503
4407
  readonly description: string;
3504
4408
  readonly promptHint: string;
4409
+ /**
4410
+ * Compact professional term (see `term.ts`). Authored only where the
4411
+ * lowercased label is NOT what a professional writes in a prompt — a bare
4412
+ * word that collides with ordinary English ("redshift", "aces"), an
4413
+ * abbreviation ("pbr"), a non-standard coinage ("16k megapixel"), a bare
4414
+ * modifier with no category noun ("denoised"), or a compound whose
4415
+ * canonical prompt spelling is hyphenated. Every other label here is
4416
+ * already the proper name of the thing ("octane render", "masterpiece")
4417
+ * and carries no `term`.
4418
+ */
4419
+ readonly term?: string;
3505
4420
  }
3506
4421
  declare const RENDER_QUALITIES: ReadonlyArray<RenderQuality>;
3507
4422
  declare function getRenderQuality(id: string | undefined | null): RenderQuality | undefined;
3508
4423
  declare function getRenderQualityLabel(id: string | undefined | null, fallback?: string): string;
3509
4424
  declare function getRenderQualityPromptHint(id: string | undefined | null): string;
4425
+ /** Compact-mode sibling of `getRenderQualityPromptHint` — same lookup, short form. */
4426
+ declare function getRenderQualityTerm(id: string | undefined | null): string;
3510
4427
  declare const RENDER_QUALITY_IDS: ReadonlyArray<string>;
3511
4428
 
3512
4429
  /**
@@ -3536,11 +4453,22 @@ interface Setting {
3536
4453
  readonly category: SettingCategory;
3537
4454
  readonly description: string;
3538
4455
  readonly promptHint: string;
4456
+ /**
4457
+ * Compact professional term (see `term.ts`). Authored only where the
4458
+ * lowercased label is not what a location scout / cinematographer would
4459
+ * write in a prompt — a building name standing in for the specific space
4460
+ * inside it ("Hospital" → "hospital corridor"), or a label that reads
4461
+ * ambiguously on its own ("Conservatory" → the greenhouse, not the music
4462
+ * school). Everywhere else the lowercased label IS the term.
4463
+ */
4464
+ readonly term?: string;
3539
4465
  }
3540
4466
  declare const SETTINGS: ReadonlyArray<Setting>;
3541
4467
  declare function getSetting(id: string | undefined | null): Setting | undefined;
3542
4468
  declare function getSettingLabel(id: string | undefined | null, fallback?: string): string;
3543
4469
  declare function getSettingPromptHint(id: string | undefined | null): string;
4470
+ /** Compact counterpart of {@link getSettingPromptHint} — the short setting term. */
4471
+ declare function getSettingTerm(id: string | undefined | null): string;
3544
4472
  declare const SETTING_IDS: ReadonlyArray<string>;
3545
4473
  declare const SETTING_CATEGORY_LABELS: Readonly<Record<SettingCategory, string>>;
3546
4474
 
@@ -3570,11 +4498,24 @@ interface Style {
3570
4498
  readonly label: string;
3571
4499
  readonly description: string;
3572
4500
  readonly promptHint: string;
4501
+ /**
4502
+ * Compact professional term (see `term.ts`). Authored only where the
4503
+ * lowercased label is not what an art director would write in a prompt —
4504
+ * a UI compound ("Retro / Vintage"), a bare noun that reads as a SUBJECT
4505
+ * rather than a medium ("Blueprint", "Chalkboard", "Graffiti"), a material
4506
+ * where the trade term names the artwork ("Acrylic Paint" → "acrylic
4507
+ * painting"), or a word that is ambiguous on its own ("Pastel" — the
4508
+ * medium, not the color range). Everywhere else the lowercased label IS
4509
+ * the term ("anime", "ukiyo-e", "cyberpunk") and nothing is authored.
4510
+ */
4511
+ readonly term?: string;
3573
4512
  }
3574
4513
  declare const STYLES: ReadonlyArray<Style>;
3575
4514
  declare function getStyle(id: string | undefined | null): Style | undefined;
3576
4515
  declare function getStyleLabel(id: string | undefined | null, fallback?: string): string;
3577
4516
  declare function getStylePromptHint(id: string | undefined | null): string;
4517
+ /** Compact counterpart of `getStylePromptHint` — see `term.ts`. */
4518
+ declare function getStyleTerm(id: string | undefined | null): string;
3578
4519
  declare const STYLE_IDS: ReadonlyArray<string>;
3579
4520
 
3580
4521
  /**
@@ -3624,6 +4565,7 @@ declare const STYLE_IDS: ReadonlyArray<string>;
3624
4565
  * Applies to BOTH image and video consumers. Includes pre/post free-text
3625
4566
  * fields for specifics the catalog can't express.
3626
4567
  */
4568
+
3627
4569
  type StylingDimension = "makeup" | "eyewear" | "headwear" | "hair-cut" | "hair-treatment" | "hair-state" | "jewelry" | "nails" | "face-paint" | "outfit" | "top" | "bottom" | "outerwear" | "legwear" | "footwear" | "fabric" | "wardrobe-state";
3628
4570
  interface Styling {
3629
4571
  readonly id: string;
@@ -3631,6 +4573,26 @@ interface Styling {
3631
4573
  readonly dimension: StylingDimension;
3632
4574
  readonly description: string;
3633
4575
  readonly promptHint: string;
4576
+ /**
4577
+ * Compact professional term for hint-compact mode (see `term.ts`).
4578
+ *
4579
+ * The line this catalog authors on: a label that NAMES a garment, material
4580
+ * or accessory ("Beanie", "Trench Coat", "Silk", "Hoop Earrings", "Doc
4581
+ * Martens") already IS the term a stylist writes, and gets nothing. A label
4582
+ * that is a bare MODIFIER — the whole of `hair-state`, `wardrobe-state`,
4583
+ * `nails`, and the adjective half of `makeup` / `jewelry` — means nothing
4584
+ * stripped of its category noun, so "Wet" becomes "wet hair" and "Gold"
4585
+ * becomes "gold jewelry".
4586
+ *
4587
+ * The same rule resolves this catalog's internal collisions, where two
4588
+ * dimensions share a label and would otherwise derive one indistinguishable
4589
+ * fragment: `hair-wet` / `state-wet` (both "Wet"), `jewelry-layered` /
4590
+ * `state-layered`, `makeup-goth` / `outfit-goth`. Homonym traps outside the
4591
+ * catalog get the same treatment — "Highlights" is a lighting word before it
4592
+ * is a hair word, "Cat-Eye" is eyeliner before it is eyewear, "Hood" is a
4593
+ * car part, "Bun" is bread.
4594
+ */
4595
+ readonly term?: string;
3634
4596
  }
3635
4597
  declare const STYLINGS: ReadonlyArray<Styling>;
3636
4598
  declare const STYLING_DIMENSION_ORDER: ReadonlyArray<StylingDimension>;
@@ -3690,8 +4652,23 @@ interface StylingValue {
3690
4652
  declare function getStyling(id: string | undefined | null): Styling | undefined;
3691
4653
  declare function getStylingLabel(id: string | undefined | null, fallback?: string): string;
3692
4654
  declare function getStylingPromptHint(id: string | undefined | null): string;
4655
+ /**
4656
+ * The COMPACT counterpart of `getStylingPromptHint`: the same lookup, same
4657
+ * arity, same empty-string-on-miss, returning the entry's short professional
4658
+ * term ("wet hair", "gold jewelry", "low ponytail") instead of its full
4659
+ * mechanism clause.
4660
+ */
4661
+ declare function getStylingTerm(id: string | undefined | null): string;
3693
4662
  declare const STYLING_IDS: ReadonlyArray<string>;
3694
- declare function buildStylingHints(data: Record<string, unknown> & StylingValue): string[];
4663
+ declare function buildStylingHints(data: Record<string, unknown> & StylingValue, mode?: PickerHintMode): string[];
4664
+ /**
4665
+ * The COMPACT counterpart of `buildStylingHints`: the same dimension walk in
4666
+ * the same canonical order, under the same `makeup-bold-lips` dedupe, emitting
4667
+ * each selection's short professional term ("wet hair", "leather jacket",
4668
+ * "gold jewelry") instead of its full mechanism clause. Free-text pre/post
4669
+ * fields are user prose and pass through unchanged in both modes.
4670
+ */
4671
+ declare function buildStylingTerms(data: Record<string, unknown> & StylingValue): string[];
3695
4672
 
3696
4673
  /**
3697
4674
  * Canonical catalog of temporal modifiers.
@@ -3709,6 +4686,7 @@ declare function buildStylingHints(data: Record<string, unknown> & StylingValue)
3709
4686
  * Shared between the picker UI and the prompt-hint injection on both the
3710
4687
  * frontend DAG executor and the backend orchestrator.
3711
4688
  */
4689
+
3712
4690
  type TemporalCategory = "speed" | "freeze" | "direction" | "shutter";
3713
4691
  interface Temporal {
3714
4692
  readonly id: string;
@@ -3716,6 +4694,16 @@ interface Temporal {
3716
4694
  readonly category: TemporalCategory;
3717
4695
  readonly description: string;
3718
4696
  readonly promptHint: string;
4697
+ /**
4698
+ * Compact professional term injected in compact hint mode (see `term.ts`).
4699
+ *
4700
+ * Authored where the picker label is a UI compound ("Reverse / Rewind",
4701
+ * "Loop / Boomerang") or a bare word that reads as something else entirely
4702
+ * inside a prompt — "Forward" as a camera move rather than playback
4703
+ * direction, "Moving Subject" as a plain description of the action rather
4704
+ * than the frozen-world effect it selects here.
4705
+ */
4706
+ readonly term?: string;
3719
4707
  }
3720
4708
  declare const TEMPORALS: ReadonlyArray<Temporal>;
3721
4709
  declare const TEMPORAL_CATEGORY_ORDER: ReadonlyArray<TemporalCategory>;
@@ -3723,6 +4711,13 @@ declare const TEMPORAL_CATEGORY_LABELS: Record<TemporalCategory, string>;
3723
4711
  declare function getTemporal(id: string | undefined | null): Temporal | undefined;
3724
4712
  declare function getTemporalLabel(id: string | undefined | null, fallback?: string): string;
3725
4713
  declare function getTemporalPromptHint(id: string | undefined | null): string;
4714
+ /**
4715
+ * The COMPACT counterpart of `getTemporalPromptHint`: the short professional
4716
+ * term ("super slow motion", "reverse playback", "boomerang loop") a consumer
4717
+ * injects instead of the full mechanism description. Same lookup, same
4718
+ * empty-string-on-miss behavior.
4719
+ */
4720
+ declare function getTemporalTerm(id: string | undefined | null): string;
3726
4721
  declare const TEMPORAL_IDS: ReadonlyArray<string>;
3727
4722
  /**
3728
4723
  * Maps each TemporalCategory to the consumer data field name that holds the
@@ -3761,6 +4756,18 @@ declare function buildTemporalHints(data: Record<string, unknown> & {
3761
4756
  temporalFreeze?: unknown;
3762
4757
  temporalDirection?: unknown;
3763
4758
  temporalShutter?: unknown;
4759
+ }, mode?: PickerHintMode): string[];
4760
+ /**
4761
+ * The COMPACT counterpart of `buildTemporalHints`: the same per-category walk
4762
+ * in the same canonical order, emitting each selection's short professional
4763
+ * term ("super slow motion", "bullet time", "reverse playback") instead of its
4764
+ * full mechanism description.
4765
+ */
4766
+ declare function buildTemporalTerms(data: Record<string, unknown> & {
4767
+ temporalSpeed?: unknown;
4768
+ temporalFreeze?: unknown;
4769
+ temporalDirection?: unknown;
4770
+ temporalShutter?: unknown;
3764
4771
  }): string[];
3765
4772
 
3766
4773
  /**
@@ -3776,6 +4783,7 @@ declare function buildTemporalHints(data: Record<string, unknown> & {
3776
4783
  * parameter nodes whose hints are folded into the composed clause as
3777
4784
  * "starting from <X>, ending at <Y>".
3778
4785
  */
4786
+
3779
4787
  type TransitionCategory = "standard" | "time" | "element" | "morph" | "portal" | "physics" | "light" | "glitch";
3780
4788
  interface Transition {
3781
4789
  readonly id: string;
@@ -3783,6 +4791,16 @@ interface Transition {
3783
4791
  readonly category: TransitionCategory;
3784
4792
  readonly description: string;
3785
4793
  readonly promptHint: string;
4794
+ /**
4795
+ * Optional authored compact term (see `term.ts`). Authored where the
4796
+ * lowercased label is not what an editor would write in a prompt — a UI
4797
+ * compound ("None / Hard Cut" → "hard cut"), an annotation the derivation
4798
+ * drops ("Fast-Forward (Day → Night)" → "day-to-night time-lapse"), a bare
4799
+ * word that collides with another meaning ("Melt Down", "Channel Flip",
4800
+ * "Roll"), or a coinage that is not the trade term ("Seamless Match" →
4801
+ * "invisible cut"). Everywhere else the label IS the term.
4802
+ */
4803
+ readonly term?: string;
3786
4804
  }
3787
4805
  type TransitionPosition = "auto" | "start" | "middle" | "end" | "full";
3788
4806
  type TransitionDuration = "auto" | "instant" | "short" | "medium" | "long";
@@ -3798,6 +4816,16 @@ declare const TRANSITION_CATEGORY_LABELS: Readonly<Record<TransitionCategory, st
3798
4816
  declare function getTransition(id: string | undefined | null): Transition | undefined;
3799
4817
  declare function getTransitionLabel(id: string | undefined | null, fallback?: string): string;
3800
4818
  declare function getTransitionPromptHint(id: string | undefined | null): string;
4819
+ /**
4820
+ * Compact professional TERM for an id — the short phrase an editor would write
4821
+ * in a prompt ("hard cut", "invisible cut", "day-to-night time-lapse"), as
4822
+ * opposed to the paragraph-length `promptHint`.
4823
+ *
4824
+ * Same lookup and same empty-string-on-miss behavior as
4825
+ * `getTransitionPromptHint`, so the two can never disagree about which entry
4826
+ * they describe. The no-op "Auto" entry resolves to `""` in both.
4827
+ */
4828
+ declare function getTransitionTerm(id: string | undefined | null): string;
3801
4829
  declare const TRANSITION_IDS: ReadonlyArray<string>;
3802
4830
  /**
3803
4831
  * Compose a structural prompt-hint sentence from a transition id (or array
@@ -3810,8 +4838,14 @@ declare const TRANSITION_IDS: ReadonlyArray<string>;
3810
4838
  * - n base hints joined with ", and "
3811
4839
  * - Timing/start/end clauses apply ONCE at the outer layer, not per-id
3812
4840
  * - null input is treated like undefined (falsy short-circuit → returns "")
4841
+ *
4842
+ * @param mode `"compact"` builds the base from each transition's short
4843
+ * professional `term` ("hard cut") instead of its full mechanism paragraph.
4844
+ * Everything else — the ", and " multi-pick join, the position/duration/
4845
+ * intensity clauses, and the "starting from"/"ending at" clauses — is
4846
+ * emitted identically in both modes.
3813
4847
  */
3814
- declare function composeTransitionHintFromConnections(transitionId: string | ReadonlyArray<string> | undefined, startHints: ReadonlyArray<string>, endHints: ReadonlyArray<string>, timing?: TransitionTiming): string;
4848
+ declare function composeTransitionHintFromConnections(transitionId: string | ReadonlyArray<string> | undefined, startHints: ReadonlyArray<string>, endHints: ReadonlyArray<string>, timing?: TransitionTiming, mode?: PickerHintMode): string;
3815
4849
 
3816
4850
  /**
3817
4851
  * Voice-character catalog: age + gender + language + accent + timbre. Feeds
@@ -3821,11 +4855,14 @@ declare function composeTransitionHintFromConnections(transitionId: string | Rea
3821
4855
  * voice work. Distinct from `accent` — accent is HOW it sounds, language
3822
4856
  * is WHAT'S being spoken.
3823
4857
  */
4858
+
3824
4859
  interface VoiceCharacterEntry {
3825
4860
  readonly id: string;
3826
4861
  readonly label: string;
3827
4862
  readonly description: string;
3828
4863
  readonly promptHint: string;
4864
+ /** Optional authored compact term (see `term.ts` for the convention). */
4865
+ readonly term?: string;
3829
4866
  }
3830
4867
  declare const VOICE_AGES: ReadonlyArray<VoiceCharacterEntry>;
3831
4868
  declare const VOICE_GENDERS: ReadonlyArray<VoiceCharacterEntry>;
@@ -3837,6 +4874,40 @@ declare function getVoiceGender(id: string | undefined): VoiceCharacterEntry | u
3837
4874
  declare function getVoiceLanguage(id: string | undefined): VoiceCharacterEntry | undefined;
3838
4875
  declare function getVoiceAccent(id: string | undefined): VoiceCharacterEntry | undefined;
3839
4876
  declare function getVoiceTimbre(id: string | undefined): VoiceCharacterEntry | undefined;
4877
+ /**
4878
+ * The COMPACT counterparts of the five sub-field lookups: the short
4879
+ * professional term a consumer injects instead of the entry's hint fragment.
4880
+ * Same lookup, same empty-string-on-miss behavior.
4881
+ *
4882
+ * Accent and timbre terms CARRY their dimension noun — "boston accent",
4883
+ * "french accent", "warm timbre" — where the `promptHint` fragments are bare
4884
+ * ("Boston", "French-accented", "warm") and only read as an accent or a
4885
+ * timbre once `buildVoiceCharacterHints` appends the noun. The term has to
4886
+ * stand on its own because a thin client injects one by itself (a picker
4887
+ * chip), with no composer to append anything: a bare "french" there is
4888
+ * indistinguishable from the LANGUAGE French sitting in the neighbouring
4889
+ * dimension.
4890
+ *
4891
+ * Age, gender and language terms deliberately stay BARE — "male", "mature",
4892
+ * "english". Do NOT "fix" them by authoring the noun into the data:
4893
+ * `composeVoiceCharacter` appends " voice" to the age+gender group itself, so
4894
+ * a "male voice" term would emit "...male voice voice".
4895
+ */
4896
+ declare function getVoiceAgeTerm(id: string | undefined | null): string;
4897
+ declare function getVoiceGenderTerm(id: string | undefined | null): string;
4898
+ declare function getVoiceLanguageTerm(id: string | undefined | null): string;
4899
+ declare function getVoiceAccentTerm(id: string | undefined | null): string;
4900
+ declare function getVoiceTimbreTerm(id: string | undefined | null): string;
4901
+ /** The consumer fields a voice-character clause is composed from. */
4902
+ type VoiceCharacterFieldSource = {
4903
+ readonly preText?: string;
4904
+ readonly postText?: string;
4905
+ readonly age?: string;
4906
+ readonly gender?: string;
4907
+ readonly language?: string | ReadonlyArray<string>;
4908
+ readonly accent?: string;
4909
+ readonly timbre?: string;
4910
+ };
3840
4911
  /**
3841
4912
  * Compose a natural-language voice character clause.
3842
4913
  * Examples (depending on which sub-fields are set):
@@ -3850,15 +4921,20 @@ declare function getVoiceTimbre(id: string | undefined): VoiceCharacterEntry | u
3850
4921
  * `language` is multi-pick — multiple languages emit "English / Spanish"
3851
4922
  * for codeswitching / multilingual voices.
3852
4923
  */
3853
- declare function buildVoiceCharacterHints(data: {
3854
- readonly preText?: string;
3855
- readonly postText?: string;
3856
- readonly age?: string;
3857
- readonly gender?: string;
3858
- readonly language?: string | ReadonlyArray<string>;
3859
- readonly accent?: string;
3860
- readonly timbre?: string;
3861
- }): string;
4924
+ declare function buildVoiceCharacterHints(data: VoiceCharacterFieldSource, mode?: PickerHintMode): string;
4925
+ /**
4926
+ * The COMPACT counterpart of `buildVoiceCharacterHints`: the same clause
4927
+ * skeleton, built from each selection's short professional term instead of its
4928
+ * hint fragment. The dimension noun is attached idempotently — an authored
4929
+ * term already carries it ("warm timbre", "received pronunciation accent") and
4930
+ * passes through untouched.
4931
+ * Examples:
4932
+ * { age, gender, timbre, accent } → "middle-aged male voice with warm timbre and received pronunciation accent"
4933
+ * { timbre } → "warm timbre"
4934
+ * { language: ["english","spanish"] } → "english / spanish voice"
4935
+ * { } → ""
4936
+ */
4937
+ declare function buildVoiceCharacterTerms(data: VoiceCharacterFieldSource): string;
3862
4938
  declare const VOICE_CHARACTER_DEFAULT_DATA: {
3863
4939
  preText?: string;
3864
4940
  postText?: string;
@@ -3873,11 +4949,20 @@ declare const VOICE_CHARACTER_DEFAULT_DATA: {
3873
4949
  * Voice-delivery catalog: pace + emotion + archetype. Feeds
3874
4950
  * Voice Design's voiceDescription via the Sound aggregator.
3875
4951
  */
4952
+
3876
4953
  interface VoiceDeliveryEntry {
3877
4954
  readonly id: string;
3878
4955
  readonly label: string;
3879
4956
  readonly description: string;
3880
4957
  readonly promptHint: string;
4958
+ /**
4959
+ * The COMPACT professional term this entry injects (see `./term.js`).
4960
+ * Authored only where the lowercased label is not what a voice director
4961
+ * would actually write — "drawled" not "drawl", "robotic" not "robot",
4962
+ * "nature documentary narrator" not "nature narrator". Everywhere else the
4963
+ * derived label already IS the term and nothing is stored.
4964
+ */
4965
+ readonly term?: string;
3881
4966
  }
3882
4967
  declare const VOICE_PACES: ReadonlyArray<VoiceDeliveryEntry>;
3883
4968
  declare const VOICE_EMOTIONS: ReadonlyArray<VoiceDeliveryEntry>;
@@ -3885,6 +4970,16 @@ declare const VOICE_ARCHETYPES: ReadonlyArray<VoiceDeliveryEntry>;
3885
4970
  declare function getVoicePace(id: string | undefined): VoiceDeliveryEntry | undefined;
3886
4971
  declare function getVoiceEmotion(id: string | undefined): VoiceDeliveryEntry | undefined;
3887
4972
  declare function getVoiceArchetype(id: string | undefined): VoiceDeliveryEntry | undefined;
4973
+ /**
4974
+ * The COMPACT counterparts of the three lookups above: the short professional
4975
+ * term a consumer injects instead of the full prompt fragment ("drawled",
4976
+ * "reassuring", "nature documentary narrator"). Same lookup, same
4977
+ * empty-string-on-miss behavior as the hint side, so the two can never
4978
+ * disagree about which entry they describe.
4979
+ */
4980
+ declare function getVoicePaceTerm(id: string | undefined | null): string;
4981
+ declare function getVoiceEmotionTerm(id: string | undefined | null): string;
4982
+ declare function getVoiceArchetypeTerm(id: string | undefined | null): string;
3888
4983
  /**
3889
4984
  * Compose a delivery clause.
3890
4985
  * Examples:
@@ -3899,6 +4994,20 @@ declare function buildVoiceDeliveryHints(data: {
3899
4994
  readonly pace?: string;
3900
4995
  readonly emotion?: string;
3901
4996
  readonly archetype?: string;
4997
+ }, mode?: PickerHintMode): string;
4998
+ /**
4999
+ * Compact-mode mirror of `buildVoiceDeliveryHints`: the same preText /
5000
+ * [pace] [archetype]-style delivery / [emotion] tone / postText structure,
5001
+ * built from each selection's short `term` instead of its `promptHint`
5002
+ * ("drawled noir-detective-style delivery, menacing tone"). preText and
5003
+ * postText — user free text, not catalog copy — pass through untouched.
5004
+ */
5005
+ declare function buildVoiceDeliveryTerms(data: {
5006
+ readonly preText?: string;
5007
+ readonly postText?: string;
5008
+ readonly pace?: string;
5009
+ readonly emotion?: string;
5010
+ readonly archetype?: string;
3902
5011
  }): string;
3903
5012
  declare const VOICE_DELIVERY_DEFAULT_DATA: {
3904
5013
  preText?: string;
@@ -3995,6 +5104,34 @@ declare function getPromptDoctrine(providerId: string): ProviderPromptDoctrine |
3995
5104
  /** Compact tips for a provider id ([] when none) — used by list_models. */
3996
5105
  declare function getPromptTips(providerId: string): readonly string[];
3997
5106
 
5107
+ /**
5108
+ * Reference-image prompting doctrine for IMAGE generation — the single source
5109
+ * of truth for the `{image:N:label}` token idiom on `generate-image`. Consumed
5110
+ * by backend/scripts/gen-skills (the `image-reference-prompting` block in the
5111
+ * generate-image node skill), the same way `PROVIDER_PROMPT_DOCTRINES` feeds
5112
+ * the video node skills.
5113
+ *
5114
+ * Unlike the per-provider video doctrines, this is a PLATFORM mechanism: the
5115
+ * token grammar and expansion are Nodaro's own (`prompt-builder.ts` —
5116
+ * `IMAGE_TOKEN_PATTERN`, `expandImageRefTokens`), so there is one doctrine,
5117
+ * not one per model family.
5118
+ *
5119
+ * Source of truth for the semantics documented here (verified 2026-08-25):
5120
+ * - `IMAGE_TOKEN_PATTERN` = `/\{image:(\d+)(?::([^}\n]+))?\}/gi`
5121
+ * - `expandImageRefTokens`: `{image:N:label}` → `Image N (label)`,
5122
+ * `{image:N}` → `Image N`; out-of-range tokens are left untouched so the
5123
+ * author can see and fix them.
5124
+ * - N is the reference's 1-based position in the assembled reference list
5125
+ * (connection order on the `references` handle).
5126
+ */
5127
+ interface ImageReferenceDoctrine {
5128
+ /** Human heading for skill docs. */
5129
+ readonly heading: string;
5130
+ /** Full markdown doctrine for generated skill docs. */
5131
+ readonly doctrine: string;
5132
+ }
5133
+ declare const IMAGE_REFERENCE_PROMPT_DOCTRINE: ImageReferenceDoctrine;
5134
+
3998
5135
  /**
3999
5136
  * Prompt Wizard — shared types, category definitions, and provider capabilities.
4000
5137
  *
@@ -4309,4 +5446,4 @@ declare function getPickerWiring(nodeType: string | undefined | null): PickerWir
4309
5446
  */
4310
5447
  declare function buildSurroundFillPrompt(direction: SurroundDirection, userPrompt?: string): string;
4311
5448
 
4312
- export { ACTION_FX, ACTION_FX_CATEGORY_LABELS, ACTION_FX_CATEGORY_ORDER, ACTION_FX_IDS, AESTHETICS, AESTHETIC_CATEGORY_LABELS, AESTHETIC_CATEGORY_ORDER, AESTHETIC_IDS, ALL_PICKER_WIRING, ANALYZABLE_PICKER_TYPES, ANGLE_LABELS, ASPECT_RATIO_LABELS, ATMOSPHERES, ATMOSPHERE_IDS, AUDIO_WIZARD_CATEGORIES, type ActionFx, type ActionFxCategory, type Aesthetic, type AestheticCategory, type AssembleImageInput, type AssembleSunoInput, type AssembleSunoResult, type Atmosphere, BACKDROPS, BACKDROP_CATEGORY_LABELS, BACKDROP_CATEGORY_ORDER, BACKDROP_IDS, BRAND_PRESETS, BRAND_PRESET_IDS, BRAND_PRESET_META, type Backdrop, type BackdropCategory, type BrandCasing, type BrandFonts, type BrandLogo, type BrandPalette, type BrandPresetId, type BrandPresetMeta, type BrandTokens, type BrandTypeSpec, type BuildImagePromptConfig, type BuildImagePromptResult, type BuildImagePromptSegmentsResult, CAMERA_FORMATS, CAMERA_FORMAT_IDS, CAMERA_MOTIONS, CAMERA_MOTION_CATEGORY_LABELS, CAMERA_MOTION_CATEGORY_ORDER, CAMERA_MOTION_IDS, CHARACTER_FX, CHARACTER_FX_CATEGORY_LABELS, CHARACTER_FX_CATEGORY_ORDER, CHARACTER_FX_IDS, CINEMATIC_LOOK_TAIL, COLOR_LOOKS, COLOR_LOOK_CATEGORY_LABELS, COLOR_LOOK_CATEGORY_ORDER, COLOR_LOOK_IDS, COMPOSITION_EFFECTS, COMPOSITION_EFFECT_IDS, type CameraFormat, type CameraMotion, type CameraMotionCategory, type CategorizedInstrument, type CharacterFx, type CharacterFxCategory, type CharacterFxDuration, type CharacterFxIntensity, type CharacterFxPosition, type CharacterFxTiming, type CharacterMeta, type CharacterMotionPromptInput, type CharacterPromptInput, type ColorLook, type ColorLookCategory, type CompositionEffect, type ComputeNodePromptArgs, type CreaturePromptInput, DEFAULT_IDENTITY_LOCK, DEFAULT_TEMPLATES, type DirectionFields, ERAS, ERA_CATEGORY_LABELS, ERA_CATEGORY_ORDER, ERA_IDS, EXPOSURE_CATEGORY_LABELS, EXPOSURE_CATEGORY_ORDER, EXPOSURE_FIELD_BY_CATEGORY, EXPOSURE_IDS, EXPOSURE_SETTINGS, type Era, type EraCategory, type ExposureCategory, type ExposureSettings, type ExposureValue, FACTORY_PRESETS, FACTORY_SNIPPETS, FILM_STILL_PREFIX, FRAMINGS, FRAMING_CATEGORY_LABELS, FRAMING_CATEGORY_ORDER, FRAMING_FIELD_BY_CATEGORY, FRAMING_IDS, type FacePromptInput, type FactoryPreset, type FactoryPresetGroup, type FactorySnippet, type Framing, type FramingCategory, type FramingValue, GAPS_SCHEMA, type GeminiOmniI2vInputsArgs, type GeminiOmniI2vInputsResult, HELD_PROPS, HELD_PROP_CATEGORY_LABELS, HELD_PROP_CATEGORY_ORDER, HELD_PROP_IDS, type HeldProp, type HeldPropCategory, IMAGE_WIZARD_CATEGORIES, INSTRUMENTATION_DEFAULT_DATA, INSTRUMENTS, INSTRUMENT_CATEGORY_LABELS, INSTRUMENT_CATEGORY_ORDER, type IdentityLockMode, type InstrumentCategory, type InstrumentationEntry, LENSES, LENS_IDS, LIGHTINGS, LIGHTING_CATEGORY_LABELS, LIGHTING_CATEGORY_ORDER, LIGHTING_FIELD_BY_CATEGORY, LIGHTING_IDS, LLM_CHAT_WIZARD_CATEGORIES, LOOP_SUBJECTS, LOOP_SUBJECT_CATEGORY_LABELS, LOOP_SUBJECT_CATEGORY_ORDER, type Lens, type Lighting, type LightingCategory, type LightingValue, type LlmChatFieldArgs, type LocationMotionPromptInput, type LocationPromptInput, type LocationRefinePromptInput, type LoopSubject, type LoopSubjectCategory, MATERIALS, MATERIAL_CATEGORY_LABELS, MATERIAL_CATEGORY_ORDER, MATERIAL_IDS, MAX_SELECTED_BY_DIMENSION, MAX_SELECTED_BY_FRAMING_CATEGORY, MAX_SELECTED_BY_STYLING_DIMENSION, MOODS, MOOD_CATEGORY_LABELS, MOOD_CATEGORY_ORDER, MOOD_IDS, MOVEMENT_LABELS, MULTI_PICKER_WIRING, MUSIC_EMOTIONS, MUSIC_ENERGIES, MUSIC_ERAS, MUSIC_GENRES, MUSIC_GENRE_CATEGORY_LABELS, MUSIC_GENRE_CATEGORY_ORDER, MUSIC_GENRE_DEFAULT_DATA, MUSIC_MOOD_DEFAULT_DATA, MUSIC_VIBES, MUSIC_WIZARD_CATEGORIES, type Material, type MaterialCategory, type ModelChange, type Mood, type MoodCategory, type MoodValue, type MultiDimPickerWiring, type MultiPickerAnalyzerSpec, type MusicEra, type MusicGenre, type MusicGenreCategory, type MusicMoodEntry, type MusicSubgenre, NODE_PROMPT_CANDIDATE_FIELDS, OBJECT_ANGLE_PRESETS, OBJECT_ANGLE_PROMPTS, OBJECT_ASSET_PRESETS, OBJECT_ASSET_PROMPTS, OBJECT_MATERIAL_PRESETS, OBJECT_MATERIAL_PROMPTS, OBJECT_VARIATION_PRESETS, OBJECT_VARIATION_PROMPTS, type ObjectMotionPromptInput, type ObjectPresetAssetType, type ObjectPromptInput, PEOPLE, PERSON_DIMENSION_LABELS, PERSON_DIMENSION_ORDER, PERSON_DIMENSION_SECTIONS, PERSON_FIELD_BY_DIMENSION, PERSON_IDS, PHOTOGRAPHERS, PHOTOGRAPHER_CATEGORY_LABELS, PHOTOGRAPHER_CATEGORY_ORDER, PHOTOGRAPHER_IDS, PHOTO_GENRES, PHOTO_GENRE_CATEGORY_LABELS, PHOTO_GENRE_CATEGORY_ORDER, PHOTO_GENRE_IDS, PICKER_ANALYZER_FAMILIES, PICKER_ANALYZER_REGISTRY, PICKER_CATALOGS, PICKER_TYPES, POSES, POSE_CATEGORY_LABELS, POSE_CATEGORY_ORDER, POSE_IDS, POST_PROCESS_EFFECTS, POST_PROCESS_EFFECT_IDS, PRODUCTION_STYLES, PROVIDER_CAPABILITIES, PROVIDER_PROMPT_DOCTRINES, type Person, type PersonDimension, type PersonDimensionSection, type PersonValue, type PhotoGenre, type PhotoGenreCategory, type Photographer, type PhotographerCategory, type PickerAnalyzer, type PickerAnalyzerDescriptor, type PickerAnalyzerSpec, type PickerApplyMode, type PickerCatalog, type PickerCatalogDetail, type PickerCatalogSummary, type PickerDimension, type PickerDimensionSpec, type PickerGaps, type PickerOption, type PickerType, type PickerWiring, type PickerWiringEntry, type Pose, type PoseCategory, type PoseValue, type PostProcessEffect, type ProjectPickerCatalogOptions, type ProjectedPickerCatalog, type ProjectedPickerDimension, type ProjectedPickerOption, type PromptSegment, type PromptSegmentOrigin, type ProviderPromptDoctrine, REFERENCE_IMAGE_ROLES, REFERENCE_RULES, REFERENCE_RULES_MULTI_PERSON, REF_BINDING, RENDER_QUALITIES, RENDER_QUALITY_IDS, type RecommendedModel, type ReferenceCounts, type RenderQuality, type ResolveCharacterMentionsResult, type ResolveLocationMentionsResult, type ResolvePromptArgs, type ResolveVideoReferenceCoreArgs, SCENE_FRAME_RULE, SCENE_PROMPT_MAX_LENGTH, SETTINGS, SETTING_CATEGORY_LABELS, SETTING_IDS, SHOT_LABELS, SINGING_STYLES, SINGLE_PICKER_WIRING, SNIPPET_MEDIA_VALUES, STYLES, STYLE_IDS, STYLE_PRESETS, STYLINGS, STYLING_DIMENSION_LABELS, STYLING_DIMENSION_ORDER, STYLING_FIELD_BY_DIMENSION, STYLING_IDS, type Seedance2InputsArgs, type Seedance2InputsResult, type Seedance2Mode, type Setting, type SettingCategory, type SingleDimPickerWiring, type SnippetMedia, type SnippetTarget, type SoundComposition, type SoundCompositionFields, type SoundConsumerType, type StructuredPromptFields, type Style, type StylePreset, type Styling, type StylingDimension, type StylingValue, TEMPORALS, TEMPORAL_CATEGORY_LABELS, TEMPORAL_CATEGORY_ORDER, TEMPORAL_FIELD_BY_CATEGORY, TEMPORAL_IDS, TEXT_WIZARD_CATEGORIES, TRANSITIONS, TRANSITION_CATEGORY_LABELS, TRANSITION_CATEGORY_ORDER, TRANSITION_IDS, type Temporal, type TemporalCategory, type TemporalValue, type Transition, type TransitionCategory, type TransitionDuration, type TransitionIntensity, type TransitionPosition, type TransitionTiming, VIDEO_WIZARD_CATEGORIES, VOCAL_PRESENCE, VOCAL_PRESENCE_INSTRUMENTAL_ID, VOICE_ACCENTS, VOICE_AGES, VOICE_ARCHETYPES, VOICE_CHARACTER_DEFAULT_DATA, VOICE_DELIVERY_DEFAULT_DATA, VOICE_EMOTIONS, VOICE_GENDERS, VOICE_LANGUAGES, VOICE_PACES, VOICE_TIMBRES, type VeoI2vInputsArgs, type VeoI2vInputsResult, type VideoExtraRef, type VoiceCharacterEntry, type VoiceDeliveryEntry, WARDROBE, WARDROBE_CATEGORY_LABELS, WARDROBE_DIMENSION_ORDER, WARDROBE_FIELD_BY_DIMENSION, type WardrobeDimension, type WardrobeEntry, type WardrobeValue, type WizardCategory, type WizardNodeContext, type WizardOption, type WizardQuestion, type WizardSelection, appendField, appendMusicMeta, applyPickerJson, applyReferenceOrderToVideo, applyTemplate, assembleImageInput, assembleSunoInput, buildActionFxHints, buildAestheticHints, buildAgeHint, buildAtmosphereHints, buildCharacterPrompt, buildCreaturePrompt, buildExposureHints, buildFaceTemplateInputs, buildFramingHints, buildHeldPropHints, buildIdentityDirectives, buildIdentityLockLine, buildImagePrompt, buildImagePromptSegments, buildInstrumentationHints, buildLightingHints, buildLocationMotionPrompt, buildLocationPrompt, buildLocationRefinePrompt, buildMaterialHints, buildMoodHints, buildMotionPrompt, buildMultiPickerAnalyzerSpec, buildMusicGenreHints, buildMusicMoodHints, buildObjectMotionPrompt, buildObjectPrompt, buildPersonHints, buildPhotographerHints, buildPickerAnalyzerSpec, buildPickerLegend, buildPickerZodSchema, buildPoseHints, buildPostProcessHints, buildReferenceBlocks, buildScenePrompt, buildStylingHints, buildSurroundFillPrompt, buildTemporalHints, buildVoiceCharacterHints, buildVoiceDeliveryHints, buildWardrobeHints, characterLockToRefLock, collectIdentityLockClause, composeCameraMotionHintFromConnections, composeCharacterFxHintFromConnections, composeNegative, composeSoundHintFromConnections, composeTransitionHintFromConnections, computeLlmChatFields, computeNodePrompt, expandImagePositionRefs, expandImageRefTokens, filmStillPrefix, getActionFx, getActionFxLabel, getActionFxPromptHint, getAesthetic, getAestheticLabel, getAestheticPromptHint, getAtmosphere, getAtmosphereLabel, getAtmospherePromptHint, getBackdrop, getBackdropLabel, getBackdropPromptHint, getCameraFormat, getCameraFormatLabel, getCameraFormatPromptHint, getCameraMotion, getCameraMotionLabel, getCameraMotionPromptHint, getCategoriesForNodeType, getCharacterFx, getCharacterFxLabel, getCharacterFxPromptHint, getColorLook, getColorLookLabel, getColorLookPromptHint, getCompositionEffect, getCompositionEffectLabel, getCompositionEffectPromptHint, getEffectiveSunoCustomMode, getEra, getEraLabel, getEraPromptHint, getExposure, getExposureLabel, getExposurePromptHint, getFactoryPresets, getFactorySnippets, getFraming, getFramingCategoryLimit, getFramingLabel, getFramingPromptHint, getHeldProp, getHeldPropLabel, getHeldPropPromptHint, getIdentityLockClause, getInstrument, getLens, getLensLabel, getLensPromptHint, getLighting, getLightingLabel, getLightingPromptHint, getLoopSubject, getLoopSubjectLabel, getLoopSubjectPromptHint, getMaterial, getMaterialLabel, getMaterialPromptHint, getMood, getMoodLabel, getMoodPromptHint, getMusicEmotion, getMusicEnergy, getMusicEra, getMusicGenre, getMusicGenreLabel, getMusicSubgenre, getMusicVibe, getParameterPromptHint, getPerson, getPersonDimensionLimit, getPersonLabel, getPersonPromptHint, getPhotoGenre, getPhotoGenreLabel, getPhotoGenrePromptHint, getPhotographer, getPhotographerLabel, getPhotographerPromptHint, getPickerAnalyzer, getPickerCatalog, getPickerWiring, getPose, getPoseLabel, getPosePromptHint, getPostProcessEffect, getPostProcessEffectLabel, getPostProcessEffectPromptHint, getProductionStyle, getPromptDoctrine, getPromptTips, getRenderQuality, getRenderQualityLabel, getRenderQualityPromptHint, getSetting, getSettingLabel, getSettingPromptHint, getSingingStyle, getStyle, getStyleLabel, getStylePreset, getStylePromptHint, getStyling, getStylingDimensionLimit, getStylingLabel, getStylingPromptHint, getTemporal, getTemporalLabel, getTemporalPromptHint, getTransition, getTransitionLabel, getTransitionPromptHint, getVocalPresence, getVoiceAccent, getVoiceAge, getVoiceArchetype, getVoiceEmotion, getVoiceGender, getVoiceLanguage, getVoicePace, getVoiceTimbre, getWardrobeEntriesByDimension, getWardrobeEntry, getWardrobePromptHint, groupFactoryPresets, hasUpstreamCharacter, identityRefsSentence, isAnalyzablePicker, isInstrumentalVocal, isVantageFraming, isWizardSupported, listPickerCatalogs, migratePersonValue, pickerFanoutTargets, projectPickerCatalog, promptBindsFirstFrame, referenceRulesBlock, renderStructuredFields, resolveBrandInput, resolveCharacterMentions, resolveGeminiOmniI2vInputs, resolveLocationMentions, resolvePrompt, resolveReferenceTokens, resolveSeedance2Inputs, resolveTemplate, resolveVeoI2vInputs, resolveVideoReferenceCore, summarizePickerCatalogs, toIdentityLockMode, truncateForField, truncateText, withForcedIdentityLock };
5449
+ export { ACTION_FX, ACTION_FX_CATEGORY_LABELS, ACTION_FX_CATEGORY_ORDER, ACTION_FX_IDS, AESTHETICS, AESTHETIC_CATEGORY_LABELS, AESTHETIC_CATEGORY_ORDER, AESTHETIC_IDS, ALL_PICKER_WIRING, ANALYZABLE_PICKER_TYPES, ANGLE_LABELS, ASPECT_RATIO_LABELS, ATMOSPHERES, ATMOSPHERE_IDS, AUDIO_WIZARD_CATEGORIES, type ActionFx, type ActionFxCategory, type Aesthetic, type AestheticCategory, type AssembleImageInput, type AssembleSunoInput, type AssembleSunoResult, type Atmosphere, BACKDROPS, BACKDROP_CATEGORY_LABELS, BACKDROP_CATEGORY_ORDER, BACKDROP_IDS, BRAND_PRESETS, BRAND_PRESET_IDS, BRAND_PRESET_META, type Backdrop, type BackdropCategory, type BrandCasing, type BrandFonts, type BrandLogo, type BrandPalette, type BrandPresetId, type BrandPresetMeta, type BrandTokens, type BrandTypeSpec, type BuildImagePromptConfig, type BuildImagePromptResult, type BuildImagePromptSegmentsResult, CAMERA_FORMATS, CAMERA_FORMAT_IDS, CAMERA_MOTIONS, CAMERA_MOTION_CATEGORY_LABELS, CAMERA_MOTION_CATEGORY_ORDER, CAMERA_MOTION_IDS, CHARACTER_FX, CHARACTER_FX_CATEGORY_LABELS, CHARACTER_FX_CATEGORY_ORDER, CHARACTER_FX_IDS, CINEMATIC_LOOK_TAIL, COLOR_LOOKS, COLOR_LOOK_CATEGORY_LABELS, COLOR_LOOK_CATEGORY_ORDER, COLOR_LOOK_IDS, COMPOSITION_EFFECTS, COMPOSITION_EFFECT_IDS, type CameraFormat, type CameraMotion, type CameraMotionCategory, type CatalogPack, type CatalogPackMode, type CategorizedInstrument, type CharacterFx, type CharacterFxCategory, type CharacterFxDuration, type CharacterFxIntensity, type CharacterFxPosition, type CharacterFxTiming, type CharacterMeta, type CharacterMotionPromptInput, type CharacterPromptInput, type ColorLook, type ColorLookCategory, type CompositionEffect, type ComputeNodePromptArgs, type CreaturePromptInput, DEFAULT_IDENTITY_LOCK, DEFAULT_TEMPLATES, type DirectionFields, ERAS, ERA_CATEGORY_LABELS, ERA_CATEGORY_ORDER, ERA_IDS, EXPOSURE_CATEGORY_LABELS, EXPOSURE_CATEGORY_ORDER, EXPOSURE_FIELD_BY_CATEGORY, EXPOSURE_IDS, EXPOSURE_SETTINGS, type Era, type EraCategory, type ExposureCategory, type ExposureSettings, type ExposureValue, FACTORY_PRESETS, FACTORY_SNIPPETS, FILM_STILL_PREFIX, FRAMINGS, FRAMING_CATEGORY_LABELS, FRAMING_CATEGORY_ORDER, FRAMING_FIELD_BY_CATEGORY, FRAMING_IDS, type FacePromptInput, type FactoryPreset, type FactoryPresetGroup, type FactorySnippet, type Framing, type FramingCategory, type FramingValue, GAPS_SCHEMA, type GeminiOmniI2vInputsArgs, type GeminiOmniI2vInputsResult, HELD_PROPS, HELD_PROP_CATEGORY_LABELS, HELD_PROP_CATEGORY_ORDER, HELD_PROP_IDS, type HeldProp, type HeldPropCategory, IMAGE_REFERENCE_PROMPT_DOCTRINE, IMAGE_WIZARD_CATEGORIES, INSTRUMENTATION_DEFAULT_DATA, INSTRUMENTS, INSTRUMENT_CATEGORY_LABELS, INSTRUMENT_CATEGORY_ORDER, type IdentityLockMode, type ImageReferenceDoctrine, type InstrumentCategory, type InstrumentationEntry, LENSES, LENS_IDS, LIGHTINGS, LIGHTING_CATEGORY_LABELS, LIGHTING_CATEGORY_ORDER, LIGHTING_FIELD_BY_CATEGORY, LIGHTING_IDS, LLM_CHAT_WIZARD_CATEGORIES, LOOP_SUBJECTS, LOOP_SUBJECT_CATEGORY_LABELS, LOOP_SUBJECT_CATEGORY_ORDER, type Lens, type Lighting, type LightingCategory, type LightingValue, type LlmChatFieldArgs, type LocationMotionPromptInput, type LocationPromptInput, type LocationRefinePromptInput, type LoopSubject, type LoopSubjectCategory, MATERIALS, MATERIAL_CATEGORY_LABELS, MATERIAL_CATEGORY_ORDER, MATERIAL_IDS, MAX_SELECTED_BY_DIMENSION, MAX_SELECTED_BY_FRAMING_CATEGORY, MAX_SELECTED_BY_STYLING_DIMENSION, MOODS, MOOD_CATEGORY_LABELS, MOOD_CATEGORY_ORDER, MOOD_IDS, MOVEMENT_LABELS, MULTI_PICKER_WIRING, MUSIC_EMOTIONS, MUSIC_ENERGIES, MUSIC_ERAS, MUSIC_GENRES, MUSIC_GENRE_CATEGORY_LABELS, MUSIC_GENRE_CATEGORY_ORDER, MUSIC_GENRE_DEFAULT_DATA, MUSIC_MOOD_DEFAULT_DATA, MUSIC_VIBES, MUSIC_WIZARD_CATEGORIES, type Material, type MaterialCategory, type ModelChange, type Mood, type MoodCategory, type MoodValue, type MultiDimPickerWiring, type MultiPickerAnalyzerSpec, type MusicEra, type MusicGenre, type MusicGenreCategory, type MusicMoodData, type MusicMoodEntry, type MusicSubgenre, NODE_PROMPT_CANDIDATE_FIELDS, OBJECT_ANGLE_PRESETS, OBJECT_ANGLE_PROMPTS, OBJECT_ASSET_PRESETS, OBJECT_ASSET_PROMPTS, OBJECT_MATERIAL_PRESETS, OBJECT_MATERIAL_PROMPTS, OBJECT_VARIATION_PRESETS, OBJECT_VARIATION_PROMPTS, type ObjectMotionPromptInput, type ObjectPresetAssetType, type ObjectPromptInput, PEOPLE, PERSON_DIMENSION_LABELS, PERSON_DIMENSION_ORDER, PERSON_DIMENSION_SECTIONS, PERSON_FIELD_BY_DIMENSION, PERSON_IDS, PHOTOGRAPHERS, PHOTOGRAPHER_CATEGORY_LABELS, PHOTOGRAPHER_CATEGORY_ORDER, PHOTOGRAPHER_IDS, PHOTO_GENRES, PHOTO_GENRE_CATEGORY_LABELS, PHOTO_GENRE_CATEGORY_ORDER, PHOTO_GENRE_IDS, PICKER_ANALYZER_FAMILIES, PICKER_ANALYZER_REGISTRY, PICKER_CATALOGS, PICKER_TYPES, POSES, POSE_CATEGORY_LABELS, POSE_CATEGORY_ORDER, POSE_IDS, POST_PROCESS_EFFECTS, POST_PROCESS_EFFECT_IDS, PRODUCTION_STYLES, PROVIDER_CAPABILITIES, PROVIDER_PROMPT_DOCTRINES, type Person, type PersonDimension, type PersonDimensionSection, type PersonPack, type PersonValue, type PhotoGenre, type PhotoGenreCategory, type Photographer, type PhotographerCategory, type PickerAnalyzer, type PickerAnalyzerDescriptor, type PickerAnalyzerSpec, type PickerApplyMode, type PickerCatalog, type PickerCatalogDetail, type PickerCatalogInput, type PickerCatalogSummary, type PickerDimension, type PickerDimensionInput, type PickerDimensionSpec, type PickerGaps, type PickerHintMode, type PickerOption, type PickerOptionInput, type PickerType, type PickerWiring, type PickerWiringEntry, type Pose, type PoseCategory, type PoseValue, type PostProcessEffect, type ProjectPickerCatalogOptions, type ProjectedPickerCatalog, type ProjectedPickerDimension, type ProjectedPickerOption, type PromptSegment, type PromptSegmentOrigin, type ProviderPromptDoctrine, REFERENCE_IMAGE_ROLES, REFERENCE_RULES, REFERENCE_RULES_MULTI_PERSON, REF_BINDING, RENDER_QUALITIES, RENDER_QUALITY_IDS, type RecommendedModel, type ReferenceCounts, type RegisteredPersonEntry, type RenderQuality, type ResolveCharacterMentionsResult, type ResolveLocationMentionsResult, type ResolvePromptArgs, type ResolveVideoReferenceCoreArgs, SCENE_FRAME_RULE, SCENE_PROMPT_MAX_LENGTH, SETTINGS, SETTING_CATEGORY_LABELS, SETTING_IDS, SHOT_LABELS, SINGING_STYLES, SINGLE_PICKER_WIRING, SNIPPET_MEDIA_VALUES, STYLES, STYLE_IDS, STYLE_PRESETS, STYLINGS, STYLING_DIMENSION_LABELS, STYLING_DIMENSION_ORDER, STYLING_FIELD_BY_DIMENSION, STYLING_IDS, type Seedance2InputsArgs, type Seedance2InputsResult, type Seedance2Mode, type Setting, type SettingCategory, type SidecarCoverageReport, type SingleDimPickerWiring, type SnippetMedia, type SnippetTarget, type SoundComposition, type SoundCompositionFields, type SoundConsumerType, type StructuredPromptFields, type Style, type StylePreset, type Styling, type StylingDimension, type StylingValue, type SuspiciousTermOptions, TEMPORALS, TEMPORAL_CATEGORY_LABELS, TEMPORAL_CATEGORY_ORDER, TEMPORAL_FIELD_BY_CATEGORY, TEMPORAL_IDS, TERM_MAX_CHARS, TEXT_WIZARD_CATEGORIES, TRANSITIONS, TRANSITION_CATEGORY_LABELS, TRANSITION_CATEGORY_ORDER, TRANSITION_IDS, type Temporal, type TemporalCategory, type TemporalValue, type TermCarrier, type Transition, type TransitionCategory, type TransitionDuration, type TransitionIntensity, type TransitionPosition, type TransitionTiming, VIDEO_WIZARD_CATEGORIES, VOCAL_PRESENCE, VOCAL_PRESENCE_INSTRUMENTAL_ID, VOICE_ACCENTS, VOICE_AGES, VOICE_ARCHETYPES, VOICE_CHARACTER_DEFAULT_DATA, VOICE_DELIVERY_DEFAULT_DATA, VOICE_EMOTIONS, VOICE_GENDERS, VOICE_LANGUAGES, VOICE_PACES, VOICE_TIMBRES, type VeoI2vInputsArgs, type VeoI2vInputsResult, type VideoExtraRef, type VoiceCharacterEntry, type VoiceDeliveryEntry, WARDROBE, WARDROBE_CATEGORY_LABELS, WARDROBE_DIMENSION_ORDER, WARDROBE_FIELD_BY_DIMENSION, type WardrobeDimension, type WardrobeEntry, type WardrobeValue, type WizardCategory, type WizardNodeContext, type WizardOption, type WizardQuestion, type WizardSelection, appendField, appendMusicMeta, applyPickerJson, applyReferenceOrderToVideo, applyTemplate, assembleImageInput, assembleSunoInput, buildActionFxHints, buildActionFxTerms, buildAestheticHints, buildAestheticTerms, buildAgeHint, buildAtmosphereHints, buildAtmosphereTerms, buildCharacterPrompt, buildCreaturePrompt, buildExposureHints, buildExposureTerms, buildFaceTemplateInputs, buildFramingHints, buildFramingTerms, buildHeldPropHints, buildHeldPropTerms, buildIdentityDirectives, buildIdentityLockLine, buildImagePrompt, buildImagePromptSegments, buildInstrumentationHints, buildInstrumentationTerms, buildLightingHints, buildLightingTerms, buildLocationMotionPrompt, buildLocationPrompt, buildLocationRefinePrompt, buildMaterialHints, buildMaterialTerms, buildMoodHints, buildMoodTerms, buildMotionPrompt, buildMultiPickerAnalyzerSpec, buildMusicGenreHints, buildMusicGenreTerms, buildMusicMoodHints, buildMusicMoodTerms, buildObjectMotionPrompt, buildObjectPrompt, buildPersonHints, buildPersonTerms, buildPhotographerHints, buildPhotographerTerms, buildPickerAnalyzerSpec, buildPickerLegend, buildPickerZodSchema, buildPoseHints, buildPoseTerms, buildPostProcessHints, buildPostProcessTerms, buildReferenceBlocks, buildScenePrompt, buildStylingHints, buildStylingTerms, buildSurroundFillPrompt, buildTemporalHints, buildTemporalTerms, buildVoiceCharacterHints, buildVoiceCharacterTerms, buildVoiceDeliveryHints, buildVoiceDeliveryTerms, buildWardrobeHints, catalogPacksVersion, characterLockToRefLock, collectIdentityLockClause, composeCameraMotionHintFromConnections, composeCameraMotionTermFromConnections, composeCharacterFxHintFromConnections, composeNegative, composePickerCatalogs, composeSoundHintFromConnections, composeTransitionHintFromConnections, computeLlmChatFields, computeNodePrompt, computePackSidecarCoverage, deriveTerm, expandImagePositionRefs, expandImageRefTokens, filmStillPrefix, getActionFx, getActionFxLabel, getActionFxPromptHint, getActionFxTerm, getAesthetic, getAestheticLabel, getAestheticPromptHint, getAestheticTerm, getAtmosphere, getAtmosphereLabel, getAtmospherePromptHint, getAtmosphereTerm, getBackdrop, getBackdropLabel, getBackdropPromptHint, getBackdropTerm, getCameraFormat, getCameraFormatLabel, getCameraFormatPromptHint, getCameraFormatTerm, getCameraMotion, getCameraMotionLabel, getCameraMotionPromptHint, getCameraMotionTerm, getCategoriesForNodeType, getCharacterFx, getCharacterFxLabel, getCharacterFxPromptHint, getCharacterFxTerm, getColorLook, getColorLookLabel, getColorLookPromptHint, getColorLookTerm, getCompositionEffect, getCompositionEffectLabel, getCompositionEffectPromptHint, getCompositionEffectTerm, getEffectiveSunoCustomMode, getEra, getEraLabel, getEraPromptHint, getEraTerm, getExposure, getExposureLabel, getExposurePromptHint, getExposureTerm, getFactoryPresets, getFactorySnippets, getFraming, getFramingCategoryLimit, getFramingLabel, getFramingPromptHint, getFramingTerm, getHeldProp, getHeldPropLabel, getHeldPropPromptHint, getHeldPropTerm, getIdentityLockClause, getInstrument, getInstrumentTerm, getLens, getLensLabel, getLensPromptHint, getLensTerm, getLighting, getLightingLabel, getLightingPromptHint, getLightingTerm, getLoopSubject, getLoopSubjectLabel, getLoopSubjectPromptHint, getLoopSubjectTerm, getMaterial, getMaterialLabel, getMaterialPromptHint, getMaterialTerm, getMood, getMoodLabel, getMoodPromptHint, getMoodTerm, getMusicEmotion, getMusicEmotionTerm, getMusicEnergy, getMusicEnergyTerm, getMusicEra, getMusicEraTerm, getMusicGenre, getMusicGenreLabel, getMusicGenreTerm, getMusicSubgenre, getMusicSubgenreTerm, getMusicVibe, getMusicVibeTerm, getParameterPromptHint, getPerson, getPersonDimensionLimit, getPersonLabel, getPersonPromptHint, getPersonTerm, getPhotoGenre, getPhotoGenreLabel, getPhotoGenrePromptHint, getPhotoGenreTerm, getPhotographer, getPhotographerLabel, getPhotographerPromptHint, getPhotographerTerm, getPickerAnalyzer, getPickerCatalog, getPickerWiring, getPose, getPoseLabel, getPosePromptHint, getPoseTerm, getPostProcessEffect, getPostProcessEffectLabel, getPostProcessEffectPromptHint, getPostProcessEffectTerm, getProductionStyle, getProductionStyleTerm, getPromptDoctrine, getPromptTips, getRegisteredCatalogPacks, getRegisteredPeople, getRegisteredPersonDimensionLabels, getRegisteredPersonDimensionOrder, getRegisteredPersonFieldByDimension, getRegisteredPickerCatalogs, getRenderQuality, getRenderQualityLabel, getRenderQualityPromptHint, getRenderQualityTerm, getSetting, getSettingLabel, getSettingPromptHint, getSettingTerm, getSingingStyle, getSingingStyleTerm, getStyle, getStyleLabel, getStylePreset, getStylePromptHint, getStyleTerm, getStyling, getStylingDimensionLimit, getStylingLabel, getStylingPromptHint, getStylingTerm, getTemporal, getTemporalLabel, getTemporalPromptHint, getTemporalTerm, getTransition, getTransitionLabel, getTransitionPromptHint, getTransitionTerm, getVocalPresence, getVocalPresenceTerm, getVoiceAccent, getVoiceAccentTerm, getVoiceAge, getVoiceAgeTerm, getVoiceArchetype, getVoiceArchetypeTerm, getVoiceEmotion, getVoiceEmotionTerm, getVoiceGender, getVoiceGenderTerm, getVoiceLanguage, getVoiceLanguageTerm, getVoicePace, getVoicePaceTerm, getVoiceTimbre, getVoiceTimbreTerm, getWardrobeEntriesByDimension, getWardrobeEntry, getWardrobePromptHint, groupFactoryPresets, hasUpstreamCharacter, identityRefsSentence, isAnalyzablePicker, isInstrumentalVocal, isSuspiciousDerivedTerm, isVantageFraming, isWizardSupported, listPickerCatalogs, migratePersonValue, personPacksVersion, pickerFanoutTargets, projectAllCatalogs, projectPickerCatalog, promptBindsFirstFrame, referenceRulesBlock, registerCatalogPack, registerPersonPack, renderStructuredFields, resetCatalogPacks, resetPersonPacks, resolveBrandInput, resolveCharacterMentions, resolveGeminiOmniI2vInputs, resolveLocationMentions, resolvePrompt, resolveReferenceTokens, resolveSeedance2Inputs, resolveTemplate, resolveTerm, resolveVeoI2vInputs, resolveVideoReferenceCore, summarizePickerCatalogs, toIdentityLockMode, truncateForField, truncateText, withForcedIdentityLock };