studio-lumiere-cli 0.1.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 (114) hide show
  1. package/.agents/skills/annotate-image/SKILL.md +99 -0
  2. package/.agents/skills/config-troubleshooting/SKILL.md +97 -0
  3. package/.agents/skills/generate-images/SKILL.md +667 -0
  4. package/.agents/skills/generate-video/SKILL.md +328 -0
  5. package/.agents/skills/image-grid/SKILL.md +96 -0
  6. package/.agents/skills/image-overlay/SKILL.md +66 -0
  7. package/.agents/skills/image-overlay/agents/openai.yaml +4 -0
  8. package/.agents/skills/image-overlay/scripts/overlay-image.js +218 -0
  9. package/.agents/skills/muse-management/SKILL.md +232 -0
  10. package/.agents/skills/refine-images/SKILL.md +192 -0
  11. package/.agents/skills/tired-girl/SKILL.md +131 -0
  12. package/.env.example +2 -0
  13. package/AGENTS.md +66 -0
  14. package/README.md +96 -0
  15. package/dist/cli.d.ts +2 -0
  16. package/dist/cli.js +214 -0
  17. package/dist/cli.js.map +1 -0
  18. package/dist/clients/geminiClient.d.ts +37 -0
  19. package/dist/clients/geminiClient.js +129 -0
  20. package/dist/clients/geminiClient.js.map +1 -0
  21. package/dist/config/constants.d.ts +63 -0
  22. package/dist/config/constants.js +1005 -0
  23. package/dist/config/constants.js.map +1 -0
  24. package/dist/config/options.d.ts +1 -0
  25. package/dist/config/options.js +2 -0
  26. package/dist/config/options.js.map +1 -0
  27. package/dist/config/templates.d.ts +3 -0
  28. package/dist/config/templates.js +4 -0
  29. package/dist/config/templates.js.map +1 -0
  30. package/dist/config/tiredGirl.d.ts +3 -0
  31. package/dist/config/tiredGirl.js +9 -0
  32. package/dist/config/tiredGirl.js.map +1 -0
  33. package/dist/image/annotate.d.ts +2 -0
  34. package/dist/image/annotate.js +119 -0
  35. package/dist/image/annotate.js.map +1 -0
  36. package/dist/image/grid.d.ts +2 -0
  37. package/dist/image/grid.js +44 -0
  38. package/dist/image/grid.js.map +1 -0
  39. package/dist/index.d.ts +12 -0
  40. package/dist/index.js +13 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/pipelines/createMuse.d.ts +3 -0
  43. package/dist/pipelines/createMuse.js +49 -0
  44. package/dist/pipelines/createMuse.js.map +1 -0
  45. package/dist/pipelines/generateImages.d.ts +2 -0
  46. package/dist/pipelines/generateImages.js +140 -0
  47. package/dist/pipelines/generateImages.js.map +1 -0
  48. package/dist/pipelines/generateTiredGirl.d.ts +2 -0
  49. package/dist/pipelines/generateTiredGirl.js +73 -0
  50. package/dist/pipelines/generateTiredGirl.js.map +1 -0
  51. package/dist/pipelines/generateVideo.d.ts +2 -0
  52. package/dist/pipelines/generateVideo.js +27 -0
  53. package/dist/pipelines/generateVideo.js.map +1 -0
  54. package/dist/pipelines/refineImage.d.ts +2 -0
  55. package/dist/pipelines/refineImage.js +28 -0
  56. package/dist/pipelines/refineImage.js.map +1 -0
  57. package/dist/pipelines/resolve.d.ts +11 -0
  58. package/dist/pipelines/resolve.js +74 -0
  59. package/dist/pipelines/resolve.js.map +1 -0
  60. package/dist/pipelines/upscaleImage.d.ts +2 -0
  61. package/dist/pipelines/upscaleImage.js +23 -0
  62. package/dist/pipelines/upscaleImage.js.map +1 -0
  63. package/dist/prompt/buildPrompt.d.ts +4 -0
  64. package/dist/prompt/buildPrompt.js +322 -0
  65. package/dist/prompt/buildPrompt.js.map +1 -0
  66. package/dist/prompt/tiredGirlPrompt.d.ts +3 -0
  67. package/dist/prompt/tiredGirlPrompt.js +33 -0
  68. package/dist/prompt/tiredGirlPrompt.js.map +1 -0
  69. package/dist/storage/files.d.ts +15 -0
  70. package/dist/storage/files.js +34 -0
  71. package/dist/storage/files.js.map +1 -0
  72. package/dist/storage/museStore.d.ts +5 -0
  73. package/dist/storage/museStore.js +26 -0
  74. package/dist/storage/museStore.js.map +1 -0
  75. package/dist/types.d.ts +169 -0
  76. package/dist/types.js +2 -0
  77. package/dist/types.js.map +1 -0
  78. package/examples/generate.d.ts +1 -0
  79. package/examples/generate.js +28 -0
  80. package/examples/generate.js.map +1 -0
  81. package/examples/generate.ts +30 -0
  82. package/examples/muse.d.ts +1 -0
  83. package/examples/muse.js +18 -0
  84. package/examples/muse.js.map +1 -0
  85. package/examples/muse.ts +20 -0
  86. package/examples/video.d.ts +1 -0
  87. package/examples/video.js +18 -0
  88. package/examples/video.js.map +1 -0
  89. package/examples/video.ts +20 -0
  90. package/logo-round.png +0 -0
  91. package/logo.jpeg +0 -0
  92. package/package.json +27 -0
  93. package/src/cli.ts +259 -0
  94. package/src/clients/geminiClient.ts +168 -0
  95. package/src/config/constants.ts +1105 -0
  96. package/src/config/options.ts +15 -0
  97. package/src/config/templates.ts +4 -0
  98. package/src/config/tiredGirl.ts +11 -0
  99. package/src/image/annotate.ts +139 -0
  100. package/src/image/grid.ts +58 -0
  101. package/src/index.ts +27 -0
  102. package/src/pipelines/createMuse.ts +76 -0
  103. package/src/pipelines/generateImages.ts +203 -0
  104. package/src/pipelines/generateTiredGirl.ts +86 -0
  105. package/src/pipelines/generateVideo.ts +36 -0
  106. package/src/pipelines/refineImage.ts +36 -0
  107. package/src/pipelines/resolve.ts +88 -0
  108. package/src/pipelines/upscaleImage.ts +30 -0
  109. package/src/prompt/buildPrompt.ts +380 -0
  110. package/src/prompt/tiredGirlPrompt.ts +35 -0
  111. package/src/storage/files.ts +41 -0
  112. package/src/storage/museStore.ts +31 -0
  113. package/src/types.ts +198 -0
  114. package/tsconfig.json +15 -0
