@su-record/vibe 2.6.3 → 2.6.5

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/README.md CHANGED
@@ -43,7 +43,9 @@ vibe init
43
43
  | `/vibe.review` | 13+ agent parallel review |
44
44
  | `/vibe.analyze` | Code analysis |
45
45
  | `/vibe.reason "problem"` | Systematic reasoning |
46
- | `/vibe.utils` | Utilities (--e2e, --diagram, etc.) |
46
+ | `/vibe.utils --ui` | UI preview (Gemini image / ASCII fallback) |
47
+ | `/vibe.utils --ui-sync` | Sync design files to code (v2.6.3) |
48
+ | `/vibe.utils --e2e` | E2E testing, diagrams, etc. |
47
49
 
48
50
  ## Workflow
49
51
 
@@ -211,6 +213,44 @@ await generateChangelog('feature-name');
211
213
  - Automatic changelog generation
212
214
  - Baseline tagging for releases
213
215
 
216
+ ## UI Design Tools (v2.6.3)
217
+
218
+ ### UI Preview (`--ui`)
219
+
220
+ Generate UI previews from text description or design folder:
221
+
222
+ ```bash
223
+ /vibe.utils --ui "login form with email/password"
224
+ /vibe.utils --ui ./design/dashboard/
225
+ ```
226
+
227
+ **Features:**
228
+
229
+ - **Gemini enabled**: Generates actual UI mockup image
230
+ - **Gemini disabled**: ASCII art fallback
231
+ - Supports: HTML, PNG, JPG, CSS, JSON, SVG, MD
232
+
233
+ ### Design-to-Code Sync (`--ui-sync`)
234
+
235
+ Sync design files to existing UI code:
236
+
237
+ ```bash
238
+ /vibe.utils --ui-sync ./design/ui/
239
+ ```
240
+
241
+ **Workflow:**
242
+
243
+ 1. Read all design files (HTML, images, CSS, tokens)
244
+ 2. Extract design specs (colors, typography, spacing)
245
+ 3. Compare with existing code
246
+ 4. Generate update plan
247
+ 5. Apply changes (with confirmation)
248
+
249
+ **Mode:**
250
+
251
+ - **Gemini enabled**: Gemini generates code from design
252
+ - **Gemini disabled**: Claude handles analysis and generation
253
+
214
254
  ## Multi-model Orchestration
215
255
 
216
256
  **Hook-based automatic routing** - Keywords in your prompt trigger the right LLM automatically:
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Sync UI code with design files
2
+ description: Sync UI code with design files (Gemini or Claude)
3
3
  argument-hint: "design folder path"
4
4
  ---
5
5
 
@@ -7,6 +7,9 @@ argument-hint: "design folder path"
7
7
 
8
8
  Analyze design files and update existing UI code to match.
9
9
 
10
+ - **Gemini enabled**: Gemini analyzes designs and generates code
11
+ - **Gemini disabled**: Claude handles directly
12
+
10
13
  ## Usage
11
14
 
