@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
@@ -23,11 +23,24 @@
23
23
  * and the backend orchestrator.
24
24
  */
25
25
 
26
+ import { resolveTerm } from "./term.js"
27
+
26
28
  export interface RenderQuality {
27
29
  readonly id: string
28
30
  readonly label: string
29
31
  readonly description: string
30
32
  readonly promptHint: string
33
+ /**
34
+ * Compact professional term (see `term.ts`). Authored only where the
35
+ * lowercased label is NOT what a professional writes in a prompt — a bare
36
+ * word that collides with ordinary English ("redshift", "aces"), an
37
+ * abbreviation ("pbr"), a non-standard coinage ("16k megapixel"), a bare
38
+ * modifier with no category noun ("denoised"), or a compound whose
39
+ * canonical prompt spelling is hyphenated. Every other label here is
40
+ * already the proper name of the thing ("octane render", "masterpiece")
41
+ * and carries no `term`.
42
+ */
43
+ readonly term?: string
31
44
  }
32
45
 
33
46
  export const RENDER_QUALITIES: ReadonlyArray<RenderQuality> = [
@@ -35,35 +48,35 @@ export const RENDER_QUALITIES: ReadonlyArray<RenderQuality> = [
35
48
  { id: "unreal-engine-5", label: "Unreal Engine 5", description: "Real-time path-traced UE5 look", promptHint: "rendered in Unreal Engine 5, real-time path-traced lighting with Lumen reflections, Nanite-grade micro-detail and cinematic post-processing" },
36
49
  { id: "blender-cycles", label: "Blender Cycles", description: "Cycles unbiased path tracing", promptHint: "rendered in Blender Cycles, unbiased path-traced lighting with physically accurate shadows, soft global illumination and clean denoise" },
37
50
  { id: "octane-render", label: "Octane Render", description: "GPU spectral path tracing", promptHint: "rendered in Octane, GPU spectral path tracing with hyper-realistic materials, vivid color response and crisp specular highlights" },
38
- { id: "redshift", label: "Redshift", description: "Production GPU biased renderer", promptHint: "rendered in Redshift, production-quality GPU rendering with rich material response, controlled GI and film-grade depth" },
51
+ { id: "redshift", label: "Redshift", description: "Production GPU biased renderer", promptHint: "rendered in Redshift, production-quality GPU rendering with rich material response, controlled GI and film-grade depth", term: "redshift render" },
39
52
  { id: "houdini-mantra", label: "Houdini Mantra", description: "VFX-grade physical rendering", promptHint: "rendered in Houdini Mantra, VFX-grade physically-based rendering with subtle volumetric scatter and ultra-clean shading" },
40
53
  { id: "arnold-render", label: "Arnold Render", description: "Industry-standard VFX path tracer", promptHint: "rendered in Solid Angle Arnold, industry-standard VFX path-traced lighting with physically accurate light transport, smooth noise-free shading, and the flagship Pixar / ILM / Sony feature-film polish" },
41
54
  { id: "corona-renderer", label: "Corona Renderer", description: "Photorealistic archviz unbiased renderer", promptHint: "rendered in Chaos Corona, unbiased photorealistic rendering with crisp daylight global illumination, refined material response and the signature architectural-visualization clarity" },
42
55
  { id: "vray", label: "V-Ray", description: "Industry-standard product / archviz / VFX renderer", promptHint: "rendered in Chaos V-Ray, industry-standard hybrid path-traced production rendering with razor-sharp detail, accurate reflections and the polished product-viz / archviz / VFX finish" },
43
- { id: "aces", label: "ACES", description: "Cinema-grade ACES color management", promptHint: "graded through the ACES (Academy Color Encoding System) color management workflow, modern cinema-grade tonal response with consistent wide-gamut color rendering, filmic highlight rolloff and reference-quality color fidelity" },
56
+ { id: "aces", label: "ACES", description: "Cinema-grade ACES color management", promptHint: "graded through the ACES (Academy Color Encoding System) color management workflow, modern cinema-grade tonal response with consistent wide-gamut color rendering, filmic highlight rolloff and reference-quality color fidelity", term: "aces color space" },
44
57
 
45
58
  // ---------------------------- Render-quality keywords ----------------------------
46
59
  { id: "raytracing", label: "Ray Tracing", description: "Accurate reflections + shadows", promptHint: "ray-traced rendering, physically accurate reflections, refractions and contact shadows with realistic light bounce" },
47
- { id: "physically-based-rendering", label: "PBR", description: "Physically-based materials", promptHint: "physically-based rendering with energy-conserving materials, accurate metallic/roughness response and realistic Fresnel falloff" },
60
+ { id: "physically-based-rendering", label: "PBR", description: "Physically-based materials", promptHint: "physically-based rendering with energy-conserving materials, accurate metallic/roughness response and realistic Fresnel falloff", term: "physically-based rendering" },
48
61
  { id: "global-illumination", label: "Global Illumination", description: "Realistic light bounce", promptHint: "global illumination, realistic indirect light bounce with soft color bleeding between surfaces and naturally lit shadow regions" },
49
62
  { id: "lumen-reflections", label: "Lumen Reflections", description: "Real-time dynamic GI", promptHint: "Lumen-style real-time dynamic global illumination with crisp screen-space reflections, soft contact shadows and beautifully lit indirect bounces" },
50
63
 
51
64
  // ---------------------------- Resolution / Detail ----------------------------
52
65
  { id: "8k-uhd", label: "8K UHD", description: "Ultra-sharp 8K resolution", promptHint: "8K ultra-high-definition resolution, ultra-sharp detail with every micro-texture preserved and zero softness" },
53
66
  { id: "4k-uhd", label: "4K UHD", description: "Crisp 4K resolution", promptHint: "4K UHD resolution, crisp detail with cinema-grade clarity and clean edge definition" },
54
- { id: "16k-megapixel", label: "16K Megapixel", description: "Insanely high-resolution detail", promptHint: "16K megapixel-grade resolution, insanely high-resolution detail with surgically clean edges and microscopic surface fidelity" },
55
- { id: "ultra-detailed", label: "Ultra Detailed", description: "Maximum micro-detail rendering", promptHint: "ultra-detailed rendering with intricate micro-surface detail, fine pore-level fidelity and meticulously preserved fine structures" },
67
+ { id: "16k-megapixel", label: "16K Megapixel", description: "Insanely high-resolution detail", promptHint: "16K megapixel-grade resolution, insanely high-resolution detail with surgically clean edges and microscopic surface fidelity", term: "16k resolution" },
68
+ { id: "ultra-detailed", label: "Ultra Detailed", description: "Maximum micro-detail rendering", promptHint: "ultra-detailed rendering with intricate micro-surface detail, fine pore-level fidelity and meticulously preserved fine structures", term: "ultra-detailed" },
56
69
 
57
70
  // ---------------------------- Style stamps ----------------------------
58
71
  { id: "raw-photo", label: "Raw Photo", description: "Unprocessed photographic feel", promptHint: "raw photograph aesthetic, unprocessed natural color science, authentic photographic detail and untouched documentary realism" },
59
72
  { id: "masterpiece", label: "Masterpiece", description: "Hand-of-an-expert quality stamp", promptHint: "masterpiece-quality rendering, hand-of-an-expert level execution with refined composition, immaculate detail and curated finish" },
60
- { id: "award-winning", label: "Award Winning", description: "Award-circuit caliber", promptHint: "award-winning quality, award-circuit caliber image with editorial-grade composition, magazine-cover finish and signature visual authority" },
73
+ { id: "award-winning", label: "Award Winning", description: "Award-circuit caliber", promptHint: "award-winning quality, award-circuit caliber image with editorial-grade composition, magazine-cover finish and signature visual authority", term: "award-winning" },
61
74
 
62
75
  // ---------------------------- Lighting / Image-quality passes ----------------------------
63
76
  { id: "volumetric-lighting", label: "Volumetric Lighting", description: "God-ray volumetric light shafts cutting through atmosphere", promptHint: "volumetric lighting with god-ray light shafts cutting through atmospheric haze, beams of illuminated dust and particulate scattering through the scene" },
64
77
  { id: "photon-mapping", label: "Photon Mapping", description: "Caustic-aware photon-mapped global illumination renderer", promptHint: "photon-mapped global illumination with caustic-aware light transport, accurate refractive light patterns through glass and water and physically correct indirect bounces" },
65
78
  { id: "ai-upscaled", label: "AI Upscaled", description: "Neural-network upscaled detail enhancement, sharp super-resolution", promptHint: "neural-network AI-upscaled detail enhancement, sharp super-resolution clarity with reconstructed micro-detail and surgically clean edge definition" },
66
- { id: "denoised", label: "Denoised", description: "Clean noise-removed pristine rendering, no grain or speckle", promptHint: "clean denoised rendering with noise removed entirely, pristine smooth surfaces and zero grain or speckle across shadows and midtones" },
79
+ { id: "denoised", label: "Denoised", description: "Clean noise-removed pristine rendering, no grain or speckle", promptHint: "clean denoised rendering with noise removed entirely, pristine smooth surfaces and zero grain or speckle across shadows and midtones", term: "denoised render" },
67
80
  ] as const
68
81
 
69
82
  const renderQualityById = new Map<string, RenderQuality>(
@@ -86,4 +99,9 @@ export function getRenderQualityPromptHint(id: string | undefined | null): strin
86
99
  return getRenderQuality(id)?.promptHint ?? ""
87
100
  }
88
101
 
102
+ /** Compact-mode sibling of `getRenderQualityPromptHint` — same lookup, short form. */
103
+ export function getRenderQualityTerm(id: string | undefined | null): string {
104
+ return resolveTerm(getRenderQuality(id))
105
+ }
106
+
89
107
  export const RENDER_QUALITY_IDS: ReadonlyArray<string> = RENDER_QUALITIES.map((r) => r.id)
package/src/setting.ts CHANGED
@@ -19,6 +19,8 @@
19
19
  * backend orchestrator.
20
20
  */
21
21
 
22
+ import { resolveTerm } from "./term.js"
23
+
22
24
  export type SettingCategory = "indoor" | "urban" | "nature" | "fantastical"
23
25
 
24
26
  export interface Setting {
@@ -27,6 +29,15 @@ export interface Setting {
27
29
  readonly category: SettingCategory
28
30
  readonly description: string
29
31
  readonly promptHint: string
32
+ /**
33
+ * Compact professional term (see `term.ts`). Authored only where the
34
+ * lowercased label is not what a location scout / cinematographer would
35
+ * write in a prompt — a building name standing in for the specific space
36
+ * inside it ("Hospital" → "hospital corridor"), or a label that reads
37
+ * ambiguously on its own ("Conservatory" → the greenhouse, not the music
38
+ * school). Everywhere else the lowercased label IS the term.
39
+ */
40
+ readonly term?: string
30
41
  }
31
42
 
32
43
  export const SETTINGS: ReadonlyArray<Setting> = [
@@ -37,39 +48,39 @@ export const SETTINGS: ReadonlyArray<Setting> = [
37
48
  { id: "home-office", label: "Home Office", category: "indoor", description: "Cozy home workspace", promptHint: "set in a cozy home office with a wooden desk, laptop and monitor, warm task lamp, bookshelves, houseplants and soft daylight through a nearby window" },
38
49
  { id: "bedroom", label: "Bedroom", category: "indoor", description: "Intimate bedroom", promptHint: "set in an intimate bedroom with soft diffused window light, rumpled linen bedding and warm wood floors" },
39
50
  { id: "living-room", label: "Living Room", category: "indoor", description: "Cozy residential living room", promptHint: "set in a cozy residential living room with a plush sofa, wooden coffee table, soft lamplight, bookshelves and a warm family-home atmosphere" },
40
- { id: "kitchen", label: "Kitchen", category: "indoor", description: "Warm home kitchen with morning light", promptHint: "set in a warm home kitchen with morning light, wood cabinets, a marble island with fresh produce and steam rising from a stovetop" },
51
+ { id: "kitchen", label: "Kitchen", category: "indoor", description: "Warm home kitchen with morning light", term: "home kitchen", promptHint: "set in a warm home kitchen with morning light, wood cabinets, a marble island with fresh produce and steam rising from a stovetop" },
41
52
  { id: "hotel-room", label: "Hotel Room", category: "indoor", description: "Elegant hotel room with city view", promptHint: "set in an elegant hotel room with a neatly made king bed, heavy drapes, a panoramic city view through the window, minimalist desk and soft warm lamplight" },
42
53
  { id: "restaurant", label: "Restaurant", category: "indoor", description: "Intimate candlelit restaurant", promptHint: "set in an intimate restaurant interior with candlelit tables, white linen, leather booths, wine glasses catching warm light and a softly bustling dining room" },
43
54
  { id: "nightclub", label: "Nightclub", category: "indoor", description: "Dark club with lasers and smoke", promptHint: "set in a dark nightclub interior with a packed dance floor, laser and strobe lighting, thumping bass energy, silhouetted bodies and hazy atmospheric smoke" },
44
55
  { id: "gym", label: "Gym", category: "indoor", description: "Modern fitness gym", promptHint: "set in a modern fitness gym with rubber flooring, racks of weights, mirrored walls and bright overhead lights on training equipment" },
45
56
  { id: "classroom", label: "Classroom", category: "indoor", description: "Bright school classroom", promptHint: "set in a bright school classroom with rows of wooden desks, a whiteboard covered in notes, posters on the walls and afternoon sun through tall windows" },
46
- { id: "hospital", label: "Hospital", category: "indoor", description: "Sterile hospital corridor", promptHint: "set in a sterile hospital corridor with polished linoleum floors, fluorescent ceiling lights, stainless-steel gurneys and softly beeping medical equipment" },
57
+ { id: "hospital", label: "Hospital", category: "indoor", description: "Sterile hospital corridor", term: "hospital corridor", promptHint: "set in a sterile hospital corridor with polished linoleum floors, fluorescent ceiling lights, stainless-steel gurneys and softly beeping medical equipment" },
47
58
  { id: "laboratory", label: "Laboratory", category: "indoor", description: "Research lab with glowing equipment", promptHint: "set in a modern research laboratory with stainless-steel benches, glowing microscopes, racks of beakers and test tubes, overhead task lights and faint blue ambient glow from monitors" },
48
59
  { id: "courtroom", label: "Courtroom", category: "indoor", description: "Wood-paneled courtroom", promptHint: "set in a formal wood-paneled courtroom with rows of oak benches, a raised judge's bench, a lectern, flags on either side and amber light streaming through tall windows" },
49
60
  { id: "warehouse", label: "Industrial Warehouse", category: "indoor", description: "Cavernous warehouse with skylights", promptHint: "set in a cavernous industrial warehouse with steel rafters, concrete floors and dust motes in shafts of light from skylights above" },
50
- { id: "subway-car", label: "Subway Car", category: "indoor", description: "Moving subway interior", promptHint: "set inside a moving subway car with fluorescent strip lights, graffiti-scarred windows and empty blue plastic seats" },
61
+ { id: "subway-car", label: "Subway Car", category: "indoor", description: "Moving subway interior", term: "subway car interior", promptHint: "set inside a moving subway car with fluorescent strip lights, graffiti-scarred windows and empty blue plastic seats" },
51
62
  { id: "taxi", label: "Taxi Interior", category: "indoor", description: "Back seat of a city taxi at night", promptHint: "set inside the back seat of a city taxi at night with rain-streaked windows, neon reflections sliding across the dashboard, the driver silhouetted against the windshield and the dim green glow of the fare meter" },
52
- { id: "cathedral", label: "Cathedral", category: "indoor", description: "Gothic cathedral interior", promptHint: "set in a vast gothic cathedral interior with vaulted stone ceilings, stained-glass kaleidoscopes and candlelit side chapels" },
63
+ { id: "cathedral", label: "Cathedral", category: "indoor", description: "Gothic cathedral interior", term: "gothic cathedral interior", promptHint: "set in a vast gothic cathedral interior with vaulted stone ceilings, stained-glass kaleidoscopes and candlelit side chapels" },
53
64
  { id: "art-gallery", label: "Art Gallery", category: "indoor", description: "Minimalist white-cube gallery", promptHint: "set in a minimalist white-cube art gallery with polished concrete floor, precision track lighting and framed canvases on bare walls" },
54
- { id: "balcony", label: "Balcony", category: "indoor", description: "Apartment balcony with urban view", promptHint: "set on an apartment balcony with potted plants along the railing, a sweeping urban view beyond, soft daylight and a candid intimate atmosphere of a private outdoor pocket above the city" },
65
+ { id: "balcony", label: "Balcony", category: "indoor", description: "Apartment balcony with urban view", term: "apartment balcony", promptHint: "set on an apartment balcony with potted plants along the railing, a sweeping urban view beyond, soft daylight and a candid intimate atmosphere of a private outdoor pocket above the city" },
55
66
  { id: "attic", label: "Attic", category: "indoor", description: "Wooden-beam dusty attic", promptHint: "set in a wooden-beam dusty attic with a slanted roof, exposed rafters, found objects in cardboard boxes, draped sheets over old furniture and a single shaft of light through a small dormer window" },
56
67
  { id: "basement", label: "Basement", category: "indoor", description: "Concrete basement with exposed pipes", promptHint: "set in a concrete basement with exposed overhead pipes, a bare hanging bulb, dim industrial vibe, water stains on the walls and stacked storage crates in the shadows" },
57
68
  { id: "sauna", label: "Sauna", category: "indoor", description: "Wood-paneled sauna with rising steam", promptHint: "set in a wood-paneled sauna with rising steam clouds, intimate warm sweaty space lit by amber bulbs, condensation on glass and cedar slat benches glistening with moisture" },
58
69
  { id: "dorm-room", label: "Dorm Room", category: "indoor", description: "Cluttered college dorm with fairy lights", promptHint: "set in a cluttered college dorm room with a twin bed, posters taped to the walls, fairy lights strung along the ceiling, a cramped desk piled with books and an intimate lived-in glow" },
59
70
  { id: "locker-room", label: "Locker Room", category: "indoor", description: "Tiled gym locker room with benches", promptHint: "set in a tiled gym locker room with rows of metal lockers, wooden benches down the center, mirrors above the sinks, post-workout steam in the air and the harsh hum of overhead fluorescents" },
60
- { id: "music-studio", label: "Music Studio", category: "indoor", description: "Recording studio with mics and foam", promptHint: "set in a recording music studio with a vocal microphone on a boom arm, soundproof foam panels on the walls, a large mixing control board, monitor speakers and warm low task lighting" },
61
- { id: "conservatory", label: "Conservatory", category: "indoor", description: "Glass greenhouse with tropical plants", promptHint: "set inside a glass-walled conservatory greenhouse with tropical plants, hanging ferns, terracotta pots, filtered sunlight pouring through the panes and a humid earthy atmosphere" },
71
+ { id: "music-studio", label: "Music Studio", category: "indoor", description: "Recording studio with mics and foam", term: "recording studio", promptHint: "set in a recording music studio with a vocal microphone on a boom arm, soundproof foam panels on the walls, a large mixing control board, monitor speakers and warm low task lighting" },
72
+ { id: "conservatory", label: "Conservatory", category: "indoor", description: "Glass greenhouse with tropical plants", term: "conservatory greenhouse", promptHint: "set inside a glass-walled conservatory greenhouse with tropical plants, hanging ferns, terracotta pots, filtered sunlight pouring through the panes and a humid earthy atmosphere" },
62
73
 
63
74
  // -------------------- Urban --------------------
64
75
  { id: "city-street", label: "City Street", category: "urban", description: "Bustling city street", promptHint: "set on a bustling city street with pedestrians, traffic, reflections on wet asphalt and mid-rise commercial facades" },
65
- { id: "rooftop", label: "Rooftop", category: "urban", description: "Rooftop terrace over skyline", promptHint: "set on a rooftop terrace overlooking a dense city skyline with string lights, distant car horns and hazy sunset light" },
76
+ { id: "rooftop", label: "Rooftop", category: "urban", description: "Rooftop terrace over skyline", term: "rooftop terrace", promptHint: "set on a rooftop terrace overlooking a dense city skyline with string lights, distant car horns and hazy sunset light" },
66
77
  { id: "back-alley", label: "Back Alley", category: "urban", description: "Gritty narrow alley", promptHint: "set in a narrow urban back alley with dumpsters, fire escapes, overflowing rain gutters and a single flickering wall sconce" },
67
- { id: "neon-alley", label: "Neon Alley", category: "urban", description: "Rain-soaked neon alley", promptHint: "set in a rain-soaked neon-lit alley in a Tokyo-style nightlife district with glowing kanji signs, steam vents and reflective puddles" },
78
+ { id: "neon-alley", label: "Neon Alley", category: "urban", description: "Rain-soaked neon alley", term: "rain-soaked neon-lit alley", promptHint: "set in a rain-soaked neon-lit alley in a Tokyo-style nightlife district with glowing kanji signs, steam vents and reflective puddles" },
68
79
  { id: "park", label: "Urban Park", category: "urban", description: "Leafy urban park with paths", promptHint: "set in a leafy urban park with winding footpaths, wooden benches, tall shade trees, people lounging on grass and sunlight filtering through leaves" },
69
80
  { id: "backyard", label: "Backyard Patio", category: "urban", description: "Deck patio with string lights", promptHint: "set in a warm backyard patio with a wooden deck, string lights overhead, lounge chairs, green lawn beyond a low fence and the soft golden light of a late summer afternoon" },
70
81
  { id: "highway", label: "Open Highway", category: "urban", description: "Sweeping highway to horizon", promptHint: "set on a sweeping open highway with lane markings stretching to the horizon, rolling hills on either side, a single car on the road and a vast cinematic sky" },
71
82
  { id: "bridge", label: "Suspension Bridge", category: "urban", description: "Long suspension bridge over water", promptHint: "set on a long suspension bridge with towering steel cables, sweeping views over water, evening glow on the railings and a distant city skyline beyond" },
72
- { id: "train-station", label: "Train Station", category: "urban", description: "Platform with waiting train", promptHint: "set on a long urban train station platform with polished steel rails, a waiting train with warmly lit windows, overhead station signs, drifting steam and the lonely echo of footsteps on stone" },
83
+ { id: "train-station", label: "Train Station", category: "urban", description: "Platform with waiting train", term: "train station platform", promptHint: "set on a long urban train station platform with polished steel rails, a waiting train with warmly lit windows, overhead station signs, drifting steam and the lonely echo of footsteps on stone" },
73
84
  { id: "airport", label: "Airport Terminal", category: "urban", description: "Vast terminal with curved glass", promptHint: "set in a vast airport terminal with gleaming polished floors, flight information boards, travelers with rolling luggage, curved glass walls and the soft drone of distant announcements" },
74
85
  { id: "parking-lot", label: "Parking Lot", category: "urban", description: "Suburban parking lot at dusk", promptHint: "set in an empty suburban parking lot at dusk with sodium-vapor lamps casting orange pools, scattered shopping carts and painted lane lines" },
75
86
  { id: "penthouse", label: "Penthouse", category: "urban", description: "Luxury penthouse with skyline view", promptHint: "set in a luxury penthouse interior with panoramic skyline views, marble floors, modernist furniture and low warm ambient light" },
@@ -87,14 +98,14 @@ export const SETTINGS: ReadonlyArray<Setting> = [
87
98
  { id: "riverbank", label: "Riverbank", category: "nature", description: "Meandering river with willow trees", promptHint: "set on a meandering riverbank with slow flowing water, smooth pebbles along the shore, willow trees leaning over the banks and dappled sunlight rippling on the current" },
88
99
  { id: "waterfall", label: "Waterfall", category: "nature", description: "Cascading falls over mossy cliffs", promptHint: "set at a thundering waterfall cascading over mossy cliffs into a misty pool, rainbows in the spray, an emerald basin below and lush ferns clinging to wet rocks" },
89
100
  { id: "cave", label: "Cave", category: "nature", description: "Rocky cave with daylight shafts", promptHint: "set inside a vast rocky cave with dripping stalactites, pools of still water, shafts of daylight piercing the darkness from above and dark mossy walls slick with moisture" },
90
- { id: "western-canyon", label: "Western Canyon", category: "nature", description: "Red-rock mesa with a winding river", promptHint: "set in a sweeping Southwestern canyon landscape with red sandstone mesas, a winding river cutting through the valley floor, cottonwood groves, open arid plains and the wide cinematic sky of a classic Western" },
101
+ { id: "western-canyon", label: "Western Canyon", category: "nature", description: "Red-rock mesa with a winding river", term: "southwestern red-rock canyon", promptHint: "set in a sweeping Southwestern canyon landscape with red sandstone mesas, a winding river cutting through the valley floor, cottonwood groves, open arid plains and the wide cinematic sky of a classic Western" },
91
102
 
92
103
  // -------------------- Fantastical --------------------
93
104
  { id: "alien-planet", label: "Alien Planet", category: "fantastical", description: "Otherworldly landscape with twin moons", promptHint: "set on an otherworldly alien planet landscape with bioluminescent flora, twin moons in a violet sky and iridescent rock formations" },
94
105
  { id: "spaceship-interior", label: "Spaceship Interior", category: "fantastical", description: "Sleek starship corridor", promptHint: "set inside a sleek spaceship interior with curved corridors, illuminated control panels, softly humming machinery and a panoramic view of stars through a reinforced window" },
95
- { id: "underwater", label: "Underwater", category: "fantastical", description: "Sunlit deep-ocean scene", promptHint: "set in a deep-ocean underwater scene with shafts of sunlight piercing blue-green water, drifting particles and dim coral shapes" },
96
- { id: "fantasy-castle", label: "Fantasy Castle", category: "fantastical", description: "Sprawling castle courtyard", promptHint: "set in a sprawling fantasy castle courtyard with weathered stone walls, banners, torches in iron sconces and wrought-iron gates" },
97
- { id: "medieval-village", label: "Medieval Village", category: "fantastical", description: "Cobblestone village square", promptHint: "set in a cobblestone medieval village square with timber-framed houses, smoking chimneys, a stone well, market stalls and warm amber lantern light" },
106
+ { id: "underwater", label: "Underwater", category: "fantastical", description: "Sunlit deep-ocean scene", term: "deep-ocean underwater scene", promptHint: "set in a deep-ocean underwater scene with shafts of sunlight piercing blue-green water, drifting particles and dim coral shapes" },
107
+ { id: "fantasy-castle", label: "Fantasy Castle", category: "fantastical", description: "Sprawling castle courtyard", term: "fantasy castle courtyard", promptHint: "set in a sprawling fantasy castle courtyard with weathered stone walls, banners, torches in iron sconces and wrought-iron gates" },
108
+ { id: "medieval-village", label: "Medieval Village", category: "fantastical", description: "Cobblestone village square", term: "medieval village square", promptHint: "set in a cobblestone medieval village square with timber-framed houses, smoking chimneys, a stone well, market stalls and warm amber lantern light" },
98
109
  { id: "ancient-ruins", label: "Ancient Ruins", category: "fantastical", description: "Vine-choked stone ruins", promptHint: "set among vine-choked ancient stone ruins with toppled pillars, weathered carvings, shafts of golden light piercing overgrown jungle and the weight of a long-forgotten civilization" },
99
110
  { id: "cyberpunk-city", label: "Cyberpunk City", category: "fantastical", description: "Sprawling neon megacity skyline", promptHint: "set on an elevated walkway over a sprawling cyberpunk megacity skyline at night with towering neon-clad skyscrapers, holographic billboards, flying traffic and a pink haze blanketing the grid" },
100
111
  { id: "haunted-mansion", label: "Haunted Mansion", category: "fantastical", description: "Decaying gothic manor", promptHint: "set inside a decaying gothic haunted mansion with cobwebbed chandeliers, warped wooden floors, dust-covered furniture and pale moonlight through cracked windows" },
@@ -120,6 +131,11 @@ export function getSettingPromptHint(id: string | undefined | null): string {
120
131
  return getSetting(id)?.promptHint ?? ""
121
132
  }
122
133
 
134
+ /** Compact counterpart of {@link getSettingPromptHint} — the short setting term. */
135
+ export function getSettingTerm(id: string | undefined | null): string {
136
+ return resolveTerm(getSetting(id))
137
+ }
138
+
123
139
  export const SETTING_IDS: ReadonlyArray<string> = SETTINGS.map((s) => s.id)
124
140
 
125
141
  export const SETTING_CATEGORY_LABELS: Readonly<Record<SettingCategory, string>> = {
package/src/style.ts CHANGED
@@ -20,51 +20,64 @@
20
20
  * at execution time.
21
21
  */
22
22
 
23
+ import { resolveTerm } from "./term.js"
24
+
23
25
  export interface Style {
24
26
  readonly id: string
25
27
  readonly label: string
26
28
  readonly description: string
27
29
  readonly promptHint: string
30
+ /**
31
+ * Compact professional term (see `term.ts`). Authored only where the
32
+ * lowercased label is not what an art director would write in a prompt —
33
+ * a UI compound ("Retro / Vintage"), a bare noun that reads as a SUBJECT
34
+ * rather than a medium ("Blueprint", "Chalkboard", "Graffiti"), a material
35
+ * where the trade term names the artwork ("Acrylic Paint" → "acrylic
36
+ * painting"), or a word that is ambiguous on its own ("Pastel" — the
37
+ * medium, not the color range). Everywhere else the lowercased label IS
38
+ * the term ("anime", "ukiyo-e", "cyberpunk") and nothing is authored.
39
+ */
40
+ readonly term?: string
28
41
  }
29
42
 
30
43
  export const STYLES: ReadonlyArray<Style> = [
31
44
  { id: "3d-render", label: "3D Render", description: "Modern CGI render with clean shading", promptHint: "3D rendered style, modern CGI aesthetic with clean shading, subtle ambient occlusion and crisp materials" },
32
45
  { id: "anime", label: "Anime", description: "Japanese animation look", promptHint: "anime style, Japanese animation aesthetic with bold cel-shaded lines, expressive eyes and saturated colors" },
33
- { id: "children-book", label: "Children's Book", description: "Warm illustrated storybook", promptHint: "children's book illustration style, warm hand-drawn storybook look with soft shapes, friendly characters and inviting colors" },
46
+ { id: "children-book", label: "Children's Book", description: "Warm illustrated storybook", promptHint: "children's book illustration style, warm hand-drawn storybook look with soft shapes, friendly characters and inviting colors", term: "children's book illustration" },
34
47
  { id: "cinematic", label: "Cinematic", description: "Film-grade dramatic image", promptHint: "cinematic film style, dramatic lighting with cinematic color grading, widescreen aesthetic and film-like depth of field" },
35
- { id: "comic-book", label: "Comic Book", description: "Inked panels with flat color", promptHint: "comic book style, bold inked outlines, halftone shading and flat saturated comic panel colors" },
48
+ { id: "comic-book", label: "Comic Book", description: "Inked panels with flat color", promptHint: "comic book style, bold inked outlines, halftone shading and flat saturated comic panel colors", term: "comic book art" },
36
49
  { id: "digital-art", label: "Digital Art", description: "Polished digital illustration", promptHint: "digital art style, polished digital painting with smooth brushwork, vibrant colors and clean rendering" },
37
- { id: "fantasy", label: "Fantasy", description: "Epic high-fantasy illustration", promptHint: "fantasy art style, epic high-fantasy illustration with painterly detail, magical atmosphere and rich lore-driven mood" },
50
+ { id: "fantasy", label: "Fantasy", description: "Epic high-fantasy illustration", promptHint: "fantasy art style, epic high-fantasy illustration with painterly detail, magical atmosphere and rich lore-driven mood", term: "fantasy art" },
38
51
  { id: "minimalist", label: "Minimalist", description: "Simple shapes, lots of whitespace", promptHint: "minimalist style, reduced composition with simple shapes, limited palette and generous negative space" },
39
- { id: "noir", label: "Noir", description: "High-contrast B&W film noir", promptHint: "film noir style, high-contrast black-and-white imagery, deep shadows, venetian-blind lighting and moody 1940s cinema feel" },
52
+ { id: "noir", label: "Noir", description: "High-contrast B&W film noir", promptHint: "film noir style, high-contrast black-and-white imagery, deep shadows, venetian-blind lighting and moody 1940s cinema feel", term: "film noir" },
40
53
  { id: "oil-painting", label: "Oil Painting", description: "Thick brush strokes, classical canvas", promptHint: "oil painting style, visible thick brush strokes on canvas with rich pigment, classical painterly texture and warm tonal blending" },
41
54
  { id: "pencil-sketch", label: "Pencil Sketch", description: "Hand-drawn graphite drawing", promptHint: "pencil sketch style, hand-drawn graphite drawing with visible hatching, soft smudges and raw paper texture" },
42
55
  { id: "photorealistic", label: "Photorealistic", description: "Indistinguishable from a photograph", promptHint: "photorealistic style, high-fidelity photographic realism with natural lighting, accurate materials and DSLR-grade detail" },
43
56
  { id: "pixel-art", label: "Pixel Art", description: "Retro game-style pixel grid", promptHint: "pixel art style, retro low-resolution pixel grid aesthetic with limited palette and hard-edged chunky sprites" },
44
57
  { id: "pop-art", label: "Pop Art", description: "Bold colors, Warhol/Lichtenstein", promptHint: "pop art style, bold saturated colors, Ben-Day dots and high-contrast Warhol/Lichtenstein-inspired graphic look" },
45
- { id: "retro-vintage", label: "Retro / Vintage", description: "Faded nostalgic film look", promptHint: "retro vintage style, faded nostalgic film look with muted colors, subtle grain and old-photograph warmth" },
58
+ { id: "retro-vintage", label: "Retro / Vintage", description: "Faded nostalgic film look", promptHint: "retro vintage style, faded nostalgic film look with muted colors, subtle grain and old-photograph warmth", term: "retro vintage film look" },
46
59
  { id: "watercolor", label: "Watercolor", description: "Soft transparent washes", promptHint: "watercolor style, soft transparent washes with bleeding edges, paper grain and delicate pigment pooling" },
47
60
  { id: "concept-art", label: "Concept Art", description: "Film/game pre-production painting", promptHint: "concept art style, painterly film and game pre-production illustration with dramatic lighting, moody atmosphere and loose brushwork emphasizing scale and storytelling" },
48
- { id: "impressionism", label: "Impressionism", description: "Monet-style dabbed brushwork", promptHint: "impressionist style, Monet-inspired visible dabbed brush strokes, soft natural light, pastel palette and loose color mixing that captures atmosphere over detail" },
49
- { id: "surrealism", label: "Surrealism", description: "Dreamlike Dalí-inspired", promptHint: "surrealist style, Dalí-inspired dreamlike imagery with impossible geometry, melting forms, floating elements and uncanny color combinations" },
61
+ { id: "impressionism", label: "Impressionism", description: "Monet-style dabbed brushwork", promptHint: "impressionist style, Monet-inspired visible dabbed brush strokes, soft natural light, pastel palette and loose color mixing that captures atmosphere over detail", term: "impressionist painting" },
62
+ { id: "surrealism", label: "Surrealism", description: "Dreamlike Dalí-inspired", promptHint: "surrealist style, Dalí-inspired dreamlike imagery with impossible geometry, melting forms, floating elements and uncanny color combinations", term: "surrealist painting" },
50
63
  { id: "cyberpunk", label: "Cyberpunk", description: "Neon-lit dystopian future", promptHint: "cyberpunk style, neon-lit dystopian future aesthetic with magenta and cyan glow, rain-slick reflections, high-tech low-life mood and dense urban detail" },
51
64
  { id: "steampunk", label: "Steampunk", description: "Victorian brass + machinery", promptHint: "steampunk style, Victorian-era brass and copper machinery, exposed gears and pipes, sepia tones and retrofuturistic mechanical detail" },
52
65
  { id: "vaporwave", label: "Vaporwave", description: "80s pastel digital retro", promptHint: "vaporwave style, 1980s digital retro aesthetic with pastel pink and teal palette, chrome text, glitch artifacts, palm silhouettes and dreamlike sunset grids" },
53
66
  { id: "low-poly", label: "Low Poly", description: "Faceted geometric 3D", promptHint: "low poly style, faceted geometric 3D aesthetic with visible flat triangular faces, simplified forms and crisp shadow edges between facets" },
54
- { id: "ink-wash", label: "Ink Wash", description: "East-Asian sumi-e brush", promptHint: "ink wash sumi-e style, East-Asian brush painting on rice paper with bold gestural black brush strokes, soft ink bleeding and generous negative space" },
67
+ { id: "ink-wash", label: "Ink Wash", description: "East-Asian sumi-e brush", promptHint: "ink wash sumi-e style, East-Asian brush painting on rice paper with bold gestural black brush strokes, soft ink bleeding and generous negative space", term: "sumi-e ink wash painting" },
55
68
  { id: "isometric", label: "Isometric", description: "3/4 axonometric view", promptHint: "isometric style, 3/4 axonometric projection with clean geometric forms, bright saturated flat colors and uniform lighting like a tile-based game or architectural diagram" },
56
- { id: "flat-vector", label: "Flat Vector", description: "Modern flat illustration", promptHint: "flat vector illustration style, modern SaaS-style flat shapes with bright solid colors, no gradients or shadows, clean geometry and friendly simplified forms" },
69
+ { id: "flat-vector", label: "Flat Vector", description: "Modern flat illustration", promptHint: "flat vector illustration style, modern SaaS-style flat shapes with bright solid colors, no gradients or shadows, clean geometry and friendly simplified forms", term: "flat vector illustration" },
57
70
  { id: "ukiyo-e", label: "Ukiyo-e", description: "Japanese woodblock print", promptHint: "ukiyo-e style, traditional Japanese woodblock print with bold outlined flat color planes, Hokusai-inspired palette and stylized natural elements" },
58
- { id: "graffiti", label: "Graffiti", description: "Street-art spray paint", promptHint: "graffiti street art style, vivid urban spray-paint aesthetic with bold tag lettering, drip textures, stencil edges and gritty wall surfaces" },
71
+ { id: "graffiti", label: "Graffiti", description: "Street-art spray paint", promptHint: "graffiti street art style, vivid urban spray-paint aesthetic with bold tag lettering, drip textures, stencil edges and gritty wall surfaces", term: "graffiti street art" },
59
72
  { id: "claymation", label: "Claymation", description: "Tactile stop-motion clay", promptHint: "claymation stop-motion style, tactile handcrafted clay figures with visible fingerprints, rounded plasticine forms and warm diorama lighting reminiscent of Aardman productions" },
60
73
  { id: "glitch-art", label: "Glitch Art", description: "Digital corruption + datamosh", promptHint: "glitch art style, digital corruption aesthetic with chromatic aberration, RGB channel shifts, horizontal scanline tearing, pixel sorting and datamoshed compression artifacts" },
61
74
  { id: "ascii-art", label: "ASCII Art", description: "Monochrome terminal characters", promptHint: "ASCII art style, monochrome terminal aesthetic built from text characters (@ # %, . :) forming the image, green-on-black old-computer vibe, monospace typography and character-grid rendering" },
62
- { id: "blueprint", label: "Blueprint", description: "Technical drawing on blue", promptHint: "blueprint technical drawing style, white line work on deep cyan-blue paper with dimension lines, annotations, orthographic projections and engineering-schematic precision" },
75
+ { id: "blueprint", label: "Blueprint", description: "Technical drawing on blue", promptHint: "blueprint technical drawing style, white line work on deep cyan-blue paper with dimension lines, annotations, orthographic projections and engineering-schematic precision", term: "blueprint technical drawing" },
63
76
  { id: "stained-glass", label: "Stained Glass", description: "Leaded colored glass mosaic", promptHint: "stained glass window style, tessellated colored glass panels separated by thick black lead lines, luminous backlit jewel tones and church-window composition" },
64
- { id: "chalkboard", label: "Chalkboard", description: "White chalk on slate", promptHint: "chalkboard style, white and pastel chalk on dark slate with smudged edges, visible chalk dust, hand-drawn marks and classroom-lecture feel" },
77
+ { id: "chalkboard", label: "Chalkboard", description: "White chalk on slate", promptHint: "chalkboard style, white and pastel chalk on dark slate with smudged edges, visible chalk dust, hand-drawn marks and classroom-lecture feel", term: "chalk drawing on blackboard" },
65
78
  { id: "paper-cutout", label: "Paper Cutout", description: "Layered cut paper + shadows", promptHint: "paper cutout papercraft style, Matisse-inspired layered cut paper shapes with visible paper texture, clean scissor edges and soft drop shadows between layered planes" },
66
79
  { id: "illuminated", label: "Illuminated Manuscript", description: "Gold leaf + calligraphy", promptHint: "illuminated manuscript style, medieval parchment with gold leaf accents, ornate decorative borders with vines and creatures, calligraphic script and jewel-toned miniature paintings" },
67
- { id: "pixar-3d", label: "Pixar 3D", description: "Polished character animation CG", promptHint: "Pixar-style 3D character animation, polished CG with appealing rounded character design, soft subsurface skin shading, cinematic key lighting and expressive animated feature-film quality" },
80
+ { id: "pixar-3d", label: "Pixar 3D", description: "Polished character animation CG", promptHint: "Pixar-style 3D character animation, polished CG with appealing rounded character design, soft subsurface skin shading, cinematic key lighting and expressive animated feature-film quality", term: "pixar-style 3d animation" },
68
81
  { id: "caricature", label: "Caricature", description: "Exaggerated stylized portrait", promptHint: "caricature illustration style, an exaggerated stylized portrait with a comically oversized head on a small body, amplified signature features — large nose, wide grin, oversized eyes — drawn with confident ink lines and watery color washes in the tradition of street-fair sketch artists" },
69
82
  { id: "fresco", label: "Fresco", description: "Renaissance plaster wall painting", promptHint: "rendered as a fresco painting in the style of a Renaissance ceiling, mineral pigments soaked into wet lime plaster with a chalky matte surface, softly weathered tonal range, faint craquelure and warm earthen palette reminiscent of Michelangelo's Sistine Chapel" },
70
83
  { id: "mosaic", label: "Mosaic", description: "Byzantine tessera tile composition", promptHint: "rendered as a mosaic composed of small hand-cut tesserae in stone, ceramic and gilded glass, visible grout lines between every tile, faceted highlights catching the light and a Byzantine / ancient-Roman aesthetic with stylized figures on a shimmering gold ground" },
@@ -72,8 +85,8 @@ export const STYLES: ReadonlyArray<Style> = [
72
85
  { id: "etching", label: "Etching", description: "Rembrandt-style intaglio print", promptHint: "rendered as an intaglio etching, dense fine cross-hatched lines bitten into a copper plate, rich velvety blacks against warm cream paper, delicate tonal gradations and the introspective chiaroscuro of a Rembrandt print" },
73
86
  { id: "lithograph", label: "Lithograph", description: "Toulouse-Lautrec stone-printed poster", promptHint: "rendered as a stone lithograph, soft graphite-like tonal range with grainy crayon textures, flat areas of limited spot color, slightly off-register edges and the bold poster-art sensibility of a Toulouse-Lautrec belle-époque print" },
74
87
  { id: "charcoal", label: "Charcoal Drawing", description: "Smudgeable black tonal study", promptHint: "rendered as a charcoal drawing on toothy paper, soft black and grey tonal masses with smudged blended midtones, sharp accented darks, expressive gestural strokes and the raw immediacy of a fine-art figure study" },
75
- { id: "pastel", label: "Pastel", description: "Degas-era soft chalk pastel", promptHint: "rendered as a soft chalk pastel drawing, dry powdery pigment laid in feathered strokes on tinted paper with luminous dusty colors, gently blended edges and the dreamy Degas-era atmosphere of dancers in stage light" },
76
- { id: "acrylic-paint", label: "Acrylic Paint", description: "Fast-drying opaque acrylic on canvas", promptHint: "rendered as an acrylic painting on canvas, fast-drying opaque pigment with crisp sharp edges, confident quick brush strokes, high-key saturated color and a flatter more graphic finish than traditional oil paint" },
88
+ { id: "pastel", label: "Pastel", description: "Degas-era soft chalk pastel", promptHint: "rendered as a soft chalk pastel drawing, dry powdery pigment laid in feathered strokes on tinted paper with luminous dusty colors, gently blended edges and the dreamy Degas-era atmosphere of dancers in stage light", term: "soft pastel drawing" },
89
+ { id: "acrylic-paint", label: "Acrylic Paint", description: "Fast-drying opaque acrylic on canvas", promptHint: "rendered as an acrylic painting on canvas, fast-drying opaque pigment with crisp sharp edges, confident quick brush strokes, high-key saturated color and a flatter more graphic finish than traditional oil paint", term: "acrylic painting" },
77
90
  { id: "mixed-media", label: "Mixed Media", description: "Collage + paint + ink hybrid", promptHint: "rendered as a mixed-media artwork combining torn paper collage, acrylic paint, ink and graphite on a layered substrate, heterogeneous textures, visible tape and stitching, and an exuberant hand-assembled studio-art quality" },
78
91
  { id: "manga", label: "Manga", description: "Inked B&W Japanese comic panel", promptHint: "rendered as inked manga panel art, crisp black ink on white with confident line weight variation, screen-tone dot patterns for shading, dramatic speed lines and the distinctly Japanese black-and-white comic aesthetic — separate from full-color anime" },
79
92
  ] as const
@@ -96,4 +109,9 @@ export function getStylePromptHint(id: string | undefined | null): string {
96
109
  return getStyle(id)?.promptHint ?? ""
97
110
  }
98
111
 
112
+ /** Compact counterpart of `getStylePromptHint` — see `term.ts`. */
113
+ export function getStyleTerm(id: string | undefined | null): string {
114
+ return resolveTerm(getStyle(id))
115
+ }
116
+
99
117
  export const STYLE_IDS: ReadonlyArray<string> = STYLES.map((s) => s.id)