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,33 @@
1
+ import { TIRED_GIRL_STYLE_MAP, TIRED_GIRL_STYLES } from "../config/tiredGirl.js";
2
+ export const resolveTiredGirlStyles = (styleIds, quantity = 1) => {
3
+ if (styleIds && styleIds.length > 0) {
4
+ const resolved = styleIds
5
+ .map((id) => TIRED_GIRL_STYLE_MAP.get(id))
6
+ .filter((style) => !!style);
7
+ if (resolved.length > 0)
8
+ return resolved;
9
+ }
10
+ // Default cycling through predefined styles
11
+ const styles = [];
12
+ for (let i = 0; i < quantity; i += 1) {
13
+ styles.push(TIRED_GIRL_STYLES[i % TIRED_GIRL_STYLES.length]);
14
+ }
15
+ return styles;
16
+ };
17
+ export const buildTiredGirlPrompt = (style, hasMuse) => {
18
+ return `You are a world-renowned fashion photographer.
19
+ Your task is to write a prompt for an AI image generator to create a photorealistic portrait of a model in a "before" look.
20
+
21
+ CRITICAL GUIDELINES:
22
+ 1. JEWELRY REMOVAL: The final image must contain NO jewelry whatsoever (no rings, earrings, necklaces, bracelets, watches).
23
+ - If jewelry appears in reference images, REMOVE it.
24
+ 2. IDENTITY CONSISTENCY: The model must match the reference images exactly (same face, features, skin tone).
25
+ ${hasMuse ? "3. The reference images are of the same model (Muse). Use them to preserve identity." : "3. Use the reference image to preserve identity."}
26
+ 4. STYLE: ${style.value}
27
+ 5. WARDROBE: casual, at-home, or relaxed styling (if not explicitly specified in style).
28
+ 6. LIGHTING: naturalistic, soft, real-world light.
29
+ 7. REALISM: no stylized effects, no glamour retouching.
30
+
31
+ OUTPUT: A single, dense prompt describing the scene. Do not include any jewelry.`;
32
+ };
33
+ //# sourceMappingURL=tiredGirlPrompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tiredGirlPrompt.js","sourceRoot":"","sources":["../../src/prompt/tiredGirlPrompt.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEjF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,QAAmB,EAAE,WAAmB,CAAC,EAAY,EAAE;IAC5F,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,QAAQ;aACtB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;aACzC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,QAAQ,CAAC;IAC3C,CAAC;IAED,4CAA4C;IAC5C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAa,EAAE,OAAgB,EAAU,EAAE;IAC9E,OAAO;;;;;;;EAOP,OAAO,CAAC,CAAC,CAAC,sFAAsF,CAAC,CAAC,CAAC,kDAAkD;YAC3I,KAAK,CAAC,KAAK;;;;;iFAK0D,CAAC;AAClF,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ export declare const ensureDir: (dir: string) => Promise<void>;
2
+ export declare const readFileAsBase64: (filePath: string) => Promise<{
3
+ data: string;
4
+ mimeType: string;
5
+ }>;
6
+ export declare const readImageAsPart: (filePath: string) => Promise<{
7
+ inlineData: {
8
+ mimeType: string;
9
+ data: string;
10
+ };
11
+ }>;
12
+ export declare const saveBase64Image: (base64DataUrl: string, outputPath: string) => Promise<void>;
13
+ export declare const saveBinary: (bytes: Uint8Array, outputPath: string) => Promise<void>;
14
+ export declare const writeJson: (outputPath: string, payload: unknown) => Promise<void>;
15
+ export declare const resolveOutputDir: (baseDir: string, subdir: string) => string;
@@ -0,0 +1,34 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ export const ensureDir = async (dir) => {
4
+ await fs.mkdir(dir, { recursive: true });
5
+ };
6
+ export const readFileAsBase64 = async (filePath) => {
7
+ const buffer = await fs.readFile(filePath);
8
+ const ext = path.extname(filePath).toLowerCase();
9
+ const mimeType = ext === ".png" ? "image/png" : ext === ".webp" ? "image/webp" : "image/jpeg";
10
+ return { data: buffer.toString("base64"), mimeType };
11
+ };
12
+ export const readImageAsPart = async (filePath) => {
13
+ const { data, mimeType } = await readFileAsBase64(filePath);
14
+ return { inlineData: { data, mimeType } };
15
+ };
16
+ export const saveBase64Image = async (base64DataUrl, outputPath) => {
17
+ const base64 = base64DataUrl.includes(",") ? base64DataUrl.split(",")[1] : base64DataUrl;
18
+ const buffer = Buffer.from(base64, "base64");
19
+ await ensureDir(path.dirname(outputPath));
20
+ await fs.writeFile(outputPath, buffer);
21
+ };
22
+ export const saveBinary = async (bytes, outputPath) => {
23
+ await ensureDir(path.dirname(outputPath));
24
+ await fs.writeFile(outputPath, Buffer.from(bytes));
25
+ };
26
+ export const writeJson = async (outputPath, payload) => {
27
+ await ensureDir(path.dirname(outputPath));
28
+ await fs.writeFile(outputPath, JSON.stringify(payload, null, 2));
29
+ };
30
+ export const resolveOutputDir = (baseDir, subdir) => {
31
+ const stamp = new Date().toISOString().replace(/[:.]/g, "-");
32
+ return path.join(baseDir, subdir, stamp);
33
+ };
34
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/storage/files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAAE,GAAW,EAAiB,EAAE;IAC5D,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC3C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,QAAgB,EAA+C,EAAE;IACtG,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IACjD,MAAM,QAAQ,GAAG,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC;IAC9F,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;AACvD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAAE,QAAgB,EAA+D,EAAE;IACrH,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC5D,OAAO,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC;AAC5C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAAE,aAAqB,EAAE,UAAkB,EAAiB,EAAE;IAChG,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;IACzF,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC7C,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAC1C,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;AACzC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAAE,KAAiB,EAAE,UAAkB,EAAiB,EAAE;IACvF,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAC1C,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AACrD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAAE,UAAkB,EAAE,OAAgB,EAAiB,EAAE;IACrF,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAC1C,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAe,EAAE,MAAc,EAAU,EAAE;IAC1E,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC7D,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AAC3C,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { MuseRecord } from "../types.js";
2
+ export declare const loadMuses: (baseDir: string) => Promise<MuseRecord[]>;
3
+ export declare const saveMuses: (baseDir: string, muses: MuseRecord[]) => Promise<void>;
4
+ export declare const addMuse: (baseDir: string, muse: MuseRecord) => Promise<void>;
5
+ export declare const getMuseById: (baseDir: string, id: string) => Promise<MuseRecord | undefined>;
@@ -0,0 +1,26 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ const museIndexPath = (baseDir) => path.join(baseDir, "muses.json");
4
+ export const loadMuses = async (baseDir) => {
5
+ try {
6
+ const raw = await fs.readFile(museIndexPath(baseDir), "utf-8");
7
+ return JSON.parse(raw);
8
+ }
9
+ catch {
10
+ return [];
11
+ }
12
+ };
13
+ export const saveMuses = async (baseDir, muses) => {
14
+ await fs.mkdir(baseDir, { recursive: true });
15
+ await fs.writeFile(museIndexPath(baseDir), JSON.stringify(muses, null, 2));
16
+ };
17
+ export const addMuse = async (baseDir, muse) => {
18
+ const muses = await loadMuses(baseDir);
19
+ muses.push(muse);
20
+ await saveMuses(baseDir, muses);
21
+ };
22
+ export const getMuseById = async (baseDir, id) => {
23
+ const muses = await loadMuses(baseDir);
24
+ return muses.find((m) => m.id === id);
25
+ };
26
+ //# sourceMappingURL=museStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"museStore.js","sourceRoot":"","sources":["../../src/storage/museStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,MAAM,aAAa,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;AAE5E,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAAE,OAAe,EAAyB,EAAE;IACxE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;QAC/D,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAiB,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAAE,OAAe,EAAE,KAAmB,EAAiB,EAAE;IACrF,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,MAAM,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,EAAE,OAAe,EAAE,IAAgB,EAAiB,EAAE;IAChF,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;IACvC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,MAAM,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAClC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAE,OAAe,EAAE,EAAU,EAAmC,EAAE;IAChG,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;IACvC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AACxC,CAAC,CAAC"}
@@ -0,0 +1,169 @@
1
+ export type AspectRatio = "1:1" | "3:4" | "4:3" | "9:16" | "16:9";
2
+ export interface Option {
3
+ id: string;
4
+ name: string;
5
+ value: string;
6
+ visualColor?: string;
7
+ visualImage?: string;
8
+ }
9
+ export interface Template {
10
+ id: string;
11
+ name: string;
12
+ description: string;
13
+ visualUrl?: string;
14
+ basePrompt: string;
15
+ customizationLabel?: string;
16
+ customizationOptions?: Option[];
17
+ secondaryCustomizationLabel?: string;
18
+ secondaryCustomizationOptions?: Option[];
19
+ tertiaryCustomizationLabel?: string;
20
+ tertiaryCustomizationOptions?: Option[];
21
+ isAdminOnly?: boolean;
22
+ museEnabled?: boolean;
23
+ videoEnabled?: boolean;
24
+ }
25
+ export interface Resolution {
26
+ id: string;
27
+ label: string;
28
+ aspectRatio: AspectRatio;
29
+ icon?: string;
30
+ description: string;
31
+ instagramUse: string;
32
+ }
33
+ export interface OccasionTheme {
34
+ id: string;
35
+ name: string;
36
+ icon: string;
37
+ description: string;
38
+ autoConfig: {
39
+ vibe: string;
40
+ background: string;
41
+ backgroundType: string;
42
+ };
43
+ promptDetails?: {
44
+ setting: string;
45
+ atmosphere: string;
46
+ colorPalette: string;
47
+ culturalElements: string;
48
+ styling: string;
49
+ };
50
+ }
51
+ export interface GenerationSelections {
52
+ templateId: string;
53
+ detailId?: string;
54
+ secondaryDetailId?: string;
55
+ tertiaryDetailId?: string;
56
+ ethnicityId?: string;
57
+ skinToneId?: string;
58
+ hairColorId?: string;
59
+ backgroundId?: string;
60
+ backgroundTypeId?: string;
61
+ vibeId?: string;
62
+ resolutionId?: string;
63
+ occasionId?: string;
64
+ }
65
+ export interface GenerationRequest {
66
+ inputImages: string[];
67
+ quantity?: number;
68
+ selections: GenerationSelections;
69
+ styleHint?: string;
70
+ museId?: string;
71
+ museImagePaths?: string[];
72
+ outputDir?: string;
73
+ enhancePrompt?: boolean;
74
+ }
75
+ export interface GenerationResult {
76
+ prompt: string;
77
+ enhancedPrompt?: string;
78
+ outputImages: string[];
79
+ logPath: string;
80
+ }
81
+ export interface RefineRequest {
82
+ inputImage: string;
83
+ instruction: string;
84
+ sizeAdjustment?: number;
85
+ outputDir?: string;
86
+ }
87
+ export interface UpscaleRequest {
88
+ inputImage: string;
89
+ scale?: number;
90
+ outputDir?: string;
91
+ }
92
+ export interface MuseRecord {
93
+ id: string;
94
+ name: string;
95
+ imagePaths: string[];
96
+ createdAt: string;
97
+ }
98
+ export interface CreateMuseRequest {
99
+ name: string;
100
+ sourceImage: string;
101
+ variations?: number;
102
+ outputDir?: string;
103
+ }
104
+ export interface CreateMuseResult {
105
+ muse: MuseRecord;
106
+ variationPaths: string[];
107
+ logPath: string;
108
+ }
109
+ export interface VideoRequest {
110
+ prompt: string;
111
+ imageInput?: string;
112
+ durationSeconds?: number;
113
+ aspectRatio?: AspectRatio;
114
+ outputDir?: string;
115
+ }
116
+ export interface VideoResult {
117
+ operationName?: string;
118
+ videoPath?: string;
119
+ logPath: string;
120
+ }
121
+ export interface TiredGirlRequest {
122
+ inputImage?: string;
123
+ museId?: string;
124
+ styleIds?: string[];
125
+ quantity?: number;
126
+ outputDir?: string;
127
+ }
128
+ export interface TiredGirlResult {
129
+ outputImages: string[];
130
+ logPath: string;
131
+ }
132
+ export type TextPosition = "top-center" | "top-left" | "top-right" | "bottom-center" | "bottom-center-high" | "bottom-left" | "bottom-right" | "center";
133
+ export interface TextOverlayOptions {
134
+ fontFamily?: string;
135
+ fontSize?: number;
136
+ fontWeight?: number;
137
+ color?: string;
138
+ strokeColor?: string;
139
+ strokeWidth?: number;
140
+ banner?: boolean;
141
+ bannerColor?: string;
142
+ bannerPadding?: number;
143
+ bannerRadius?: number;
144
+ position?: TextPosition;
145
+ padding?: number;
146
+ maxWidthRatio?: number;
147
+ }
148
+ export interface GridOptions {
149
+ columns: number;
150
+ rows: number;
151
+ padding?: number;
152
+ background?: string;
153
+ tileWidth?: number;
154
+ tileHeight?: number;
155
+ }
156
+ export interface LumiereConfig {
157
+ apiKey: string;
158
+ outputDir: string;
159
+ models?: {
160
+ prompt?: string;
161
+ image?: string;
162
+ video?: string;
163
+ };
164
+ retry?: {
165
+ maxRetries?: number;
166
+ baseDelayMs?: number;
167
+ maxDelayMs?: number;
168
+ };
169
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ import "dotenv/config";
@@ -0,0 +1,28 @@
1
+ import "dotenv/config";
2
+ import { generateImages } from "../src/pipelines/generateImages";
3
+ const config = {
4
+ apiKey: process.env.GEMINI_API_KEY || "",
5
+ outputDir: process.env.LUMIERE_OUTPUT_DIR || "outputs"
6
+ };
7
+ const run = async () => {
8
+ if (!config.apiKey)
9
+ throw new Error("Missing GEMINI_API_KEY");
10
+ const result = await generateImages(config, {
11
+ inputImages: ["./inputs/ring.jpg"],
12
+ quantity: 1,
13
+ selections: {
14
+ templateId: "hand_model",
15
+ detailId: "nail_nude",
16
+ ethnicityId: "mena",
17
+ skinToneId: "medium",
18
+ hairColorId: "brunette",
19
+ backgroundId: "cream_silk",
20
+ backgroundTypeId: "studio",
21
+ vibeId: "clean",
22
+ resolutionId: "portrait"
23
+ }
24
+ });
25
+ console.log(result);
26
+ };
27
+ run();
28
+ //# sourceMappingURL=generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["generate.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAGjE,MAAM,MAAM,GAAkB;IAC5B,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE;IACxC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,SAAS;CACvD,CAAC;AAEF,MAAM,GAAG,GAAG,KAAK,IAAI,EAAE;IACrB,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,MAAM,EAAE;QAC1C,WAAW,EAAE,CAAC,mBAAmB,CAAC;QAClC,QAAQ,EAAE,CAAC;QACX,UAAU,EAAE;YACV,UAAU,EAAE,YAAY;YACxB,QAAQ,EAAE,WAAW;YACrB,WAAW,EAAE,MAAM;YACnB,UAAU,EAAE,QAAQ;YACpB,WAAW,EAAE,UAAU;YACvB,YAAY,EAAE,YAAY;YAC1B,gBAAgB,EAAE,QAAQ;YAC1B,MAAM,EAAE,OAAO;YACf,YAAY,EAAE,UAAU;SACzB;KACF,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC,CAAC;AAEF,GAAG,EAAE,CAAC"}
@@ -0,0 +1,30 @@
1
+ import "dotenv/config";
2
+ import { generateImages } from "../src/pipelines/generateImages";
3
+ import { LumiereConfig } from "../src/types";
4
+
5
+ const config: LumiereConfig = {
6
+ apiKey: process.env.GEMINI_API_KEY || "",
7
+ outputDir: process.env.LUMIERE_OUTPUT_DIR || "outputs"
8
+ };
9
+
10
+ const run = async () => {
11
+ if (!config.apiKey) throw new Error("Missing GEMINI_API_KEY");
12
+ const result = await generateImages(config, {
13
+ inputImages: ["./inputs/ring.jpg"],
14
+ quantity: 1,
15
+ selections: {
16
+ templateId: "hand_model",
17
+ detailId: "nail_nude",
18
+ ethnicityId: "mena",
19
+ skinToneId: "medium",
20
+ hairColorId: "brunette",
21
+ backgroundId: "cream_silk",
22
+ backgroundTypeId: "studio",
23
+ vibeId: "clean",
24
+ resolutionId: "portrait"
25
+ }
26
+ });
27
+ console.log(result);
28
+ };
29
+
30
+ run();
@@ -0,0 +1 @@
1
+ import "dotenv/config";
@@ -0,0 +1,18 @@
1
+ import "dotenv/config";
2
+ import { createMuse } from "../src/pipelines/createMuse";
3
+ const config = {
4
+ apiKey: process.env.GEMINI_API_KEY || "",
5
+ outputDir: process.env.LUMIERE_OUTPUT_DIR || "outputs"
6
+ };
7
+ const run = async () => {
8
+ if (!config.apiKey)
9
+ throw new Error("Missing GEMINI_API_KEY");
10
+ const result = await createMuse(config, {
11
+ name: "Editorial Muse",
12
+ sourceImage: "./inputs/muse_source.jpg",
13
+ variations: 3
14
+ });
15
+ console.log(result);
16
+ };
17
+ run();
18
+ //# sourceMappingURL=muse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"muse.js","sourceRoot":"","sources":["muse.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAGzD,MAAM,MAAM,GAAkB;IAC5B,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE;IACxC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,SAAS;CACvD,CAAC;AAEF,MAAM,GAAG,GAAG,KAAK,IAAI,EAAE;IACrB,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE;QACtC,IAAI,EAAE,gBAAgB;QACtB,WAAW,EAAE,0BAA0B;QACvC,UAAU,EAAE,CAAC;KACd,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC,CAAC;AAEF,GAAG,EAAE,CAAC"}
@@ -0,0 +1,20 @@
1
+ import "dotenv/config";
2
+ import { createMuse } from "../src/pipelines/createMuse";
3
+ import { LumiereConfig } from "../src/types";
4
+
5
+ const config: LumiereConfig = {
6
+ apiKey: process.env.GEMINI_API_KEY || "",
7
+ outputDir: process.env.LUMIERE_OUTPUT_DIR || "outputs"
8
+ };
9
+
10
+ const run = async () => {
11
+ if (!config.apiKey) throw new Error("Missing GEMINI_API_KEY");
12
+ const result = await createMuse(config, {
13
+ name: "Editorial Muse",
14
+ sourceImage: "./inputs/muse_source.jpg",
15
+ variations: 3
16
+ });
17
+ console.log(result);
18
+ };
19
+
20
+ run();
@@ -0,0 +1 @@
1
+ import "dotenv/config";
@@ -0,0 +1,18 @@
1
+ import "dotenv/config";
2
+ import { generateVideo } from "../src/pipelines/generateVideo";
3
+ const config = {
4
+ apiKey: process.env.GEMINI_API_KEY || "",
5
+ outputDir: process.env.LUMIERE_OUTPUT_DIR || "outputs"
6
+ };
7
+ const run = async () => {
8
+ if (!config.apiKey)
9
+ throw new Error("Missing GEMINI_API_KEY");
10
+ const result = await generateVideo(config, {
11
+ prompt: "A cinematic close-up of a model gently turning her head, earrings catching soft light. High-end jewelry commercial aesthetic.",
12
+ aspectRatio: "9:16",
13
+ durationSeconds: 5
14
+ });
15
+ console.log(result);
16
+ };
17
+ run();
18
+ //# sourceMappingURL=video.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video.js","sourceRoot":"","sources":["video.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAG/D,MAAM,MAAM,GAAkB;IAC5B,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE;IACxC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,SAAS;CACvD,CAAC;AAEF,MAAM,GAAG,GAAG,KAAK,IAAI,EAAE;IACrB,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE;QACzC,MAAM,EAAE,+HAA+H;QACvI,WAAW,EAAE,MAAM;QACnB,eAAe,EAAE,CAAC;KACnB,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC,CAAC;AAEF,GAAG,EAAE,CAAC"}
@@ -0,0 +1,20 @@
1
+ import "dotenv/config";
2
+ import { generateVideo } from "../src/pipelines/generateVideo";
3
+ import { LumiereConfig } from "../src/types";
4
+
5
+ const config: LumiereConfig = {
6
+ apiKey: process.env.GEMINI_API_KEY || "",
7
+ outputDir: process.env.LUMIERE_OUTPUT_DIR || "outputs"
8
+ };
9
+
10
+ const run = async () => {
11
+ if (!config.apiKey) throw new Error("Missing GEMINI_API_KEY");
12
+ const result = await generateVideo(config, {
13
+ prompt: "A cinematic close-up of a model gently turning her head, earrings catching soft light. High-end jewelry commercial aesthetic.",
14
+ aspectRatio: "9:16",
15
+ durationSeconds: 5
16
+ });
17
+ console.log(result);
18
+ };
19
+
20
+ run();
package/logo-round.png ADDED
Binary file
package/logo.jpeg ADDED
Binary file
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "studio-lumiere-cli",
3
+ "version": "0.1.0",
4
+ "description": "Local SDK + CLI for Studio Lumiere image and video generation",
5
+ "type": "module",
6
+ "bin": {
7
+ "lumiere": "dist/cli.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "dev": "tsx src/cli.ts",
12
+ "generate": "tsx examples/generate.ts",
13
+ "muse": "tsx examples/muse.ts",
14
+ "video": "tsx examples/video.ts"
15
+ },
16
+ "dependencies": {
17
+ "@google/genai": "^1.0.0",
18
+ "commander": "^12.0.0",
19
+ "dotenv": "^16.4.5",
20
+ "sharp": "^0.34.5"
21
+ },
22
+ "devDependencies": {
23
+ "@types/node": "^22.13.0",
24
+ "tsx": "^4.19.2",
25
+ "typescript": "^5.7.3"
26
+ }
27
+ }