12
15
  ```
@@ -17,11 +20,88 @@ Analyze design files and update existing UI code to match.
17
20
 
18
21
  ## Process
19
22
 
20
- ### 1. Read ALL Design Files
23
+ ### 0. Check Gemini Status
21
24
 
22
- **MANDATORY: Read every file in the design folder.**
25
+ **FIRST: Check if Gemini is available.**
26
+
27
+ ```bash
28
+ vibe gemini status
29
+ ```
23
30
 
24
- Scan folder and read ALL supported files:
31
+ Or check: `~/.config/vibe/gemini.json` or `~/.config/vibe/gemini-apikey.json`
32
+
33
+ - **Gemini available** → Use Gemini for code generation (Step 1A)
34
+ - **Gemini NOT available** → Claude handles directly (Step 1B)
35
+
36
+ ---
37
+
38
+ ## Path A: Gemini Enabled
39
+
40
+ ### 1A. Collect ALL Design Files
41
+
42
+ Scan folder and collect all files to send to Gemini:
43
+
44
+ | Format | What to Collect |
45
+ | ------ | --------------- |
46
+ | `*.html` | Full HTML content |
47
+ | `*.png` / `*.jpg` / `*.webp` | Image as base64 |
48
+ | `*.json` | Design tokens, theme config |
49
+ | `*.css` / `*.scss` | Style variables |
50
+ | `*.md` | Design guidelines |
51
+ | `*.svg` | Vector content |
52
+
53
+ ### 2A. Send to Gemini
54
+
55
+ Use the Gemini UI Generator script:
56
+
57
+ ```bash
58
+ node hooks/scripts/gemini-ui-gen.js \
59
+ --design-folder ./design/ui/ \
60
+ --framework react \
61
+ --output ./src/components
62
+ ```
63
+
64
+ **Or call Gemini API directly with all files:**
65
+
66
+ ```javascript
67
+ // Prepare multipart content
68
+ const parts = [
69
+ // Images as inline data
70
+ { inlineData: { mimeType: "image/png", data: imageBase64 } },
71
+ // HTML/CSS/JSON as text
72
+ { text: `HTML Mockup:\n${htmlContent}` },
73
+ { text: `CSS Styles:\n${cssContent}` },
74
+ { text: `Design Tokens:\n${jsonContent}` },
75
+ // Prompt
76
+ { text: `
77
+ Analyze these design files and generate production-ready React components.
78
+
79
+ Requirements:
80
+ 1. Match the visual design exactly
81
+ 2. Use Tailwind CSS
82
+ 3. TypeScript with proper types
83
+ 4. Responsive and accessible
84
+
85
+ Output complete component code.
86
+ ` }
87
+ ];
88
+ ```
89
+
90
+ ### 3A. Apply Gemini's Output
91
+
92
+ 1. Parse Gemini's code output
93
+ 2. Extract component files
94
+ 3. Compare with existing code
95
+ 4. Show diff to user
96
+ 5. Apply with confirmation
97
+
98
+ ---
99
+
100
+ ## Path B: Gemini NOT Available (Claude Fallback)
101
+
102
+ ### 1B. Read ALL Design Files
103
+
104
+ **MANDATORY: Read every file in the design folder.**
25
105
 
26
106
  | Format | What to Extract |
27
107
  | ------ | --------------- |
@@ -42,7 +122,7 @@ Scan folder and read ALL supported files:
42
122
 
43
123
  **CRITICAL:** Do NOT skip any file. Read images with the Read tool.
44
124
 
45
- ### 2. Analyze Design Intent
125
+ ### 2B. Analyze Design Intent (Claude)
46
126
 
47
127
  From all design files, extract:
48
128
 
@@ -63,12 +143,15 @@ From all design files, extract:
63
143
  - Border radius, shadows
64
144
  - Dark/light theme support
65
145
 
66
- **Interactions:**
67
- - Button states (hover, active, disabled)
68
- - Form validation styles
69
- - Animations/transitions
146
+ ### 3B. Generate Code (Claude)
147
+
148
+ Claude generates the code directly based on analysis.
149
+
150
+ ---
151
+
152
+ ## Common Steps (Both Paths)
70
153
 
71
- ### 3. Find Existing UI Code
154
+ ### 4. Find Existing UI Code
72
155
 
73
156
  Search for existing UI implementation:
74
157
 
@@ -87,7 +170,7 @@ Detect framework:
87
170
  - Svelte: `*.svelte`
88
171
  - Angular: `*.component.ts`
89
172
 
90
- ### 4. Compare Design vs Code
173
+ ### 5. Compare Design vs Code
91
174
 
92
175
  Create a diff report:
93
176
 
@@ -98,7 +181,7 @@ Create a diff report:
98
181
  | Border radius | 12px | 8px | Update |
99
182
  | Component X | Exists | Missing | Create |
100
183
 
101
- ### 5. Generate Update Plan
184
+ ### 6. Generate Update Plan
102
185
 
103
186
  List all changes needed:
104
187
 
@@ -125,7 +208,7 @@ List all changes needed:
125
208
  **New Components:**
126
209
  - List components that exist in design but not in code
127
210
 
128
- ### 6. Execute Updates
211
+ ### 7. Execute Updates
129
212
 
130
213
  **Ask user before making changes:**
131
214
 
@@ -147,7 +230,7 @@ Proceed with updates? [Y/n]
147
230
  4. Create new components (if needed)
148
231
  5. Update imports
149
232
 
150
- ### 7. Verify Changes
233
+ ### 8. Verify Changes
151
234
 
152
235
  After updates:
153
236
 
@@ -159,6 +242,7 @@ After updates:
159
242
 
160
243
  ```