@@ -0,0 +1,667 @@
1
+ ---
2
+ name: generate-images
3
+ description: End-to-end guide to generate images with local-lumiere SDK/CLI; use for image generation workflows and parameter reference.
4
+ ---
5
+
6
+ # Skill: Generate Images (local-lumiere)
7
+
8
+ This document is a complete, end-to-end guide for an AI agent to generate images using the **local-lumiere** SDK/CLI. It is designed to be consumed as a standalone skill: read this file, then follow the steps exactly. It covers **every function**, **every parameter**, and **all configuration points** involved in image generation.
9
+
10
+ ---
11
+
12
+ ## Quick Start (60 seconds)
13
+
14
+ 1) Ensure `GEMINI_API_KEY` is set in your environment.
15
+ 2) Build the project:
16
+
17
+ ```
18
+ npm install
19
+ npm run build
20
+ ```
21
+
22
+ 3) Generate an image via CLI:
23
+
24
+ ```
25
+ node dist/cli.js generate \
26
+ --images ./inputs/ring.jpg \
27
+ --template hand_model \
28
+ --detail nail_nude \
29
+ --ethnicity mena \
30
+ --skin-tone medium \
31
+ --hair-color brunette \
32
+ --background cream_silk \
33
+ --background-type studio \
34
+ --vibe clean \
35
+ --resolution portrait \
36
+ --quantity 1
37
+ ```
38
+
39
+ 4) Find output files under `outputs/generations/<timestamp>/`.
40
+
41
+ ---
42
+
43
+ ## 0) Purpose
44
+
45
+ The goal is to programmatically generate high-end jewelry imagery locally, mirroring the Studio Lumiere app flow:
46
+
47
+ - Provide input jewelry images
48
+ - Choose a template + template options
49
+ - Pick model/style settings (ethnicity, skin tone, hair, background, vibe, resolution, occasion)
50
+ - Optionally use a Muse (consistent model reference)
51
+ - Optionally generate multiple outputs in one run
52
+ - Save outputs locally + log full metadata
53
+
54
+ This skill focuses specifically on **image generation** (not refine/upscale/video/muse creation except where Muse references are used in generation).
55
+
56
+ ---
57
+
58
+ ## 1) Where the Image Generation API Lives
59
+
60
+ **SDK entrypoint**: `src/index.ts`
61
+
62
+ - `generateImages` (primary API)
63
+ - `TEMPLATES`, `ETHNICITIES`, `SKIN_TONES`, `HAIR_COLORS`, `BACKGROUNDS`, `BACKGROUND_TYPES`, `VIBES`, `RESOLUTIONS`, `OCCASIONS` (config lists)
64
+
65
+ **Pipeline implementation**: `src/pipelines/generateImages.ts`
66
+
67
+ **Prompt building**: `src/prompt/buildPrompt.ts`
68
+
69
+ **Gemini client wrapper**: `src/clients/geminiClient.ts`
70
+
71
+ **Option resolution**: `src/pipelines/resolve.ts`
72
+
73
+ **File I/O**: `src/storage/files.ts`
74
+
75
+ **Muse lookup**: `src/storage/museStore.ts`
76
+
77
+ ---
78
+
79
+ ## 2) Required Environment and Configuration
80
+
81
+ ### 2.1 Environment Variables
82
+
83
+ - `GEMINI_API_KEY` (required)
84
+ - Used by `GeminiClient` to authenticate to Gemini APIs.
85
+
86
+ - `LUMIERE_OUTPUT_DIR` (optional)
87
+ - Default output directory for all generated assets.
88
+ - Defaults to `outputs` if not set.
89
+
90
+ ### 2.2 Runtime Config Object
91
+
92
+ All SDK functions expect a `LumiereConfig` object:
93
+
94
+ ```ts
95
+ export interface LumiereConfig {
96
+ apiKey: string; // required
97
+ outputDir: string; // required (can be read from env)
98
+ models?: {
99
+ prompt?: string; // Gemini text model
100
+ image?: string; // Gemini image model
101
+ video?: string; // Gemini video model
102
+ };
103
+ retry?: {
104
+ maxRetries?: number; // default: 3
105
+ baseDelayMs?: number;// default: 1500
106
+ maxDelayMs?: number; // default: 12000
107
+ };
108
+ }
109
+ ```
110
+
111
+ Defaults if omitted:
112
+
113
+ - `models.prompt`: `gemini-3-flash-preview`
114
+ - `models.image`: `gemini-3-pro-image-preview`
115
+ - `models.video`: `veo-3.1-generate-preview` (not used for images)
116
+ - `retry.maxRetries`: 3
117
+ - `retry.baseDelayMs`: 1500
118
+ - `retry.maxDelayMs`: 12000
119
+
120
+ ### 2.3 Output Directory Structure
121
+
122
+ `generateImages()` creates a timestamped folder under `outputDir`:
123
+
124
+ ```
125
+ outputs/
126
+ generations/
127
+ 2026-02-11T19-40-12-123Z/
128
+ image_1.png
129
+ image_2.png
130
+ generation.json
131
+ ```
132
+
133
+ The timestamp is generated in `resolveOutputDir()` in `src/storage/files.ts`.
134
+
135
+ ---
136
+
137
+ ## 3) Primary Function: generateImages
138
+
139
+ ### 3.1 Function Signature
140
+
141
+ ```ts
142
+ export const generateImages = async (
143
+ config: LumiereConfig,
144
+ request: GenerationRequest
145
+ ): Promise<GenerationResult>
146
+ ```
147
+
148
+ ### 3.2 Request Object: GenerationRequest
149
+
150
+ ```ts
151
+ export interface GenerationRequest {
152
+ inputImages: string[]; // Required. File paths to local jewelry images.
153
+ quantity?: number; // Optional. Number of images to generate. Default: 1.
154
+ selections: GenerationSelections; // Required. All template/style choices.
155
+ styleHint?: string; // Optional. Extra pose/angle guidance.
156
+ museId?: string; // Optional. ID of a stored Muse.
157
+ museImagePaths?: string[]; // Optional. Direct Muse image paths.
158
+ outputDir?: string; // Optional. Override config.outputDir.
159
+ enhancePrompt?: boolean; // Optional. Default true. Uses LLM prompt enhancement.
160
+ }
161
+ ```
162
+
163
+ ### 3.3 Response Object: GenerationResult
164
+
165
+ ```ts
166
+ export interface GenerationResult {
167
+ prompt: string; // Base prompt (pre-enhancement)
168
+ enhancedPrompt?: string; // Final prompt after enhancement
169
+ outputImages: string[]; // Paths of saved output images
170
+ logPath: string; // Path to generation.json
171
+ }
172
+ ```
173
+
174
+ ---
175
+
176
+ ## 4) GenerationSelections (All Parameters)
177
+
178
+ The **selections** object controls all creative settings. All IDs must match configured options.
179
+
180
+ ```ts
181
+ export interface GenerationSelections {
182
+ templateId: string; // Required: template key
183
+ detailId?: string; // Primary template option
184
+ secondaryDetailId?: string;// Secondary template option
185
+ tertiaryDetailId?: string; // Tertiary template option
186
+ ethnicityId?: string; // Model ethnicity
187
+ skinToneId?: string; // Model skin tone
188
+ hairColorId?: string; // Model hair color
189
+ backgroundId?: string; // Background palette
190
+ backgroundTypeId?: string; // Background environment
191
+ vibeId?: string; // Lighting & mood
192
+ resolutionId?: string; // Aspect ratio preset
193
+ occasionId?: string; // Optional theme
194
+ }
195
+ ```
196
+
197
+ **Every field is optional except `templateId`.**
198
+
199
+ If a field is not provided, the pipeline may:
200
+ - Omit that parameter from the prompt
201
+ - Fall back to a safe default (e.g., `resolutionId` defaults to `portrait`)
202
+
203
+ ---
204
+
205
+ ## 5) Templates (All Available IDs)
206
+
207
+ Templates are defined in `src/config/templates.ts` and resolved by `TEMPLATE_MAP`.
208
+
209
+ ### 5.1 Template IDs
210
+
211
+ - `hand_model`
212
+ - `neck_model`
213
+ - `ear_model`
214
+ - `flatlay_creative`
215
+ - `floating_minimal`
216
+ - `half_body_muse`
217
+ - `museum_exhibit`
218
+ - `romantic_mood`
219
+ - `romance_proposal`
220
+
221
+ Each template includes:
222
+
223
+ ```ts
224
+ interface Template {
225
+ id: string;
226
+ name: string;
227
+ description: string;
228
+ basePrompt: string;
229
+ customizationLabel?: string;
230
+ customizationOptions?: Option[];
231
+ secondaryCustomizationLabel?: string;
232
+ secondaryCustomizationOptions?: Option[];
233
+ tertiaryCustomizationLabel?: string;
234
+ tertiaryCustomizationOptions?: Option[];
235
+ museEnabled?: boolean;
236
+ videoEnabled?: boolean;
237
+ }
238
+ ```
239
+
240
+ ### 5.2 Template Options (Primary/Secondary/Tertiary)
241
+
242
+ Each template can define up to 3 customization groups:
243
+
244
+ - **Primary** => `detailId`
245
+ - **Secondary** => `secondaryDetailId`
246
+ - **Tertiary** => `tertiaryDetailId`
247
+
248
+ The option lists are defined per template in `src/config/templates.ts`.
249
+
250
+ If an ID is passed but not found in the template’s option list, the resolver will still accept it by mapping it to a placeholder `{ id, name, value }`.
251
+
252
+ ---
253
+
254
+ ## 6) Global Style Options (All Config Lists)
255
+
256
+ Defined in `src/config/options.ts`.
257
+
258
+ ### 6.1 Ethnicities (`ETHNICITIES`)
259
+
260
+ ```ts
261
+ id: "none" | "mena" | "south_asian" | "east_asian" | "black" | "white" | "latina"
262
+ ```
263
+
264
+ Used for prompt substitution and may expand to specific regions via `ETHNICITY_REGIONS`.
265
+
266
+ ### 6.2 Skin Tones (`SKIN_TONES`)
267
+
268
+ ```ts
269
+ id: "porcelain" | "fair" | "medium" | "tan" | "deep"
270
+ ```
271
+
272
+ ### 6.3 Hair Colors (`HAIR_COLORS`)
273
+
274
+ ```ts
275
+ id: "black" | "brunette" | "blonde" | "red" | "salt_pepper"
276
+ ```
277
+
278
+ ### 6.4 Background Palettes (`BACKGROUNDS`)
279
+
280
+ ```ts
281
+ id: "cream_silk" | "midnight_velvet" | "white_marble" | "warm_sand" | "charcoal"
282
+ ```
283
+
284
+ ### 6.5 Background Types (`BACKGROUND_TYPES`)
285
+
286
+ ```ts
287
+ id: "studio" | "interior" | "outdoor" | "macro"
288
+ ```
289
+
290
+ ### 6.6 Vibes (`VIBES`)
291
+
292
+ ```ts
293
+ id: "golden" | "moody" | "clean" | "romantic"
294
+ ```
295
+
296
+ ### 6.7 Resolutions (`RESOLUTIONS`)
297
+
298
+ ```ts
299
+ id: "square" | "portrait" | "story" | "landscape"
300
+ ```
301
+
302
+ Maps to aspect ratio values:
303
+
304
+ - square => `1:1`
305
+ - portrait => `3:4`
306
+ - story => `9:16`
307
+ - landscape => `16:9`
308
+
309
+ ### 6.8 Occasions (`OCCASIONS`)
310
+
311
+ Example IDs:
312
+
313
+ - `wedding`
314
+ - `eid`
315
+ - `valentines`
316
+
317
+ Each occasion injects a rich scene description into the prompt if selected.
318
+
319
+ ---
320
+
321
+ ## 7) Prompt Construction (All Inputs and Behavior)
322
+
323
+ Prompt construction happens in `buildLumierePrompt()` in `src/prompt/buildPrompt.ts`.
324
+
325
+ ### 7.1 Inputs
326
+
327
+ ```ts
328
+ interface PromptInputs {
329
+ template: Template;
330
+ detail?: Option;
331
+ secondaryDetail?: Option;
332
+ tertiaryDetail?: Option;
333
+ ethnicity?: Option;
334
+ skinTone?: Option;
335
+ hairColor?: Option;
336
+ background?: Option;
337
+ backgroundType?: Option;
338
+ vibe?: Option;
339
+ resolution: Resolution;
340
+ occasion?: OccasionTheme;
341
+ imageCount: number;
342
+ isVariation?: boolean;
343
+ styleHint?: string;
344
+ hasMuse?: boolean;
345
+ }
346
+ ```
347
+
348
+ ### 7.2 Core Prompt Rules
349
+
350
+ - Replaces `[ETHNICITY]` and `[HAIR_COLOR]` placeholders in template base prompts.
351
+ - Enforces jewelry fidelity (no extra jewelry, no fake sparkles).
352
+ - Optionally adds occasion scene blocks.
353
+ - Adds model specifications from detail/secondary/tertiary selections.
354
+ - Applies environment settings if no occasion is chosen.
355
+ - Adds technical requirements, aspect ratio, and strict prohibitions.
356
+ - If `styleHint` is provided, it appends “STYLE & POSE DIRECTION.”
357
+ - If `isVariation` true, it appends an explicit “variation instruction.”
358
+
359
+ ### 7.3 Skip Logic for Ethnicity
360
+
361
+ Ethnicity is **not** included when:
362
+
363
+ - A Muse is being used (`hasMuse` true), OR
364
+ - Template is one of: `hand_model`, `flatlay_creative`, `floating_minimal`, `museum_exhibit`, `romantic_mood`
365
+
366
+ ### 7.4 System Instruction
367
+
368
+ `buildSystemInstruction(template, ethnicity)` generates an additional system-style block to guide the LLM for each template.
369
+
370
+ This is combined with the base prompt if `enhancePrompt` is enabled:
371
+
372
+ ```
373
+ final = systemInstruction + "\n\n" + basePrompt
374
+ ```
375
+
376
+ ---
377
+
378
+ ## 8) Prompt Enhancement (Gemini Text Model)
379
+
380
+ If `enhancePrompt` is `true` (default), the pipeline calls:
381
+
382
+ ```ts
383
+ GeminiClient.generateText(promptInput)
384
+ ```
385
+
386
+ - `promptInput` = system instruction + base prompt
387
+ - The result becomes `enhancedPrompt`
388
+
389
+ If disabled, `enhancedPrompt` is the same as `basePrompt`.
390
+
391
+ ---
392
+
393
+ ## 9) Muse Handling in Generation
394
+
395
+ There are **two ways** to supply Muse references:
396
+
397
+ 1) **Direct image paths**: `museImagePaths` (preferred for ad-hoc runs)
398
+ 2) **Stored Muse**: `museId`, loaded from `muses.json`
399
+
400
+ ### 9.1 Muse Image Parts
401
+
402
+ If Muse images are provided, they are appended to the image parts array and the final prompt is extended with strict Muse consistency language.
403
+
404
+ Muse logic happens in `generateImages.ts`:
405
+
406
+ ```ts
407
+ if (museImageParts) {
408
+ finalPrompt += "Muse consistency requirement...";
409
+ }
410
+ ```
411
+
412
+ Muse images are passed **after** jewelry images in the `parts` array:
413
+
414
+ ```
415
+ parts = [ { text: finalPrompt }, ...jewelryImages, ...museImages ]
416
+ ```
417
+
418
+ ---
419
+
420
+ ## 10) Gemini Image Generation Call
421
+
422
+ Image generation is performed by:
423
+
424
+ ```ts
425
+ GeminiClient.generateImage({
426
+ parts,
427
+ aspectRatio,
428
+ imageSize: "2K"
429
+ })
430
+ ```
431
+
432
+ ### 10.1 parts
433
+
434
+ `parts` is an array of:
435
+
436
+ ```ts
437
+ { text?: string; inlineData?: { mimeType: string; data: string } }
438
+ ```
439
+
440
+ The first part is always the prompt (text). Subsequent parts are inline base64 images.
441
+
442
+ ### 10.2 Aspect Ratio
443
+
444
+ Passed from `Resolution.aspectRatio`, resolved via `resolveResolution()`.
445
+
446
+ ### 10.3 Image Size
447
+
448
+ Hard-coded to `2K` in the image generation pipeline.
449
+
450
+ ---
451
+
452
+ ## 11) Upscaling an Image
453
+
454
+ While this skill focuses on generation, upscaling is a common follow-up step and is supported locally via `upscaleImage`.
455
+
456
+ ### 11.1 Function Signature
457
+
458
+ ```ts
459
+ export const upscaleImage = async (
460
+ config: LumiereConfig,
461
+ request: UpscaleRequest
462
+ ): Promise<string>
463
+ ```
464
+
465
+ ### 11.2 Request Object: UpscaleRequest
466
+
467
+ ```ts
468
+ export interface UpscaleRequest {
469
+ inputImage: string; // Required. Path to a local image file.
470
+ scale?: number; // Optional. Scale factor (default: 2).
471
+ outputDir?: string; // Optional. Override config.outputDir.
472
+ }
473
+ ```
474
+
475
+ ### 11.3 Behavior
476
+
477
+ - Builds an upscaling prompt: "Upscale this image to Nx resolution..."
478
+ - Uses Gemini image model via `GeminiClient.generateImage()`
479
+ - Saves output as `upscaled.png` in `outputs/upscales/<timestamp>/`
480
+ - Writes `upscale.json` log with input path, scale, output path
481
+
482
+ ### 11.4 SDK Example
483
+
484
+ ```ts
485
+ import { upscaleImage } from "./dist/index.js";
486
+
487
+ const outputPath = await upscaleImage(
488
+ { apiKey, outputDir: "outputs" },
489
+ { inputImage: "./outputs/generations/.../image_1.png", scale: 2 }
490
+ );
491
+
492
+ console.log(outputPath);
493
+ ```
494
+
495
+ ### 11.5 CLI Example
496
+
497
+ ```
498
+ node dist/cli.js upscale --image ./outputs/image.png --scale 2
499
+ ```
500
+
501
+ ---
502
+
503
+ ## 12) CLI Usage (Full Parameters)
504
+
505
+ The CLI is implemented in `src/cli.ts` and compiled to `dist/cli.js`.
506
+
507
+ ### 12.1 Generate Command
508
+
509
+ ```
510
+ node dist/cli.js generate \
511
+ --images ./inputs/ring.jpg,./inputs/bracelet.jpg \
512
+ --template hand_model \
513
+ --detail nail_nude \
514
+ --secondary-detail nail_red \
515
+ --tertiary-detail makeup_soft \
516
+ --ethnicity mena \
517
+ --skin-tone medium \
518
+ --hair-color brunette \
519
+ --background cream_silk \
520
+ --background-type studio \
521
+ --vibe clean \
522
+ --resolution portrait \
523
+ --occasion wedding \
524
+ --quantity 2 \
525
+ --muse-id muse_1700000000000 \
526
+ --muse-images ./muses/m1.png,./muses/m2.png,./muses/m3.png
527
+ ```
528
+
529
+ ### 12.2 Important CLI Flags
530
+
531
+ - `--images`: **required**. Comma-separated list.
532
+ - `--template`: **required**. Must match one of `TEMPLATES`.
533
+ - `--detail`: optional
534
+ - `--secondary-detail`: optional
535
+ - `--tertiary-detail`: optional
536
+ - `--ethnicity`: optional
537
+ - `--skin-tone`: optional
538
+ - `--hair-color`: optional
539
+ - `--background`: optional
540
+ - `--background-type`: optional
541
+ - `--vibe`: optional
542
+ - `--resolution`: optional
543
+ - `--occasion`: optional
544
+ - `--quantity`: optional (default 1)
545
+ - `--muse-id`: optional
546
+ - `--muse-images`: optional (comma list)
547
+ - `--no-enhance`: disable prompt enhancement
548
+
549
+ `--no-enhance` flips `enhancePrompt=false`.
550
+
551
+ ---
552
+
553
+ ## 13) Function Call Example (SDK)
554
+
555
+ ```ts
556
+ import { generateImages } from "./dist/index.js";
557
+
558
+ const result = await generateImages(
559
+ {
560
+ apiKey: process.env.GEMINI_API_KEY!,
561
+ outputDir: "outputs",
562
+ models: {
563
+ prompt: "gemini-3-flash-preview",
564
+ image: "gemini-3-pro-image-preview"
565
+ },
566
+ retry: {
567
+ maxRetries: 3,
568
+ baseDelayMs: 1500,
569
+ maxDelayMs: 12000
570
+ }
571
+ },
572
+ {
573
+ inputImages: ["./inputs/ring.jpg"],
574
+ quantity: 2,
575
+ selections: {
576
+ templateId: "hand_model",
577
+ detailId: "nail_nude",
578
+ ethnicityId: "mena",
579
+ skinToneId: "medium",
580
+ hairColorId: "brunette",
581
+ backgroundId: "cream_silk",
582
+ backgroundTypeId: "studio",
583
+ vibeId: "clean",
584
+ resolutionId: "portrait",
585
+ occasionId: "wedding"
586
+ },
587
+ enhancePrompt: true
588
+ }
589
+ );
590
+
591
+ console.log(result.outputImages);
592
+ ```
593
+
594
+ ---
595
+
596
+ ## 14) Error Handling and Retries
597
+
598
+ All Gemini calls use a retry wrapper:
599
+
600
+ ```ts
601
+ retry: {
602
+ maxRetries: 3,
603
+ baseDelayMs: 1500,
604
+ maxDelayMs: 12000
605
+ }
606
+ ```
607
+
608
+ Retryable error detection looks for:
609
+ - HTTP 429 / 503
610
+ - “overloaded”, “unavailable”, “timeout” text
611
+
612
+ If all retries fail, the error is thrown as-is.
613
+
614
+ ---
615
+
616
+ ## 15) Extending or Modifying the Skill
617
+
618
+ If you need more templates/options:
619
+
620
+ - Add them to `src/config/templates.ts` or `src/config/options.ts`.
621
+ - Ensure your new IDs are used in `GenerationSelections`.
622
+ - The resolver will accept unknown IDs but won’t provide canonical names/values.
623
+
624
+ If you want a different image model or output size:
625
+
626
+ - Change defaults in `GeminiClient` or override `config.models.image`.
627
+ - Modify `generateImages.ts` to change `imageSize` from `2K` to `4K`.
628
+
629
+ ---
630
+
631
+ ## 16) Quick Checklist for an AI Agent
632
+
633
+ 1) Ensure `GEMINI_API_KEY` is set.
634
+ 2) Choose template ID from `TEMPLATES`.
635
+ 3) Pick detail IDs based on that template’s options.
636
+ 4) Decide optional style params (ethnicity, skin tone, hair, background, vibe, resolution, occasion).
637
+ 5) Collect local input image paths.
638
+ 6) Optionally provide Muse images or a stored `museId`.
639
+ 7) Call `generateImages(config, request)`.
640
+ 8) Read output paths and logs from the result.
641
+
642
+ ---
643
+
644
+ ## 17) Related Files (For Reference)
645
+
646
+ - `src/pipelines/generateImages.ts`
647
+ - `src/prompt/buildPrompt.ts`
648
+ - `src/clients/geminiClient.ts`
649
+ - `src/pipelines/resolve.ts`
650
+ - `src/config/templates.ts`
651
+ - `src/config/options.ts`
652
+ - `src/storage/files.ts`
653
+ - `src/storage/museStore.ts`
654
+ - `src/cli.ts`
655
+
656
+ End of skill.
657
+
658
+ ## Related Skills
659
+
660
+ - `C:\\Users\\karim\\Documents\\local-lumiere\\.agents\\skills\\generate-images.md`
661
+ - `C:\\Users\\karim\\Documents\\local-lumiere\\.agents\\skills\\generate-video.md`
662
+ - `C:\\Users\\karim\\Documents\\local-lumiere\\.agents\\skills\\refine-images.md`
663
+ - `C:\\Users\\karim\\Documents\\local-lumiere\\.agents\\skills\\muse-management.md`
664
+ - `C:\\Users\\karim\\Documents\\local-lumiere\\.agents\\skills\\tired-girl.md`
665
+ - `C:\\Users\\karim\\Documents\\local-lumiere\\.agents\\skills\\image-grid.md`
666
+ - `C:\\Users\\karim\\Documents\\local-lumiere\\.agents\\skills\\config-troubleshooting.md`
667
+