@su-record/vibe 2.6.13 ā 2.6.15
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/LICENSE +21 -21
- package/README.md +497 -497
- package/agents/architect-low.md +41 -41
- package/agents/architect-medium.md +59 -59
- package/agents/architect.md +80 -80
- package/agents/build-error-resolver.md +115 -115
- package/agents/compounder.md +261 -261
- package/agents/diagrammer.md +178 -178
- package/agents/e2e-tester.md +266 -266
- package/agents/explorer-low.md +42 -42
- package/agents/explorer-medium.md +59 -59
- package/agents/explorer.md +48 -48
- package/agents/implementer-low.md +43 -43
- package/agents/implementer-medium.md +52 -52
- package/agents/implementer.md +54 -54
- package/agents/refactor-cleaner.md +143 -143
- package/agents/research/best-practices-agent.md +199 -199
- package/agents/research/codebase-patterns-agent.md +157 -157
- package/agents/research/framework-docs-agent.md +188 -188
- package/agents/research/security-advisory-agent.md +213 -213
- package/agents/review/architecture-reviewer.md +107 -107
- package/agents/review/complexity-reviewer.md +116 -116
- package/agents/review/data-integrity-reviewer.md +88 -88
- package/agents/review/git-history-reviewer.md +103 -103
- package/agents/review/performance-reviewer.md +86 -86
- package/agents/review/python-reviewer.md +150 -150
- package/agents/review/rails-reviewer.md +139 -139
- package/agents/review/react-reviewer.md +144 -144
- package/agents/review/security-reviewer.md +80 -80
- package/agents/review/simplicity-reviewer.md +140 -140
- package/agents/review/test-coverage-reviewer.md +116 -116
- package/agents/review/typescript-reviewer.md +127 -127
- package/agents/searcher.md +54 -54
- package/agents/simplifier.md +120 -120
- package/agents/tester.md +49 -49
- package/agents/ui-previewer.md +268 -268
- package/commands/vibe.analyze.md +356 -356
- package/commands/vibe.reason.md +329 -329
- package/commands/vibe.review.md +412 -412
- package/commands/vibe.run.md +1266 -1266
- package/commands/vibe.spec.md +1054 -1054
- package/commands/vibe.spec.review.md +319 -319
- package/commands/vibe.trace.md +161 -161
- package/commands/vibe.utils.md +376 -376
- package/commands/vibe.verify.md +375 -375
- package/dist/cli/collaborator.js +52 -52
- package/dist/cli/detect.d.ts.map +1 -1
- package/dist/cli/detect.js +118 -44
- package/dist/cli/detect.js.map +1 -1
- package/dist/cli/hud.js +20 -20
- package/dist/cli/index.js +118 -118
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/llm.js +144 -144
- package/dist/cli/mcp.d.ts +49 -0
- package/dist/cli/mcp.d.ts.map +1 -0
- package/dist/cli/mcp.js +169 -0
- package/dist/cli/mcp.js.map +1 -0
- package/dist/cli/postinstall.js +858 -858
- package/dist/cli/setup/ProjectSetup.d.ts +3 -0
- package/dist/cli/setup/ProjectSetup.d.ts.map +1 -1
- package/dist/cli/setup/ProjectSetup.js +28 -6
- package/dist/cli/setup/ProjectSetup.js.map +1 -1
- package/dist/lib/DeepInit.js +24 -24
- package/dist/lib/IterationTracker.js +11 -11
- package/dist/lib/PythonParser.js +108 -108
- package/dist/lib/ReviewRace.js +96 -96
- package/dist/lib/SkillFrontmatter.js +28 -28
- package/dist/lib/SkillQualityGate.js +9 -9
- package/dist/lib/SkillRepository.js +159 -159
- package/dist/lib/UltraQA.js +77 -77
- package/dist/lib/gemini-api.js +5 -5
- package/dist/lib/gemini-mcp.d.ts +10 -0
- package/dist/lib/gemini-mcp.d.ts.map +1 -0
- package/dist/lib/gemini-mcp.js +353 -0
- package/dist/lib/gemini-mcp.js.map +1 -0
- package/dist/lib/gpt-api.js +4 -4
- package/dist/lib/gpt-mcp.d.ts +10 -0
- package/dist/lib/gpt-mcp.d.ts.map +1 -0
- package/dist/lib/gpt-mcp.js +352 -0
- package/dist/lib/gpt-mcp.js.map +1 -0
- package/dist/lib/memory/KnowledgeGraph.js +4 -4
- package/dist/lib/memory/MemorySearch.js +20 -20
- package/dist/lib/memory/MemoryStorage.js +64 -64
- package/dist/orchestrator/AgentManager.js +12 -12
- package/dist/orchestrator/MultiLlmResearch.js +8 -8
- package/dist/orchestrator/SmartRouter.js +11 -11
- package/dist/orchestrator/parallelResearch.js +24 -24
- package/dist/tools/analytics/getUsageAnalytics.d.ts +10 -0
- package/dist/tools/analytics/getUsageAnalytics.d.ts.map +1 -0
- package/dist/tools/analytics/getUsageAnalytics.js +246 -0
- package/dist/tools/analytics/getUsageAnalytics.js.map +1 -0
- package/dist/tools/analytics/index.d.ts +5 -0
- package/dist/tools/analytics/index.d.ts.map +1 -0
- package/dist/tools/analytics/index.js +5 -0
- package/dist/tools/analytics/index.js.map +1 -0
- package/dist/tools/convention/analyzeComplexity.test.js +115 -115
- package/dist/tools/convention/getCodingGuide.d.ts +7 -0
- package/dist/tools/convention/getCodingGuide.d.ts.map +1 -0
- package/dist/tools/convention/getCodingGuide.js +69 -0
- package/dist/tools/convention/getCodingGuide.js.map +1 -0
- package/dist/tools/convention/validateCodeQuality.test.js +104 -104
- package/dist/tools/planning/analyzeRequirements.d.ts +9 -0
- package/dist/tools/planning/analyzeRequirements.d.ts.map +1 -0
- package/dist/tools/planning/analyzeRequirements.js +171 -0
- package/dist/tools/planning/analyzeRequirements.js.map +1 -0
- package/dist/tools/planning/createUserStories.d.ts +9 -0
- package/dist/tools/planning/createUserStories.d.ts.map +1 -0
- package/dist/tools/planning/createUserStories.js +124 -0
- package/dist/tools/planning/createUserStories.js.map +1 -0
- package/dist/tools/planning/featureRoadmap.d.ts +10 -0
- package/dist/tools/planning/featureRoadmap.d.ts.map +1 -0
- package/dist/tools/planning/featureRoadmap.js +207 -0
- package/dist/tools/planning/featureRoadmap.js.map +1 -0
- package/dist/tools/planning/generatePrd.d.ts +11 -0
- package/dist/tools/planning/generatePrd.d.ts.map +1 -0
- package/dist/tools/planning/generatePrd.js +161 -0
- package/dist/tools/planning/generatePrd.js.map +1 -0
- package/dist/tools/planning/index.d.ts +8 -0
- package/dist/tools/planning/index.d.ts.map +1 -0
- package/dist/tools/planning/index.js +8 -0
- package/dist/tools/planning/index.js.map +1 -0
- package/dist/tools/prompt/analyzePrompt.d.ts +7 -0
- package/dist/tools/prompt/analyzePrompt.d.ts.map +1 -0
- package/dist/tools/prompt/analyzePrompt.js +150 -0
- package/dist/tools/prompt/analyzePrompt.js.map +1 -0
- package/dist/tools/prompt/enhancePrompt.d.ts +8 -0
- package/dist/tools/prompt/enhancePrompt.d.ts.map +1 -0
- package/dist/tools/prompt/enhancePrompt.js +110 -0
- package/dist/tools/prompt/enhancePrompt.js.map +1 -0
- package/dist/tools/prompt/enhancePromptGemini.d.ts +8 -0
- package/dist/tools/prompt/enhancePromptGemini.d.ts.map +1 -0
- package/dist/tools/prompt/enhancePromptGemini.js +332 -0
- package/dist/tools/prompt/enhancePromptGemini.js.map +1 -0
- package/dist/tools/prompt/index.d.ts +7 -0
- package/dist/tools/prompt/index.d.ts.map +1 -0
- package/dist/tools/prompt/index.js +7 -0
- package/dist/tools/prompt/index.js.map +1 -0
- package/dist/tools/reasoning/applyReasoningFramework.d.ts +8 -0
- package/dist/tools/reasoning/applyReasoningFramework.d.ts.map +1 -0
- package/dist/tools/reasoning/applyReasoningFramework.js +266 -0
- package/dist/tools/reasoning/applyReasoningFramework.js.map +1 -0
- package/dist/tools/reasoning/index.d.ts +5 -0
- package/dist/tools/reasoning/index.d.ts.map +1 -0
- package/dist/tools/reasoning/index.js +5 -0
- package/dist/tools/reasoning/index.js.map +1 -0
- package/dist/tools/spec/prdParser.test.js +171 -171
- package/dist/tools/spec/specGenerator.js +169 -169
- package/dist/tools/spec/traceabilityMatrix.js +64 -64
- package/dist/tools/spec/traceabilityMatrix.test.js +28 -28
- package/dist/tools/thinking/analyzeProblem.d.ts +7 -0
- package/dist/tools/thinking/analyzeProblem.d.ts.map +1 -0
- package/dist/tools/thinking/analyzeProblem.js +55 -0
- package/dist/tools/thinking/analyzeProblem.js.map +1 -0
- package/dist/tools/thinking/breakDownProblem.d.ts +8 -0
- package/dist/tools/thinking/breakDownProblem.d.ts.map +1 -0
- package/dist/tools/thinking/breakDownProblem.js +145 -0
- package/dist/tools/thinking/breakDownProblem.js.map +1 -0
- package/dist/tools/thinking/createThinkingChain.d.ts +7 -0
- package/dist/tools/thinking/createThinkingChain.d.ts.map +1 -0
- package/dist/tools/thinking/createThinkingChain.js +44 -0
- package/dist/tools/thinking/createThinkingChain.js.map +1 -0
- package/dist/tools/thinking/formatAsPlan.d.ts +9 -0
- package/dist/tools/thinking/formatAsPlan.d.ts.map +1 -0
- package/dist/tools/thinking/formatAsPlan.js +78 -0
- package/dist/tools/thinking/formatAsPlan.js.map +1 -0
- package/dist/tools/thinking/index.d.ts +10 -0
- package/dist/tools/thinking/index.d.ts.map +1 -0
- package/dist/tools/thinking/index.js +10 -0
- package/dist/tools/thinking/index.js.map +1 -0
- package/dist/tools/thinking/stepByStepAnalysis.d.ts +8 -0
- package/dist/tools/thinking/stepByStepAnalysis.d.ts.map +1 -0
- package/dist/tools/thinking/stepByStepAnalysis.js +63 -0
- package/dist/tools/thinking/stepByStepAnalysis.js.map +1 -0
- package/dist/tools/thinking/thinkAloudProcess.d.ts +8 -0
- package/dist/tools/thinking/thinkAloudProcess.d.ts.map +1 -0
- package/dist/tools/thinking/thinkAloudProcess.js +80 -0
- package/dist/tools/thinking/thinkAloudProcess.js.map +1 -0
- package/hooks/hooks.json +222 -222
- package/hooks/scripts/code-check.js +22 -22
- package/hooks/scripts/code-review.js +22 -22
- package/hooks/scripts/complexity.js +22 -22
- package/hooks/scripts/compound.js +23 -23
- package/hooks/scripts/context-save.js +33 -33
- package/hooks/scripts/gemini-ui-gen.js +281 -281
- package/hooks/scripts/generate-brand-assets.js +474 -474
- package/hooks/scripts/hud-multiline.js +262 -262
- package/hooks/scripts/hud-status.js +291 -291
- package/hooks/scripts/keyword-detector.js +214 -214
- package/hooks/scripts/llm-orchestrate.js +171 -171
- package/hooks/scripts/post-edit.js +97 -97
- package/hooks/scripts/post-tool-verify.js +210 -210
- package/hooks/scripts/pre-tool-guard.js +125 -125
- package/hooks/scripts/recall.js +22 -22
- package/hooks/scripts/session-start.js +30 -30
- package/hooks/scripts/skill-injector.js +191 -191
- package/hooks/scripts/utils.js +97 -97
- package/languages/csharp-unity.md +515 -515
- package/languages/gdscript-godot.md +470 -470
- package/languages/ruby-rails.md +489 -489
- package/languages/typescript-angular.md +433 -433
- package/languages/typescript-astro.md +416 -416
- package/languages/typescript-electron.md +406 -406
- package/languages/typescript-nestjs.md +524 -524
- package/languages/typescript-svelte.md +407 -407
- package/languages/typescript-tauri.md +365 -365
- package/package.json +84 -84
- package/skills/brand-assets.md +141 -141
- package/skills/commerce-patterns.md +361 -361
- package/skills/context7-usage.md +102 -102
- package/skills/e2e-commerce.md +304 -304
- package/skills/frontend-design.md +92 -92
- package/skills/git-worktree.md +181 -181
- package/skills/parallel-research.md +77 -77
- package/skills/priority-todos.md +239 -239
- package/skills/seo-checklist.md +244 -244
- package/skills/tool-fallback.md +190 -190
- package/skills/vibe-capabilities.md +161 -161
- package/vibe/constitution.md +227 -227
- package/vibe/rules/core/communication-guide.md +98 -98
- package/vibe/rules/core/development-philosophy.md +52 -52
- package/vibe/rules/core/quick-start.md +102 -102
- package/vibe/rules/quality/bdd-contract-testing.md +393 -393
- package/vibe/rules/quality/checklist.md +276 -276
- package/vibe/rules/quality/testing-strategy.md +440 -440
- package/vibe/rules/standards/anti-patterns.md +541 -541
- package/vibe/rules/standards/code-structure.md +291 -291
- package/vibe/rules/standards/complexity-metrics.md +313 -313
- package/vibe/rules/standards/naming-conventions.md +198 -198
- package/vibe/setup.sh +31 -31
- package/vibe/templates/constitution-template.md +252 -252
- package/vibe/templates/contract-backend-template.md +526 -526
- package/vibe/templates/contract-frontend-template.md +599 -599
- package/vibe/templates/feature-template.md +96 -96
- package/vibe/templates/spec-template.md +221 -221
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Notification Hook - 컨ķ
ģ¤ķø ģė ģ ģ„ (80/90/95%)
|
|
3
|
-
* Usage: node context-save.js <urgency>
|
|
4
|
-
* urgency: medium | high | critical
|
|
5
|
-
*/
|
|
6
|
-
import { getToolsBaseUrl, PROJECT_DIR } from './utils.js';
|
|
7
|
-
|
|
8
|
-
const BASE_URL = getToolsBaseUrl();
|
|
9
|
-
|
|
10
|
-
const urgency = process.argv[2] || 'medium';
|
|
11
|
-
const summaryMap = {
|
|
12
|
-
medium: 'Context at 80% - auto checkpoint',
|
|
13
|
-
high: 'Context at 90% - save before overflow',
|
|
14
|
-
critical: 'Context at 95% - CRITICAL save before session end',
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
async function main() {
|
|
18
|
-
try {
|
|
19
|
-
const module = await import(`${BASE_URL}memory/index.js`);
|
|
20
|
-
const result = await module.autoSaveContext({
|
|
21
|
-
urgency,
|
|
22
|
-
contextType: 'progress',
|
|
23
|
-
summary: summaryMap[urgency] || summaryMap.medium,
|
|
24
|
-
projectPath: PROJECT_DIR,
|
|
25
|
-
});
|
|
26
|
-
const percent = urgency === 'critical' ? '95' : urgency === 'high' ? '90' : '80';
|
|
27
|
-
console.log(`[CONTEXT ${percent}%]`, result.content[0].text);
|
|
28
|
-
} catch {
|
|
29
|
-
// 묓ģ
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
main();
|
|
1
|
+
/**
|
|
2
|
+
* Notification Hook - 컨ķ
ģ¤ķø ģė ģ ģ„ (80/90/95%)
|
|
3
|
+
* Usage: node context-save.js <urgency>
|
|
4
|
+
* urgency: medium | high | critical
|
|
5
|
+
*/
|
|
6
|
+
import { getToolsBaseUrl, PROJECT_DIR } from './utils.js';
|
|
7
|
+
|
|
8
|
+
const BASE_URL = getToolsBaseUrl();
|
|
9
|
+
|
|
10
|
+
const urgency = process.argv[2] || 'medium';
|
|
11
|
+
const summaryMap = {
|
|
12
|
+
medium: 'Context at 80% - auto checkpoint',
|
|
13
|
+
high: 'Context at 90% - save before overflow',
|
|
14
|
+
critical: 'Context at 95% - CRITICAL save before session end',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
async function main() {
|
|
18
|
+
try {
|
|
19
|
+
const module = await import(`${BASE_URL}memory/index.js`);
|
|
20
|
+
const result = await module.autoSaveContext({
|
|
21
|
+
urgency,
|
|
22
|
+
contextType: 'progress',
|
|
23
|
+
summary: summaryMap[urgency] || summaryMap.medium,
|
|
24
|
+
projectPath: PROJECT_DIR,
|
|
25
|
+
});
|
|
26
|
+
const percent = urgency === 'critical' ? '95' : urgency === 'high' ? '90' : '80';
|
|
27
|
+
console.log(`[CONTEXT ${percent}%]`, result.content[0].text);
|
|
28
|
+
} catch {
|
|
29
|
+
// 묓ģ
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
main();
|
|
@@ -1,281 +1,281 @@
|
|
|
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 askGemini(prompt) {
|
|
35
|
-
const api = await getGeminiApi();
|
|
36
|
-
return api.ask(prompt, { model: 'gemini-3-flash', maxTokens: 8192, temperature: 0.3 });
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// ============================================
|
|
40
|
-
// UI Code Generation
|
|
41
|
-
// ============================================
|
|
42
|
-
|
|
43
|
-
function getFrameworkPrompt(framework) {
|
|
44
|
-
const prompts = {
|
|
45
|
-
react: `Generate React TypeScript components using:
|
|
46
|
-
- Functional components with hooks
|
|
47
|
-
- Tailwind CSS for styling
|
|
48
|
-
- Proper TypeScript types/interfaces
|
|
49
|
-
- Export as default`,
|
|
50
|
-
|
|
51
|
-
vue: `Generate Vue 3 components using:
|
|
52
|
-
- Composition API with <script setup>
|
|
53
|
-
- Tailwind CSS for styling
|
|
54
|
-
- TypeScript support
|
|
55
|
-
- Single File Component format`,
|
|
56
|
-
|
|
57
|
-
svelte: `Generate Svelte components using:
|
|
58
|
-
- Svelte 5 runes syntax
|
|
59
|
-
- Tailwind CSS for styling
|
|
60
|
-
- TypeScript support`,
|
|
61
|
-
|
|
62
|
-
html: `Generate semantic HTML5 with:
|
|
63
|
-
- Tailwind CSS classes
|
|
64
|
-
- Accessible markup
|
|
65
|
-
- Responsive design`,
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
return prompts[framework] || prompts.react;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
async function generateUIFromImage(imagePath, framework) {
|
|
72
|
-
const imageBuffer = fs.readFileSync(imagePath);
|
|
73
|
-
const imageBase64 = imageBuffer.toString('base64');
|
|
74
|
-
|
|
75
|
-
const ext = path.extname(imagePath).toLowerCase();
|
|
76
|
-
const mimeTypes = {
|
|
77
|
-
'.png': 'image/png',
|
|
78
|
-
'.jpg': 'image/jpeg',
|
|
79
|
-
'.jpeg': 'image/jpeg',
|
|
80
|
-
'.webp': 'image/webp',
|
|
81
|
-
'.gif': 'image/gif',
|
|
82
|
-
};
|
|
83
|
-
const mimeType = mimeTypes[ext] || 'image/png';
|
|
84
|
-
|
|
85
|
-
const prompt = `[Image attached as base64: ${mimeType}]
|
|
86
|
-
data:${mimeType};base64,${imageBase64}
|
|
87
|
-
|
|
88
|
-
Analyze this UI design image and generate production-ready code.
|
|
89
|
-
|
|
90
|
-
${getFrameworkPrompt(framework)}
|
|
91
|
-
|
|
92
|
-
Requirements:
|
|
93
|
-
1. Match the visual design exactly (colors, spacing, typography, layout)
|
|
94
|
-
2. Extract exact colors as hex values
|
|
95
|
-
3. Use proper semantic HTML structure
|
|
96
|
-
4. Make it responsive (mobile-first)
|
|
97
|
-
5. Include hover/focus states where appropriate
|
|
98
|
-
6. Add appropriate accessibility attributes
|
|
99
|
-
|
|
100
|
-
Output format:
|
|
101
|
-
\`\`\`${framework === 'html' ? 'html' : 'tsx'}
|
|
102
|
-
// Component code here
|
|
103
|
-
\`\`\`
|
|
104
|
-
|
|
105
|
-
Also provide a summary of:
|
|
106
|
-
- Colors extracted
|
|
107
|
-
- Components identified
|
|
108
|
-
- Layout structure`;
|
|
109
|
-
|
|
110
|
-
return askGemini(prompt);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
async function generateUIFromHTML(htmlPath, framework) {
|
|
114
|
-
const htmlContent = fs.readFileSync(htmlPath, 'utf-8');
|
|
115
|
-
|
|
116
|
-
const prompt = `Convert this HTML mockup to production-ready ${framework} code.
|
|
117
|
-
|
|
118
|
-
HTML Mockup:
|
|
119
|
-
\`\`\`html
|
|
120
|
-
${htmlContent}
|
|
121
|
-
\`\`\`
|
|
122
|
-
|
|
123
|
-
${getFrameworkPrompt(framework)}
|
|
124
|
-
|
|
125
|
-
Requirements:
|
|
126
|
-
1. Preserve the exact visual appearance
|
|
127
|
-
2. Extract inline styles to Tailwind classes
|
|
128
|
-
3. Create reusable components where appropriate
|
|
129
|
-
4. Add proper TypeScript types
|
|
130
|
-
5. Make it responsive
|
|
131
|
-
|
|
132
|
-
Output the converted code in proper format.`;
|
|
133
|
-
|
|
134
|
-
return askGemini(prompt);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
async function analyzeDesignFolder(folderPath, framework) {
|
|
138
|
-
const files = fs.readdirSync(folderPath);
|
|
139
|
-
let combinedPrompt = `Analyze the following design files and generate production-ready ${framework} code.\n\n`;
|
|
140
|
-
|
|
141
|
-
for (const file of files) {
|
|
142
|
-
const filePath = path.join(folderPath, file);
|
|
143
|
-
const ext = path.extname(file).toLowerCase();
|
|
144
|
-
|
|
145
|
-
if (['.png', '.jpg', '.jpeg', '.webp', '.gif'].includes(ext)) {
|
|
146
|
-
const imageBuffer = fs.readFileSync(filePath);
|
|
147
|
-
const imageBase64 = imageBuffer.toString('base64');
|
|
148
|
-
const mimeType = ext === '.png' ? 'image/png' : ext === '.webp' ? 'image/webp' : 'image/jpeg';
|
|
149
|
-
combinedPrompt += `\n--- Image: ${file} ---\ndata:${mimeType};base64,${imageBase64}\n`;
|
|
150
|
-
console.log(`š· ${file}`);
|
|
151
|
-
} else if (ext === '.html') {
|
|
152
|
-
const content = fs.readFileSync(filePath, 'utf-8');
|
|
153
|
-
combinedPrompt += `\n--- HTML: ${file} ---\n${content}\n`;
|
|
154
|
-
console.log(`š ${file}`);
|
|
155
|
-
} else if (ext === '.json') {
|
|
156
|
-
const content = fs.readFileSync(filePath, 'utf-8');
|
|
157
|
-
combinedPrompt += `\n--- Design Tokens: ${file} ---\n${content}\n`;
|
|
158
|
-
console.log(`š ${file}`);
|
|
159
|
-
} else if (['.css', '.scss'].includes(ext)) {
|
|
160
|
-
const content = fs.readFileSync(filePath, 'utf-8');
|
|
161
|
-
combinedPrompt += `\n--- Styles: ${file} ---\n${content}\n`;
|
|
162
|
-
console.log(`šØ ${file}`);
|
|
163
|
-
} else if (ext === '.md') {
|
|
164
|
-
const content = fs.readFileSync(filePath, 'utf-8');
|
|
165
|
-
combinedPrompt += `\n--- Guide: ${file} ---\n${content}\n`;
|
|
166
|
-
console.log(`š ${file}`);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
combinedPrompt += `\n${getFrameworkPrompt(framework)}
|
|
171
|
-
|
|
172
|
-
Requirements:
|
|
173
|
-
1. Match the visual design exactly
|
|
174
|
-
2. Extract design tokens from JSON if provided
|
|
175
|
-
3. Use CSS variables from stylesheets if provided
|
|
176
|
-
4. Create separate component files for each major UI section
|
|
177
|
-
5. Make it responsive (mobile-first)
|
|
178
|
-
6. Include accessibility attributes
|
|
179
|
-
|
|
180
|
-
Output complete component code.`;
|
|
181
|
-
|
|
182
|
-
return askGemini(combinedPrompt);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// ============================================
|
|
186
|
-
// CLI
|
|
187
|
-
// ============================================
|
|
188
|
-
|
|
189
|
-
async function main() {
|
|
190
|
-
const args = process.argv.slice(2);
|
|
191
|
-
|
|
192
|
-
const options = {
|
|
193
|
-
image: null,
|
|
194
|
-
html: null,
|
|
195
|
-
designFolder: null,
|
|
196
|
-
framework: 'react',
|
|
197
|
-
output: './generated',
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
for (let i = 0; i < args.length; i++) {
|
|
201
|
-
switch (args[i]) {
|
|
202
|
-
case '--image':
|
|
203
|
-
options.image = args[++i];
|
|
204
|
-
break;
|
|
205
|
-
case '--html':
|
|
206
|
-
options.html = args[++i];
|
|
207
|
-
break;
|
|
208
|
-
case '--design-folder':
|
|
209
|
-
case '--folder':
|
|
210
|
-
options.designFolder = args[++i];
|
|
211
|
-
break;
|
|
212
|
-
case '--framework':
|
|
213
|
-
case '-f':
|
|
214
|
-
options.framework = args[++i];
|
|
215
|
-
break;
|
|
216
|
-
case '--output':
|
|
217
|
-
case '-o':
|
|
218
|
-
options.output = args[++i];
|
|
219
|
-
break;
|
|
220
|
-
case '--help':
|
|
221
|
-
case '-h':
|
|
222
|
-
console.log(`
|
|
223
|
-
Gemini UI Code Generator
|
|
224
|
-
|
|
225
|
-
Usage:
|
|
226
|
-
node gemini-ui-gen.js --image ./design.png --framework react
|
|
227
|
-
node gemini-ui-gen.js --html ./mockup.html --framework vue
|
|
228
|
-
node gemini-ui-gen.js --design-folder ./design/ --framework react
|
|
229
|
-
|
|
230
|
-
Options:
|
|
231
|
-
--image <path> Image file to analyze
|
|
232
|
-
--html <path> HTML mockup to convert
|
|
233
|
-
--design-folder <path> Folder with design files
|
|
234
|
-
--framework <name> Target framework (react, vue, svelte, html)
|
|
235
|
-
--output <path> Output directory
|
|
236
|
-
--help Show this help
|
|
237
|
-
`);
|
|
238
|
-
process.exit(0);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
console.log(`š¤ Gemini UI Generator`);
|
|
243
|
-
console.log(`š¦ Framework: ${options.framework}`);
|
|
244
|
-
|
|
245
|
-
try {
|
|
246
|
-
let result;
|
|
247
|
-
|
|
248
|
-
if (options.image) {
|
|
249
|
-
console.log(`\nš· Analyzing: ${options.image}\n`);
|
|
250
|
-
result = await generateUIFromImage(options.image, options.framework);
|
|
251
|
-
} else if (options.html) {
|
|
252
|
-
console.log(`\nš Converting: ${options.html}\n`);
|
|
253
|
-
result = await generateUIFromHTML(options.html, options.framework);
|
|
254
|
-
} else if (options.designFolder) {
|
|
255
|
-
console.log(`\nš Analyzing folder: ${options.designFolder}\n`);
|
|
256
|
-
result = await analyzeDesignFolder(options.designFolder, options.framework);
|
|
257
|
-
} else {
|
|
258
|
-
console.error('ā No input specified. Use --image, --html, or --design-folder');
|
|
259
|
-
process.exit(1);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
console.log('\n' + '='.repeat(60) + '\n');
|
|
263
|
-
console.log(result);
|
|
264
|
-
console.log('\n' + '='.repeat(60));
|
|
265
|
-
|
|
266
|
-
if (options.output && result) {
|
|
267
|
-
if (!fs.existsSync(options.output)) {
|
|
268
|
-
fs.mkdirSync(options.output, { recursive: true });
|
|
269
|
-
}
|
|
270
|
-
const outputFile = path.join(options.output, `generated-${Date.now()}.txt`);
|
|
271
|
-
fs.writeFileSync(outputFile, result);
|
|
272
|
-
console.log(`\nā
Output saved to: ${outputFile}`);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
} catch (error) {
|
|
276
|
-
console.error(`\nā Error: ${error.message}`);
|
|
277
|
-
process.exit(1);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
main();
|
|
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 askGemini(prompt) {
|
|
35
|
+
const api = await getGeminiApi();
|
|
36
|
+
return api.ask(prompt, { model: 'gemini-3-flash', maxTokens: 8192, temperature: 0.3 });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ============================================
|
|
40
|
+
// UI Code Generation
|
|
41
|
+
// ============================================
|
|
42
|
+
|
|
43
|
+
function getFrameworkPrompt(framework) {
|
|
44
|
+
const prompts = {
|
|
45
|
+
react: `Generate React TypeScript components using:
|
|
46
|
+
- Functional components with hooks
|
|
47
|
+
- Tailwind CSS for styling
|
|
48
|
+
- Proper TypeScript types/interfaces
|
|
49
|
+
- Export as default`,
|
|
50
|
+
|
|
51
|
+
vue: `Generate Vue 3 components using:
|
|
52
|
+
- Composition API with <script setup>
|
|
53
|
+
- Tailwind CSS for styling
|
|
54
|
+
- TypeScript support
|
|
55
|
+
- Single File Component format`,
|
|
56
|
+
|
|
57
|
+
svelte: `Generate Svelte components using:
|
|
58
|
+
- Svelte 5 runes syntax
|
|
59
|
+
- Tailwind CSS for styling
|
|
60
|
+
- TypeScript support`,
|
|
61
|
+
|
|
62
|
+
html: `Generate semantic HTML5 with:
|
|
63
|
+
- Tailwind CSS classes
|
|
64
|
+
- Accessible markup
|
|
65
|
+
- Responsive design`,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
return prompts[framework] || prompts.react;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function generateUIFromImage(imagePath, framework) {
|
|
72
|
+
const imageBuffer = fs.readFileSync(imagePath);
|
|
73
|
+
const imageBase64 = imageBuffer.toString('base64');
|
|
74
|
+
|
|
75
|
+
const ext = path.extname(imagePath).toLowerCase();
|
|
76
|
+
const mimeTypes = {
|
|
77
|
+
'.png': 'image/png',
|
|
78
|
+
'.jpg': 'image/jpeg',
|
|
79
|
+
'.jpeg': 'image/jpeg',
|
|
80
|
+
'.webp': 'image/webp',
|
|
81
|
+
'.gif': 'image/gif',
|
|
82
|
+
};
|
|
83
|
+
const mimeType = mimeTypes[ext] || 'image/png';
|
|
84
|
+
|
|
85
|
+
const prompt = `[Image attached as base64: ${mimeType}]
|
|
86
|
+
data:${mimeType};base64,${imageBase64}
|
|
87
|
+
|
|
88
|
+
Analyze this UI design image and generate production-ready code.
|
|
89
|
+
|
|
90
|
+
${getFrameworkPrompt(framework)}
|
|
91
|
+
|
|
92
|
+
Requirements:
|
|
93
|
+
1. Match the visual design exactly (colors, spacing, typography, layout)
|
|
94
|
+
2. Extract exact colors as hex values
|
|
95
|
+
3. Use proper semantic HTML structure
|
|
96
|
+
4. Make it responsive (mobile-first)
|
|
97
|
+
5. Include hover/focus states where appropriate
|
|
98
|
+
6. Add appropriate accessibility attributes
|
|
99
|
+
|
|
100
|
+
Output format:
|
|
101
|
+
\`\`\`${framework === 'html' ? 'html' : 'tsx'}
|
|
102
|
+
// Component code here
|
|
103
|
+
\`\`\`
|
|
104
|
+
|
|
105
|
+
Also provide a summary of:
|
|
106
|
+
- Colors extracted
|
|
107
|
+
- Components identified
|
|
108
|
+
- Layout structure`;
|
|
109
|
+
|
|
110
|
+
return askGemini(prompt);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async function generateUIFromHTML(htmlPath, framework) {
|
|
114
|
+
const htmlContent = fs.readFileSync(htmlPath, 'utf-8');
|
|
115
|
+
|
|
116
|
+
const prompt = `Convert this HTML mockup to production-ready ${framework} code.
|
|
117
|
+
|
|
118
|
+
HTML Mockup:
|
|
119
|
+
\`\`\`html
|
|
120
|
+
${htmlContent}
|
|
121
|
+
\`\`\`
|
|
122
|
+
|
|
123
|
+
${getFrameworkPrompt(framework)}
|
|
124
|
+
|
|
125
|
+
Requirements:
|
|
126
|
+
1. Preserve the exact visual appearance
|
|
127
|
+
2. Extract inline styles to Tailwind classes
|
|
128
|
+
3. Create reusable components where appropriate
|
|
129
|
+
4. Add proper TypeScript types
|
|
130
|
+
5. Make it responsive
|
|
131
|
+
|
|
132
|
+
Output the converted code in proper format.`;
|
|
133
|
+
|
|
134
|
+
return askGemini(prompt);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async function analyzeDesignFolder(folderPath, framework) {
|
|
138
|
+
const files = fs.readdirSync(folderPath);
|
|
139
|
+
let combinedPrompt = `Analyze the following design files and generate production-ready ${framework} code.\n\n`;
|
|
140
|
+
|
|
141
|
+
for (const file of files) {
|
|
142
|
+
const filePath = path.join(folderPath, file);
|
|
143
|
+
const ext = path.extname(file).toLowerCase();
|
|
144
|
+
|
|
145
|
+
if (['.png', '.jpg', '.jpeg', '.webp', '.gif'].includes(ext)) {
|
|
146
|
+
const imageBuffer = fs.readFileSync(filePath);
|
|
147
|
+
const imageBase64 = imageBuffer.toString('base64');
|
|
148
|
+
const mimeType = ext === '.png' ? 'image/png' : ext === '.webp' ? 'image/webp' : 'image/jpeg';
|
|
149
|
+
combinedPrompt += `\n--- Image: ${file} ---\ndata:${mimeType};base64,${imageBase64}\n`;
|
|
150
|
+
console.log(`š· ${file}`);
|
|
151
|
+
} else if (ext === '.html') {
|
|
152
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
153
|
+
combinedPrompt += `\n--- HTML: ${file} ---\n${content}\n`;
|
|
154
|
+
console.log(`š ${file}`);
|
|
155
|
+
} else if (ext === '.json') {
|
|
156
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
157
|
+
combinedPrompt += `\n--- Design Tokens: ${file} ---\n${content}\n`;
|
|
158
|
+
console.log(`š ${file}`);
|
|
159
|
+
} else if (['.css', '.scss'].includes(ext)) {
|
|
160
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
161
|
+
combinedPrompt += `\n--- Styles: ${file} ---\n${content}\n`;
|
|
162
|
+
console.log(`šØ ${file}`);
|
|
163
|
+
} else if (ext === '.md') {
|
|
164
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
165
|
+
combinedPrompt += `\n--- Guide: ${file} ---\n${content}\n`;
|
|
166
|
+
console.log(`š ${file}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
combinedPrompt += `\n${getFrameworkPrompt(framework)}
|
|
171
|
+
|
|
172
|
+
Requirements:
|
|
173
|
+
1. Match the visual design exactly
|
|
174
|
+
2. Extract design tokens from JSON if provided
|
|
175
|
+
3. Use CSS variables from stylesheets if provided
|
|
176
|
+
4. Create separate component files for each major UI section
|
|
177
|
+
5. Make it responsive (mobile-first)
|
|
178
|
+
6. Include accessibility attributes
|
|
179
|
+
|
|
180
|
+
Output complete component code.`;
|
|
181
|
+
|
|
182
|
+
return askGemini(combinedPrompt);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// ============================================
|
|
186
|
+
// CLI
|
|
187
|
+
// ============================================
|
|
188
|
+
|
|
189
|
+
async function main() {
|
|
190
|
+
const args = process.argv.slice(2);
|
|
191
|
+
|
|
192
|
+
const options = {
|
|
193
|
+
image: null,
|
|
194
|
+
html: null,
|
|
195
|
+
designFolder: null,
|
|
196
|
+
framework: 'react',
|
|
197
|
+
output: './generated',
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
for (let i = 0; i < args.length; i++) {
|
|
201
|
+
switch (args[i]) {
|
|
202
|
+
case '--image':
|
|
203
|
+
options.image = args[++i];
|
|
204
|
+
break;
|
|
205
|
+
case '--html':
|
|
206
|
+
options.html = args[++i];
|
|
207
|
+
break;
|
|
208
|
+
case '--design-folder':
|
|
209
|
+
case '--folder':
|
|
210
|
+
options.designFolder = args[++i];
|
|
211
|
+
break;
|
|
212
|
+
case '--framework':
|
|
213
|
+
case '-f':
|
|
214
|
+
options.framework = args[++i];
|
|
215
|
+
break;
|
|
216
|
+
case '--output':
|
|
217
|
+
case '-o':
|
|
218
|
+
options.output = args[++i];
|
|
219
|
+
break;
|
|
220
|
+
case '--help':
|
|
221
|
+
case '-h':
|
|
222
|
+
console.log(`
|
|
223
|
+
Gemini UI Code Generator
|
|
224
|
+
|
|
225
|
+
Usage:
|
|
226
|
+
node gemini-ui-gen.js --image ./design.png --framework react
|
|
227
|
+
node gemini-ui-gen.js --html ./mockup.html --framework vue
|
|
228
|
+
node gemini-ui-gen.js --design-folder ./design/ --framework react
|
|
229
|
+
|
|
230
|
+
Options:
|
|
231
|
+
--image <path> Image file to analyze
|
|
232
|
+
--html <path> HTML mockup to convert
|
|
233
|
+
--design-folder <path> Folder with design files
|
|
234
|
+
--framework <name> Target framework (react, vue, svelte, html)
|
|
235
|
+
--output <path> Output directory
|
|
236
|
+
--help Show this help
|
|
237
|
+
`);
|
|
238
|
+
process.exit(0);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
console.log(`š¤ Gemini UI Generator`);
|
|
243
|
+
console.log(`š¦ Framework: ${options.framework}`);
|
|
244
|
+
|
|
245
|
+
try {
|
|
246
|
+
let result;
|
|
247
|
+
|
|
248
|
+
if (options.image) {
|
|
249
|
+
console.log(`\nš· Analyzing: ${options.image}\n`);
|
|
250
|
+
result = await generateUIFromImage(options.image, options.framework);
|
|
251
|
+
} else if (options.html) {
|
|
252
|
+
console.log(`\nš Converting: ${options.html}\n`);
|
|
253
|
+
result = await generateUIFromHTML(options.html, options.framework);
|
|
254
|
+
} else if (options.designFolder) {
|
|
255
|
+
console.log(`\nš Analyzing folder: ${options.designFolder}\n`);
|
|
256
|
+
result = await analyzeDesignFolder(options.designFolder, options.framework);
|
|
257
|
+
} else {
|
|
258
|
+
console.error('ā No input specified. Use --image, --html, or --design-folder');
|
|
259
|
+
process.exit(1);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
console.log('\n' + '='.repeat(60) + '\n');
|
|
263
|
+
console.log(result);
|
|
264
|
+
console.log('\n' + '='.repeat(60));
|
|
265
|
+
|
|
266
|
+
if (options.output && result) {
|
|
267
|
+
if (!fs.existsSync(options.output)) {
|
|
268
|
+
fs.mkdirSync(options.output, { recursive: true });
|
|
269
|
+
}
|
|
270
|
+
const outputFile = path.join(options.output, `generated-${Date.now()}.txt`);
|
|
271
|
+
fs.writeFileSync(outputFile, result);
|
|
272
|
+
console.log(`\nā
Output saved to: ${outputFile}`);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
} catch (error) {
|
|
276
|
+
console.error(`\nā Error: ${error.message}`);
|
|
277
|
+
process.exit(1);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
main();
|