161
244
  📂 Design Analysis: ./design/ui/
245
+ 🤖 Mode: Gemini (or Claude fallback)
162
246
 
163
247
  Files Read:
164
248
  ✓ homepage.html (structure)
@@ -190,34 +274,33 @@ Apply changes? [Y/n]
190
274
  Next: Run `npm run build` to verify
191
275
  ```
192
276
 
193
- ## Example
277
+ ## Example (with Gemini)
194
278
 
195
279
  ```
196
280
  User: /vibe.utils --ui-sync ./design/dashboard/
197
281
 
198
- Claude: Reading design folder...
282
+ Claude: Checking Gemini status...
283
+ ✅ Gemini: OAuth authenticated (user@example.com)
199
284
 
200
- 📂 Files found:
285
+ 📂 Collecting design files...
201
286
  - dashboard.html
202
287
  - dashboard-dark.png
203
288
  - dashboard-light.png
204
289
  - tokens.json
205
290
  - components.md
206
291
 
207
- Reading dashboard.html...
208
- [Extracts: header, sidebar, 3-column grid, card components]
292
+ 🤖 Sending to Gemini for analysis...
209
293
 
210
- Reading dashboard-dark.png...
211
- [Analyzes: dark theme colors, spacing, typography]
294
+ Gemini Response:
295
+ Layout: Header + Sidebar + 3-column main
296
+ Theme: Dark (#0F172A bg, #F8FAFC text)
297
+ Components: Header, Sidebar, StatCard, DataTable
212
298
 
213
- Reading tokens.json...
214
- [Extracts: color palette, spacing scale, typography scale]
215
-
216
- 📊 Design Analysis Complete:
217
-
218
- Layout: Header + Sidebar + 3-column main
219
- Theme: Dark (#0F172A bg, #F8FAFC text)
220
- Components: Header, Sidebar, StatCard, DataTable
299
+ Generated code:
300
+ - Header.tsx (64 lines)
301
+ - Sidebar.tsx (45 lines)
302
+ - StatCard.tsx (32 lines)
303
+ - DataTable.tsx (78 lines)
221
304
 
222
305
  🔍 Comparing with existing code...
223
306
 
@@ -228,31 +311,48 @@ Missing: src/components/DataTable.tsx
228
311
  Differences:
229
312
  1. StatCard border-radius: design=16px, code=8px
230
313
  2. Sidebar width: design=240px, code=200px
231
- 3. Header height: design=64px, code=56px
232
- 4. Primary color: design=#6366F1, code=#3B82F6
233
- 5. DataTable component: missing
314
+ 3. Primary color: design=#6366F1, code=#3B82F6
315
+ 4. DataTable component: missing
316
+
317
+ Apply 3 updates + create 1 component? [Y/n]
318
+ ```
234
319
 
235
- Apply 4 updates + create 1 component? [Y/n]
320
+ ## Example (Claude Fallback)
236
321
 
237
- User: Y
322
+ ```
323
+ User: /vibe.utils --ui-sync ./design/dashboard/
238
324
 
239
- Changes applied:
240
- - src/components/StatCard.tsx (border-radius)
241
- - src/components/Sidebar.tsx (width)
242
- - src/components/Header.tsx (height)
243
- - tailwind.config.js (primary color)
244
- - src/components/DataTable.tsx (created)
325
+ Claude: Checking Gemini status...
326
+ ⚠️ Gemini not configured. Using Claude fallback.
245
327
 
246
- Run `npm run dev` to preview changes.
328
+ 📂 Reading design files...
329
+
330
+ Reading dashboard.html...
331
+ [Extracts: header, sidebar, 3-column grid]
332
+
333
+ Reading dashboard-dark.png...
334
+ [Analyzes: dark theme colors, spacing]
335
+
336
+ Reading tokens.json...
337
+ [Extracts: color palette, spacing scale]
338
+
339
+ 📊 Design Analysis Complete (Claude):
340
+
341
+ Layout: Header + Sidebar + 3-column main
342
+ Theme: Dark (#0F172A bg, #F8FAFC text)
343
+
344
+ 🔍 Comparing with existing code...
345
+ ...
247
346
  ```
248
347
 
249
348
  ## Notes
250
349
 
350
+ - Always check Gemini status first
351
+ - Gemini handles image analysis better than Claude for visual matching
352
+ - Claude fallback works but may be less accurate for complex visuals
251
353
  - Always read ALL files including images
252
354
  - Ask for confirmation before making changes
253
355
  - Preserve existing functionality while updating styles
254
- - Create backup recommendation for large changes
255
- - Support both CSS-in-JS and traditional CSS
256
356
 
257
357
  ---
258
358
 
@@ -433,35 +433,35 @@ export async function vibeGeminiOrchestrate(prompt, systemPrompt, options = {})
433
433
  * Vibe Spec 파싱 (Vibe Spec → 실행 계획)
434
434
  */
435
435
  export async function vibeGeminiParseSpec(spec) {
436
- return vibeGeminiOrchestrate(spec, `You are a Vibe Spec parser. Parse the given specification and output a structured execution plan.
436
+ return vibeGeminiOrchestrate(spec, `You are a Vibe Spec parser. Parse the given specification and output a structured execution plan.
437
437
  Output format: { "phases": [...], "files": [...], "dependencies": [...] }`);
438
438
  }
439
439
  /**
440
440
  * Vibe 실행 계획 수립 (Task → Steps)
441
441
  */
442
442
  export async function vibeGeminiPlanExecution(task, context) {
443
- return vibeGeminiOrchestrate(`Task: ${task}\n\nContext:\n${context}`, `You are a Vibe execution planner. Given a task and context, create a step-by-step execution plan.
443
+ return vibeGeminiOrchestrate(`Task: ${task}\n\nContext:\n${context}`, `You are a Vibe execution planner. Given a task and context, create a step-by-step execution plan.
444
444
  Output format: { "steps": [{ "id": 1, "action": "...", "target": "...", "expected": "..." }], "estimatedComplexity": "low|medium|high" }`);
445
445
  }
446
446
  /**
447
447
  * Vibe 코드 분석 (빠른 구조 분석)
448
448
  */
449
449
  export async function vibeGeminiAnalyze(code, question) {
450
- return vibeGeminiOrchestrate(`Code:\n\`\`\`\n${code}\n\`\`\`\n\nQuestion: ${question}`, `You are a code analyzer. Answer the question about the given code concisely.
450
+ return vibeGeminiOrchestrate(`Code:\n\`\`\`\n${code}\n\`\`\`\n\nQuestion: ${question}`, `You are a code analyzer. Answer the question about the given code concisely.
451
451
  Output format: { "answer": "...", "confidence": 0.0-1.0, "relatedSymbols": [...] }`);
452
452
  }
453
453
  /**
454
454
  * Vibe 다음 액션 결정 (상태 기반)
455
455
  */
456
456
  export async function vibeGeminiDecideNextAction(currentState, availableActions, goal) {
457
- return vibeGeminiOrchestrate(`Current State:\n${currentState}\n\nAvailable Actions:\n${availableActions.join('\n')}\n\nGoal: ${goal}`, `You are an action decider. Based on the current state and goal, select the best next action.
457
+ return vibeGeminiOrchestrate(`Current State:\n${currentState}\n\nAvailable Actions:\n${availableActions.join('\n')}\n\nGoal: ${goal}`, `You are an action decider. Based on the current state and goal, select the best next action.
458
458
  Output format: { "selectedAction": "...", "reason": "...", "parameters": {} }`);
459
459
  }
460
460
  /**
461
461
  * Vibe UI/UX 분석 (검색 없이 내부 지식으로)
462
462
  */
463
463
  export async function vibeGeminiAnalyzeUX(description) {
464
- return vibeGeminiOrchestrate(description, `You are a UI/UX expert. Analyze the given design description and provide structured feedback.
464
+ return vibeGeminiOrchestrate(description, `You are a UI/UX expert. Analyze the given design description and provide structured feedback.
465
465
  Output format: { "issues": [...], "suggestions": [...], "accessibility": { "score": 0-100, "concerns": [...] } }`, { jsonMode: true });
466
466
  }
467
467
  //# sourceMappingURL=gemini-api.js.map
@@ -0,0 +1,293 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Gemini UI Code Generator
5
+ *
6
+ * 디자인 파일(이미지, HTML 등)을 분석해서 UI 코드를 생성합니다.
7
+ * 기존 gemini-api 인프라 사용.
8
+ *
9
+ * Usage:
10
+ * node gemini-ui-gen.js --image ./design.png --framework react --output ./src/components
11
+ * node gemini-ui-gen.js --html ./mockup.html --framework vue --output ./src/components
12
+ * node gemini-ui-gen.js --design-folder ./design/ --framework react --output ./src
13
+ */
14
+
15
+ import fs from 'fs';
16
+ import path from 'path';
17
+ import { getLibBaseUrl } from './utils.js';
18
+
19
+ const LIB_URL = getLibBaseUrl();
20
+
21
+ // ============================================
22
+ // Gemini API (기존 인프라 사용)
23
+ // ============================================
24
+
25
+ let geminiApi = null;
26
+
27
+ async function getGeminiApi() {
28
+ if (!geminiApi) {
29
+ geminiApi = await import(`${LIB_URL}gemini-api.js`);
30
+ }
31
+ return geminiApi;
32
+ }
33
+
34
+ async function getGeminiStatus() {
35
+ const api = await getGeminiApi();
36
+ return api.vibeGeminiStatus ? await api.vibeGeminiStatus() : null;
37
+ }
38
+
39
+ async function askGemini(prompt) {
40
+ const api = await getGeminiApi();
41
+ return api.ask(prompt, { model: 'gemini-3-flash', maxTokens: 8192, temperature: 0.3 });
42
+ }
43
+
44
+ // ============================================
45
+ // UI Code Generation
46
+ // ============================================
47
+
48
+ function getFrameworkPrompt(framework) {
49
+ const prompts = {
50
+ react: `Generate React TypeScript components using:
51
+ - Functional components with hooks
52
+ - Tailwind CSS for styling
53
+ - Proper TypeScript types/interfaces
54
+ - Export as default`,
55
+
56
+ vue: `Generate Vue 3 components using:
57
+ - Composition API with <script setup>
58
+ - Tailwind CSS for styling
59
+ - TypeScript support
60
+ - Single File Component format`,
61
+
62
+ svelte: `Generate Svelte components using:
63
+ - Svelte 5 runes syntax
64
+ - Tailwind CSS for styling
65
+ - TypeScript support`,
66
+
67
+ html: `Generate semantic HTML5 with:
68
+ - Tailwind CSS classes
69
+ - Accessible markup
70
+ - Responsive design`,
71
+ };
72
+
73
+ return prompts[framework] || prompts.react;
74
+ }
75
+
76
+ async function generateUIFromImage(imagePath, framework) {
77
+ const imageBuffer = fs.readFileSync(imagePath);
78
+ const imageBase64 = imageBuffer.toString('base64');
79
+
80
+ const ext = path.extname(imagePath).toLowerCase();
81
+ const mimeTypes = {
82
+ '.png': 'image/png',
83
+ '.jpg': 'image/jpeg',
84
+ '.jpeg': 'image/jpeg',
85
+ '.webp': 'image/webp',
86
+ '.gif': 'image/gif',
87
+ };
88
+ const mimeType = mimeTypes[ext] || 'image/png';
89
+
90
+ const prompt = `[Image attached as base64: ${mimeType}]
91
+ data:${mimeType};base64,${imageBase64}
92
+
93
+ Analyze this UI design image and generate production-ready code.
94
+
95
+ ${getFrameworkPrompt(framework)}
96
+
97
+ Requirements:
98
+ 1. Match the visual design exactly (colors, spacing, typography, layout)
99
+ 2. Extract exact colors as hex values
100
+ 3. Use proper semantic HTML structure
101
+ 4. Make it responsive (mobile-first)
102
+ 5. Include hover/focus states where appropriate
103
+ 6. Add appropriate accessibility attributes
104
+
105
+ Output format:
106
+ \`\`\`${framework === 'html' ? 'html' : 'tsx'}
107
+ // Component code here
108
+ \`\`\`
109
+
110
+ Also provide a summary of:
111
+ - Colors extracted
112
+ - Components identified
113
+ - Layout structure`;
114
+
115
+ return askGemini(prompt);
116
+ }
117
+
118
+ async function generateUIFromHTML(htmlPath, framework) {
119
+ const htmlContent = fs.readFileSync(htmlPath, 'utf-8');
120
+
121
+ const prompt = `Convert this HTML mockup to production-ready ${framework} code.
122
+
123
+ HTML Mockup:
124
+ \`\`\`html
125
+ ${htmlContent}
126
+ \`\`\`
127
+
128
+ ${getFrameworkPrompt(framework)}
129
+
130
+ Requirements:
131
+ 1. Preserve the exact visual appearance
132
+ 2. Extract inline styles to Tailwind classes
133
+ 3. Create reusable components where appropriate
134
+ 4. Add proper TypeScript types
135
+ 5. Make it responsive
136
+
137
+ Output the converted code in proper format.`;
138
+
139
+ return askGemini(prompt);
140
+ }
141
+
142
+ async function analyzeDesignFolder(folderPath, framework) {
143
+ const files = fs.readdirSync(folderPath);
144
+ let combinedPrompt = `Analyze the following design files and generate production-ready ${framework} code.\n\n`;
145
+
146
+ for (const file of files) {
147
+ const filePath = path.join(folderPath, file);
148
+ const ext = path.extname(file).toLowerCase();
149
+
150
+ if (['.png', '.jpg', '.jpeg', '.webp', '.gif'].includes(ext)) {
151
+ const imageBuffer = fs.readFileSync(filePath);
152
+ const imageBase64 = imageBuffer.toString('base64');
153
+ const mimeType = ext === '.png' ? 'image/png' : ext === '.webp' ? 'image/webp' : 'image/jpeg';
154
+ combinedPrompt += `\n--- Image: ${file} ---\ndata:${mimeType};base64,${imageBase64}\n`;
155
+ console.log(`📷 ${file}`);
156
+ } else if (ext === '.html') {
157
+ const content = fs.readFileSync(filePath, 'utf-8');
158
+ combinedPrompt += `\n--- HTML: ${file} ---\n${content}\n`;
159
+ console.log(`📄 ${file}`);
160
+ } else if (ext === '.json') {
161
+ const content = fs.readFileSync(filePath, 'utf-8');
162
+ combinedPrompt += `\n--- Design Tokens: ${file} ---\n${content}\n`;
163
+ console.log(`📋 ${file}`);
164
+ } else if (['.css', '.scss'].includes(ext)) {
165
+ const content = fs.readFileSync(filePath, 'utf-8');
166
+ combinedPrompt += `\n--- Styles: ${file} ---\n${content}\n`;
167
+ console.log(`🎨 ${file}`);
168
+ } else if (ext === '.md') {
169
+ const content = fs.readFileSync(filePath, 'utf-8');
170
+ combinedPrompt += `\n--- Guide: ${file} ---\n${content}\n`;
171
+ console.log(`📝 ${file}`);
172
+ }
173
+ }
174
+
175
+ combinedPrompt += `\n${getFrameworkPrompt(framework)}
176
+
177
+ Requirements:
178
+ 1. Match the visual design exactly
179
+ 2. Extract design tokens from JSON if provided
180
+ 3. Use CSS variables from stylesheets if provided
181
+ 4. Create separate component files for each major UI section
182
+ 5. Make it responsive (mobile-first)
183
+ 6. Include accessibility attributes
184
+
185
+ Output complete component code.`;
186
+
187
+ return askGemini(combinedPrompt);
188
+ }
189
+
190
+ // ============================================
191
+ // CLI
192
+ // ============================================
193
+
194
+ async function main() {
195
+ const args = process.argv.slice(2);
196
+
197
+ const options = {
198
+ image: null,
199
+ html: null,
200
+ designFolder: null,
201
+ framework: 'react',
202
+ output: './generated',
203
+ };
204
+
205
+ for (let i = 0; i < args.length; i++) {
206
+ switch (args[i]) {
207
+ case '--image':
208
+ options.image = args[++i];
209
+ break;
210
+ case '--html':
211
+ options.html = args[++i];
212
+ break;
213
+ case '--design-folder':
214
+ case '--folder':
215
+ options.designFolder = args[++i];
216
+ break;
217
+ case '--framework':
218
+ case '-f':
219
+ options.framework = args[++i];
220
+ break;
221
+ case '--output':
222
+ case '-o':
223
+ options.output = args[++i];
224
+ break;
225
+ case '--help':
226
+ case '-h':
227
+ console.log(`
228
+ Gemini UI Code Generator
229
+
230
+ Usage:
231
+ node gemini-ui-gen.js --image ./design.png --framework react
232
+ node gemini-ui-gen.js --html ./mockup.html --framework vue
233
+ node gemini-ui-gen.js --design-folder ./design/ --framework react
234
+
235
+ Options:
236
+ --image <path> Image file to analyze
237
+ --html <path> HTML mockup to convert
238
+ --design-folder <path> Folder with design files
239
+ --framework <name> Target framework (react, vue, svelte, html)
240
+ --output <path> Output directory
241
+ --help Show this help
242
+ `);
243
+ process.exit(0);
244
+ }
245
+ }
246
+
247
+ // Check Gemini status
248
+ const status = await getGeminiStatus();
249
+ if (!status) {
250
+ console.error('❌ Gemini credentials not found. Run: vibe gemini auth');
251
+ process.exit(1);
252
+ }
253
+
254
+ console.log(`🤖 Gemini UI Generator (${status.type}${status.email ? `: ${status.email}` : ''})`);
255
+ console.log(`📦 Framework: ${options.framework}`);
256
+
257
+ try {
258
+ let result;
259
+
260
+ if (options.image) {
261
+ console.log(`\n📷 Analyzing: ${options.image}\n`);
262
+ result = await generateUIFromImage(options.image, options.framework);
263
+ } else if (options.html) {
264
+ console.log(`\n📄 Converting: ${options.html}\n`);
265
+ result = await generateUIFromHTML(options.html, options.framework);
266
+ } else if (options.designFolder) {
267
+ console.log(`\n📂 Analyzing folder: ${options.designFolder}\n`);
268
+ result = await analyzeDesignFolder(options.designFolder, options.framework);
269
+ } else {
270
+ console.error('❌ No input specified. Use --image, --html, or --design-folder');
271
+ process.exit(1);
272
+ }
273
+
274
+ console.log('\n' + '='.repeat(60) + '\n');
275
+ console.log(result);
276
+ console.log('\n' + '='.repeat(60));
277
+
278
+ if (options.output && result) {
279
+ if (!fs.existsSync(options.output)) {
280
+ fs.mkdirSync(options.output, { recursive: true });
281
+ }
282
+ const outputFile = path.join(options.output, `generated-${Date.now()}.txt`);
283
+ fs.writeFileSync(outputFile, result);
284
+ console.log(`\n✅ Output saved to: ${outputFile}`);
285
+ }
286
+
287
+ } catch (error) {
288
+ console.error(`\n❌ Error: ${error.message}`);
289
+ process.exit(1);
290
+ }
291
+ }
292
+
293
+ main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@su-record/vibe",
3
- "version": "2.6.3",
3
+ "version": "2.6.5",
4
4
  "description": "Vibe - Claude Code exclusive SPEC-driven AI coding framework with 35+ integrated tools",
5
5
  "type": "module",
6
6
  "main": "dist/cli/index.js",