designkit-ai 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/designkit.js CHANGED
@@ -76,6 +76,7 @@ program
76
76
  .option('-o, --output <dir>', 'Output directory', '.')
77
77
  .option('-n, --name <name>', 'Output filename (without extension)', 'image')
78
78
  .option('-c, --count <n>', 'Number of images to generate (1–4)', '1')
79
+ .option('-m, --model <model>', 'Gemini model (default: gemini-2.5-flash, or imagen-3.0-generate-002)')
79
80
  .option('--aspect <ratio>', 'Aspect ratio: 1:1, 16:9, 9:16, 4:3, 3:4', '1:1')
80
81
  .option('--size <size>', 'DALL-E size: 1024x1024, 1792x1024, 1024x1792', '1024x1024')
81
82
  .option('--quality <quality>', 'DALL-E quality: standard, hd', 'standard')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "designkit-ai",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "502 HTML UI components + AI skills for designing and building web and mobile apps",
5
5
  "keywords": [
6
6
  "design-system",
@@ -1,13 +1,12 @@
1
1
  import { GoogleGenAI } from '@google/genai'
2
2
  import OpenAI from 'openai'
3
3
  import { writeFileSync, existsSync, mkdirSync } from 'fs'
4
- import { resolve, dirname } from 'path'
4
+ import { resolve } from 'path'
5
5
 
6
- const IMAGEN_MODEL = 'imagen-3.0-generate-002'
7
6
  const DALLE_MODEL = 'dall-e-3'
8
7
 
9
8
  const PROVIDERS = {
10
- gemini: { envKey: 'GEMINI_API_KEY', label: 'Imagen 3 (Google Gemini)' },
9
+ gemini: { envKey: 'GEMINI_API_KEY', label: 'Gemini (Google)' },
11
10
  openai: { envKey: 'OPENAI_API_KEY', label: 'DALL-E 3 (OpenAI)' }
12
11
  }
13
12
 
@@ -37,19 +36,69 @@ export async function imagineCommand(prompt, options) {
37
36
 
38
37
  if (!existsSync(outputDir)) mkdirSync(outputDir, { recursive: true })
39
38
 
40
- console.error(`\nProvider: ${PROVIDERS[provider].label}`)
41
- console.error(`Prompt: ${prompt}`)
42
- console.error(`Count: ${count}`)
43
- console.error(`Output: ${outputDir}\n`)
44
-
45
39
  if (provider === 'gemini') {
46
- await generateWithGemini({ apiKey, prompt, count, outputDir, options })
40
+ const model = options.model || 'gemini-2.5-flash'
41
+ console.error(`\nModel: ${model}`)
42
+ console.error(`Prompt: ${prompt}`)
43
+ console.error(`Count: ${count}`)
44
+ console.error(`Output: ${outputDir}\n`)
45
+
46
+ // imagen-* models use generateImages API
47
+ // gemini-* models use generateContent with responseModalities
48
+ if (model.startsWith('imagen')) {
49
+ await generateWithImagen({ apiKey, model, prompt, count, outputDir, options })
50
+ } else {
51
+ await generateWithGeminiFlash({ apiKey, model, prompt, count, outputDir, options })
52
+ }
47
53
  } else if (provider === 'openai') {
54
+ console.error(`\nModel: ${DALLE_MODEL}`)
55
+ console.error(`Prompt: ${prompt}`)
56
+ console.error(`Count: ${count}`)
57
+ console.error(`Output: ${outputDir}\n`)
48
58
  await generateWithOpenAI({ apiKey, prompt, count, outputDir, options })
49
59
  }
50
60
  }
51
61
 
52
- async function generateWithGemini({ apiKey, prompt, count, outputDir, options }) {
62
+ // gemini-2.5-flash, gemini-2.0-flash-exp-image-generation, etc.
63
+ async function generateWithGeminiFlash({ apiKey, model, prompt, count, outputDir, options }) {
64
+ const ai = new GoogleGenAI({ apiKey })
65
+ console.error(`Generating images...`)
66
+
67
+ const saved = []
68
+ for (let i = 0; i < count; i++) {
69
+ const response = await ai.models.generateContent({
70
+ model,
71
+ contents: prompt,
72
+ config: {
73
+ responseModalities: ['image', 'text'],
74
+ }
75
+ })
76
+
77
+ const parts = response.candidates?.[0]?.content?.parts || []
78
+ const imagePart = parts.find(p => p.inlineData?.mimeType?.startsWith('image/'))
79
+
80
+ if (!imagePart?.inlineData?.data) {
81
+ console.error(`Warning: No image in response ${i + 1}`)
82
+ continue
83
+ }
84
+
85
+ const ext = imagePart.inlineData.mimeType === 'image/jpeg' ? 'jpg' : 'png'
86
+ const filename = count === 1
87
+ ? `${options.name || 'image'}.${ext}`
88
+ : `${options.name || 'image'}-${i + 1}.${ext}`
89
+
90
+ const outputPath = resolve(outputDir, filename)
91
+ const buffer = Buffer.from(imagePart.inlineData.data, 'base64')
92
+ writeFileSync(outputPath, buffer)
93
+ saved.push(outputPath)
94
+ console.error(`Saved: ${outputPath}`)
95
+ }
96
+
97
+ console.error(`\nDone — ${saved.length} image(s) generated`)
98
+ }
99
+
100
+ // imagen-3.0-generate-002
101
+ async function generateWithImagen({ apiKey, model, prompt, count, outputDir, options }) {
53
102
  const ai = new GoogleGenAI({ apiKey })
54
103
 
55
104
  const config = {
@@ -57,21 +106,13 @@ async function generateWithGemini({ apiKey, prompt, count, outputDir, options })
57
106
  outputMimeType: 'image/png'
58
107
  }
59
108
 
60
- if (options.width && options.height) {
61
- config.aspectRatio = getAspectRatio(parseInt(options.width), parseInt(options.height))
62
- } else if (options.aspect) {
63
- config.aspectRatio = options.aspect
64
- }
65
-
66
- console.error(`Generating with Imagen 3...`)
109
+ if (options.aspect) config.aspectRatio = options.aspect
67
110
 
68
- const response = await ai.models.generateImages({
69
- model: IMAGEN_MODEL,
70
- prompt,
71
- config
72
- })
111
+ console.error(`Generating images...`)
73
112
 
113
+ const response = await ai.models.generateImages({ model, prompt, config })
74
114
  const images = response.generatedImages || []
115
+
75
116
  if (!images.length) {
76
117
  console.error('Error: No images generated')
77
118
  process.exit(1)
@@ -83,12 +124,11 @@ async function generateWithGemini({ apiKey, prompt, count, outputDir, options })
83
124
  if (!imageData) continue
84
125
 
85
126
  const filename = count === 1
86
- ? (options.name || 'image') + '.png'
127
+ ? `${options.name || 'image'}.png`
87
128
  : `${options.name || 'image'}-${i + 1}.png`
88
129
 
89
130
  const outputPath = resolve(outputDir, filename)
90
- const buffer = Buffer.from(imageData, 'base64')
91
- writeFileSync(outputPath, buffer)
131
+ writeFileSync(outputPath, Buffer.from(imageData, 'base64'))
92
132
  saved.push(outputPath)
93
133
  console.error(`Saved: ${outputPath}`)
94
134
  }
@@ -98,13 +138,11 @@ async function generateWithGemini({ apiKey, prompt, count, outputDir, options })
98
138
 
99
139
  async function generateWithOpenAI({ apiKey, prompt, count, outputDir, options }) {
100
140
  const client = new OpenAI({ apiKey })
101
-
102
141
  const size = options.size || '1024x1024'
103
142
  const quality = options.quality || 'standard'
104
143
 
105
- console.error(`Generating with DALL-E 3...`)
144
+ console.error(`Generating images...`)
106
145
 
107
- // DALL-E 3 only supports n=1 at a time
108
146
  const saved = []
109
147
  for (let i = 0; i < count; i++) {
110
148
  const response = await client.images.generate({
@@ -120,24 +158,14 @@ async function generateWithOpenAI({ apiKey, prompt, count, outputDir, options })
120
158
  if (!imageData) continue
121
159
 
122
160
  const filename = count === 1
123
- ? (options.name || 'image') + '.png'
161
+ ? `${options.name || 'image'}.png`
124
162
  : `${options.name || 'image'}-${i + 1}.png`
125
163
 
126
164
  const outputPath = resolve(outputDir, filename)
127
- const buffer = Buffer.from(imageData, 'base64')
128
- writeFileSync(outputPath, buffer)
165
+ writeFileSync(outputPath, Buffer.from(imageData, 'base64'))
129
166
  saved.push(outputPath)
130
167
  console.error(`Saved: ${outputPath}`)
131
168
  }
132
169
 
133
170
  console.error(`\nDone — ${saved.length} image(s) generated`)
134
171
  }
135
-
136
- function getAspectRatio(width, height) {
137
- const ratio = width / height
138
- if (ratio >= 1.7) return '16:9'
139
- if (ratio >= 1.3) return '4:3'
140
- if (ratio >= 0.95) return '1:1'
141
- if (ratio >= 0.7) return '3:4'
142
- return '9:16'
143
- }