opencode-nanobanana 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.
- package/.ralph-events.json +151 -0
- package/.ralph-last-branch +1 -0
- package/.ralph-monitor-state.json +7 -0
- package/.ralph-monitor.pid +1 -0
- package/.ralph-timing.json +26 -0
- package/README.md +708 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/platforms/android.d.ts +94 -0
- package/dist/platforms/android.d.ts.map +1 -0
- package/dist/platforms/android.js +123 -0
- package/dist/platforms/android.js.map +1 -0
- package/dist/platforms/ios.d.ts +51 -0
- package/dist/platforms/ios.d.ts.map +1 -0
- package/dist/platforms/ios.js +149 -0
- package/dist/platforms/ios.js.map +1 -0
- package/dist/platforms/macos.d.ts +33 -0
- package/dist/platforms/macos.d.ts.map +1 -0
- package/dist/platforms/macos.js +50 -0
- package/dist/platforms/macos.js.map +1 -0
- package/dist/platforms/watchos.d.ts +36 -0
- package/dist/platforms/watchos.d.ts.map +1 -0
- package/dist/platforms/watchos.js +113 -0
- package/dist/platforms/watchos.js.map +1 -0
- package/dist/platforms/web.d.ts +64 -0
- package/dist/platforms/web.d.ts.map +1 -0
- package/dist/platforms/web.js +96 -0
- package/dist/platforms/web.js.map +1 -0
- package/dist/providers/gemini.d.ts +41 -0
- package/dist/providers/gemini.d.ts.map +1 -0
- package/dist/providers/gemini.js +177 -0
- package/dist/providers/gemini.js.map +1 -0
- package/dist/tools/analyze/compare.d.ts +12 -0
- package/dist/tools/analyze/compare.d.ts.map +1 -0
- package/dist/tools/analyze/compare.js +83 -0
- package/dist/tools/analyze/compare.js.map +1 -0
- package/dist/tools/analyze/mockup.d.ts +12 -0
- package/dist/tools/analyze/mockup.d.ts.map +1 -0
- package/dist/tools/analyze/mockup.js +88 -0
- package/dist/tools/analyze/mockup.js.map +1 -0
- package/dist/tools/analyze/screenshot.d.ts +12 -0
- package/dist/tools/analyze/screenshot.d.ts.map +1 -0
- package/dist/tools/analyze/screenshot.js +61 -0
- package/dist/tools/analyze/screenshot.js.map +1 -0
- package/dist/tools/app-assets/app-icon.d.ts +9 -0
- package/dist/tools/app-assets/app-icon.d.ts.map +1 -0
- package/dist/tools/app-assets/app-icon.js +133 -0
- package/dist/tools/app-assets/app-icon.js.map +1 -0
- package/dist/tools/app-assets/device-mockup.d.ts +9 -0
- package/dist/tools/app-assets/device-mockup.d.ts.map +1 -0
- package/dist/tools/app-assets/device-mockup.js +139 -0
- package/dist/tools/app-assets/device-mockup.js.map +1 -0
- package/dist/tools/app-assets/launch-images.d.ts +3 -0
- package/dist/tools/app-assets/launch-images.d.ts.map +1 -0
- package/dist/tools/app-assets/launch-images.js +171 -0
- package/dist/tools/app-assets/launch-images.js.map +1 -0
- package/dist/tools/app-assets/resize-devices.d.ts +14 -0
- package/dist/tools/app-assets/resize-devices.d.ts.map +1 -0
- package/dist/tools/app-assets/resize-devices.js +296 -0
- package/dist/tools/app-assets/resize-devices.js.map +1 -0
- package/dist/tools/app-assets/screenshots.d.ts +14 -0
- package/dist/tools/app-assets/screenshots.d.ts.map +1 -0
- package/dist/tools/app-assets/screenshots.js +186 -0
- package/dist/tools/app-assets/screenshots.js.map +1 -0
- package/dist/tools/core/edit-image.d.ts +12 -0
- package/dist/tools/core/edit-image.d.ts.map +1 -0
- package/dist/tools/core/edit-image.js +102 -0
- package/dist/tools/core/edit-image.js.map +1 -0
- package/dist/tools/core/generate-image.d.ts +12 -0
- package/dist/tools/core/generate-image.d.ts.map +1 -0
- package/dist/tools/core/generate-image.js +96 -0
- package/dist/tools/core/generate-image.js.map +1 -0
- package/dist/tools/core/restore-image.d.ts +12 -0
- package/dist/tools/core/restore-image.d.ts.map +1 -0
- package/dist/tools/core/restore-image.js +104 -0
- package/dist/tools/core/restore-image.js.map +1 -0
- package/dist/tools/design/mockup-to-code.d.ts +3 -0
- package/dist/tools/design/mockup-to-code.d.ts.map +1 -0
- package/dist/tools/design/mockup-to-code.js +311 -0
- package/dist/tools/design/mockup-to-code.js.map +1 -0
- package/dist/tools/design/sketch-to-code.d.ts +3 -0
- package/dist/tools/design/sketch-to-code.d.ts.map +1 -0
- package/dist/tools/design/sketch-to-code.js +325 -0
- package/dist/tools/design/sketch-to-code.js.map +1 -0
- package/dist/tools/docs/architecture-diagram.d.ts +12 -0
- package/dist/tools/docs/architecture-diagram.d.ts.map +1 -0
- package/dist/tools/docs/architecture-diagram.js +179 -0
- package/dist/tools/docs/architecture-diagram.js.map +1 -0
- package/dist/tools/docs/readme-banner.d.ts +6 -0
- package/dist/tools/docs/readme-banner.d.ts.map +1 -0
- package/dist/tools/docs/readme-banner.js +108 -0
- package/dist/tools/docs/readme-banner.js.map +1 -0
- package/dist/tools/docs/sequence-diagram.d.ts +12 -0
- package/dist/tools/docs/sequence-diagram.d.ts.map +1 -0
- package/dist/tools/docs/sequence-diagram.js +161 -0
- package/dist/tools/docs/sequence-diagram.js.map +1 -0
- package/dist/tools/docs/social-preview.d.ts +11 -0
- package/dist/tools/docs/social-preview.d.ts.map +1 -0
- package/dist/tools/docs/social-preview.js +111 -0
- package/dist/tools/docs/social-preview.js.map +1 -0
- package/dist/tools/video/extend-video.d.ts +14 -0
- package/dist/tools/video/extend-video.d.ts.map +1 -0
- package/dist/tools/video/extend-video.js +39 -0
- package/dist/tools/video/extend-video.js.map +1 -0
- package/dist/tools/video/generate-video.d.ts +14 -0
- package/dist/tools/video/generate-video.d.ts.map +1 -0
- package/dist/tools/video/generate-video.js +39 -0
- package/dist/tools/video/generate-video.js.map +1 -0
- package/dist/tools/video/image-to-video.d.ts +15 -0
- package/dist/tools/video/image-to-video.d.ts.map +1 -0
- package/dist/tools/video/image-to-video.js +42 -0
- package/dist/tools/video/image-to-video.js.map +1 -0
- package/dist/tools/video/storyboard-video.d.ts +91 -0
- package/dist/tools/video/storyboard-video.d.ts.map +1 -0
- package/dist/tools/video/storyboard-video.js +230 -0
- package/dist/tools/video/storyboard-video.js.map +1 -0
- package/dist/utils/ffmpeg.d.ts +30 -0
- package/dist/utils/ffmpeg.d.ts.map +1 -0
- package/dist/utils/ffmpeg.js +205 -0
- package/dist/utils/ffmpeg.js.map +1 -0
- package/dist/utils/file-handler.d.ts +7 -0
- package/dist/utils/file-handler.d.ts.map +1 -0
- package/dist/utils/file-handler.js +10 -0
- package/dist/utils/file-handler.js.map +1 -0
- package/dist/utils/image-processing.d.ts +7 -0
- package/dist/utils/image-processing.d.ts.map +1 -0
- package/dist/utils/image-processing.js +10 -0
- package/dist/utils/image-processing.js.map +1 -0
- package/docs/PLUGIN-VERIFICATION.md +182 -0
- package/logs/notifications.jsonl +46 -0
- package/package.json +61 -0
- package/prd.json +216 -0
- package/progress.txt +145 -0
- package/ralph-report.html +297 -0
- package/src/index.ts +23 -0
- package/src/platforms/android/.gitkeep +0 -0
- package/src/platforms/ios/.gitkeep +0 -0
- package/src/platforms/web/.gitkeep +0 -0
- package/src/providers/.gitkeep +0 -0
- package/src/providers/gemini.ts +288 -0
- package/src/tools/core/.gitkeep +0 -0
- package/src/tools/platform/.gitkeep +0 -0
- package/src/tools/video/extend-video.ts +71 -0
- package/src/tools/video/generate-video.ts +70 -0
- package/src/tools/video/image-to-video.ts +76 -0
- package/src/tools/video/storyboard-video.ts +325 -0
- package/src/utils/.gitkeep +0 -0
- package/src/utils/ffmpeg.ts +266 -0
- package/src/utils/file-handler.ts +10 -0
- package/src/utils/image-processing.ts +10 -0
- package/templates/.gitkeep +0 -0
- package/test-analyze-screenshot.ts +50 -0
- package/test-app-icons.ts +55 -0
- package/test-cat-sunset.ts +30 -0
- package/test-full-plugin.ts +88 -0
- package/test-icon-gen.ts +30 -0
- package/test-output/test-edit.png +0 -0
- package/test-output/test-generate.png +0 -0
- package/test-output/test-video.mp4 +0 -0
- package/test-plugin-load.js +45 -0
- package/test-princess-emma-continue.ts +35 -0
- package/test-princess-emma-full.ts +38 -0
- package/test-princess-emma-short.ts +32 -0
- package/test-princess-emma-with-reference.ts +34 -0
- package/test-princess-emma.ts +38 -0
- package/test-product-ad.ts +66 -0
- package/test-ralph-droid.ts +30 -0
- package/test-social-preview.ts +61 -0
- package/test-veo31-live.ts +187 -0
- package/test-video-gen.ts +40 -0
- package/test-video-veo.ts +73 -0
- package/test-zurich-video.ts +64 -0
- package/tests/.gitkeep +0 -0
- package/tests/providers/gemini.test.ts +388 -0
- package/tests/utils/ffmpeg.test.ts +328 -0
- package/tests/video/storyboard.test.ts +469 -0
- package/tsconfig.json +25 -0
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import { tool } from '@opencode-ai/plugin/tool';
|
|
2
|
+
import { GeminiProvider } from '../../providers/gemini.js';
|
|
3
|
+
import { loadImage } from '../../utils/file-handler.js';
|
|
4
|
+
export const mockupToCodeTool = tool({
|
|
5
|
+
description: 'Convert design mockup images to component code. Supports React, Vue, SwiftUI, and HTML with various styling options.',
|
|
6
|
+
args: {
|
|
7
|
+
imagePath: tool.schema.string().describe('Path to the design mockup image'),
|
|
8
|
+
framework: tool.schema.enum(['react', 'vue', 'swiftui', 'html']).describe('Target framework for code generation'),
|
|
9
|
+
styling: tool.schema.enum(['tailwind', 'css', 'styled-components']).optional().describe('Styling approach (optional, defaults based on framework)'),
|
|
10
|
+
componentName: tool.schema.string().optional().describe('Name for the generated component (optional)'),
|
|
11
|
+
},
|
|
12
|
+
async execute(args, _context) {
|
|
13
|
+
try {
|
|
14
|
+
const { imagePath, framework, styling, componentName } = args;
|
|
15
|
+
// Load the mockup image
|
|
16
|
+
const imageBuffer = await loadImage(imagePath);
|
|
17
|
+
// Build comprehensive prompt for code generation
|
|
18
|
+
const prompt = buildCodeGenerationPrompt(framework, styling, componentName);
|
|
19
|
+
// Use Gemini to analyze mockup and generate code
|
|
20
|
+
const gemini = new GeminiProvider();
|
|
21
|
+
const generatedCode = await gemini.analyzeImage(imageBuffer, prompt);
|
|
22
|
+
// Format response
|
|
23
|
+
return `✓ Code generated from mockup: ${imagePath}
|
|
24
|
+
|
|
25
|
+
Framework: ${framework}${styling ? ` with ${styling}` : ''}
|
|
26
|
+
${componentName ? `Component: ${componentName}\n` : ''}
|
|
27
|
+
${generatedCode}
|
|
28
|
+
|
|
29
|
+
Note: Review and adjust the generated code to match your project's specific requirements and coding standards.`;
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
33
|
+
if (errorMessage.includes('API key')) {
|
|
34
|
+
return '✗ Error: GEMINI_API_KEY environment variable not set. Please configure your API key.';
|
|
35
|
+
}
|
|
36
|
+
if (errorMessage.includes('ENOENT') || errorMessage.includes('no such file')) {
|
|
37
|
+
return `✗ Error: Image file not found at path: ${args.imagePath}`;
|
|
38
|
+
}
|
|
39
|
+
return `✗ Error generating code from mockup: ${errorMessage}`;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
/**
|
|
44
|
+
* Build framework-specific code generation prompt
|
|
45
|
+
*/
|
|
46
|
+
function buildCodeGenerationPrompt(framework, styling, componentName) {
|
|
47
|
+
const name = componentName || getDefaultComponentName(framework);
|
|
48
|
+
// Base prompt common to all frameworks
|
|
49
|
+
let prompt = `Analyze this design mockup and generate clean, production-ready code that accurately recreates the design.
|
|
50
|
+
|
|
51
|
+
Component Name: ${name}
|
|
52
|
+
|
|
53
|
+
Focus on:
|
|
54
|
+
1. Accurate layout and spacing
|
|
55
|
+
2. Exact colors, fonts, and styling
|
|
56
|
+
3. Proper component structure and hierarchy
|
|
57
|
+
4. Semantic HTML/markup
|
|
58
|
+
5. Responsive design considerations
|
|
59
|
+
6. Accessibility (ARIA labels, semantic tags)
|
|
60
|
+
|
|
61
|
+
`;
|
|
62
|
+
// Framework-specific instructions
|
|
63
|
+
switch (framework) {
|
|
64
|
+
case 'react':
|
|
65
|
+
prompt += generateReactPrompt(styling || 'tailwind', name);
|
|
66
|
+
break;
|
|
67
|
+
case 'vue':
|
|
68
|
+
prompt += generateVuePrompt(styling || 'css', name);
|
|
69
|
+
break;
|
|
70
|
+
case 'swiftui':
|
|
71
|
+
prompt += generateSwiftUIPrompt(name);
|
|
72
|
+
break;
|
|
73
|
+
case 'html':
|
|
74
|
+
prompt += generateHTMLPrompt(styling || 'css', name);
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
prompt += `\n\nProvide only the code - no explanations or markdown formatting unless it's part of comments in the code.`;
|
|
78
|
+
return prompt;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Generate React-specific prompt
|
|
82
|
+
*/
|
|
83
|
+
function generateReactPrompt(styling, componentName) {
|
|
84
|
+
let prompt = `Generate React code with TypeScript.
|
|
85
|
+
|
|
86
|
+
`;
|
|
87
|
+
if (styling === 'tailwind') {
|
|
88
|
+
prompt += `Use Tailwind CSS for styling:
|
|
89
|
+
- Use Tailwind utility classes
|
|
90
|
+
- Follow responsive design patterns (sm:, md:, lg:, xl:)
|
|
91
|
+
- Use semantic color names from the design
|
|
92
|
+
- Implement proper spacing with Tailwind's spacing scale
|
|
93
|
+
|
|
94
|
+
Example structure:
|
|
95
|
+
\`\`\`tsx
|
|
96
|
+
interface ${componentName}Props {
|
|
97
|
+
// Define props here
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function ${componentName}({ }: ${componentName}Props) {
|
|
101
|
+
return (
|
|
102
|
+
<div className="...">
|
|
103
|
+
{/* Component content */}
|
|
104
|
+
</div>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
\`\`\``;
|
|
108
|
+
}
|
|
109
|
+
else if (styling === 'styled-components') {
|
|
110
|
+
prompt += `Use styled-components for styling:
|
|
111
|
+
- Create styled components for each major element
|
|
112
|
+
- Use theme variables where appropriate
|
|
113
|
+
- Implement responsive styles with media queries
|
|
114
|
+
- Follow CSS-in-JS best practices
|
|
115
|
+
|
|
116
|
+
Example structure:
|
|
117
|
+
\`\`\`tsx
|
|
118
|
+
import styled from 'styled-components';
|
|
119
|
+
|
|
120
|
+
const Container = styled.div\`
|
|
121
|
+
/* styles */
|
|
122
|
+
\`;
|
|
123
|
+
|
|
124
|
+
interface ${componentName}Props {
|
|
125
|
+
// Define props here
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function ${componentName}({ }: ${componentName}Props) {
|
|
129
|
+
return (
|
|
130
|
+
<Container>
|
|
131
|
+
{/* Component content */}
|
|
132
|
+
</Container>
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
\`\`\``;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
prompt += `Use CSS Modules for styling:
|
|
139
|
+
- Create separate styles object
|
|
140
|
+
- Use className for styling
|
|
141
|
+
- Implement BEM naming convention
|
|
142
|
+
- Include responsive media queries
|
|
143
|
+
|
|
144
|
+
Example structure:
|
|
145
|
+
\`\`\`tsx
|
|
146
|
+
import styles from './${componentName}.module.css';
|
|
147
|
+
|
|
148
|
+
interface ${componentName}Props {
|
|
149
|
+
// Define props here
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function ${componentName}({ }: ${componentName}Props) {
|
|
153
|
+
return (
|
|
154
|
+
<div className={styles.container}>
|
|
155
|
+
{/* Component content */}
|
|
156
|
+
</div>
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
\`\`\``;
|
|
160
|
+
}
|
|
161
|
+
return prompt;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Generate Vue-specific prompt
|
|
165
|
+
*/
|
|
166
|
+
function generateVuePrompt(styling, componentName) {
|
|
167
|
+
let prompt = `Generate Vue 3 code with TypeScript and Composition API.
|
|
168
|
+
|
|
169
|
+
`;
|
|
170
|
+
if (styling === 'tailwind') {
|
|
171
|
+
prompt += `Use Tailwind CSS for styling:
|
|
172
|
+
- Use Tailwind utility classes in template
|
|
173
|
+
- Follow Vue 3 best practices
|
|
174
|
+
- Use <script setup> syntax
|
|
175
|
+
|
|
176
|
+
Example structure:
|
|
177
|
+
\`\`\`vue
|
|
178
|
+
<template>
|
|
179
|
+
<div class="...">
|
|
180
|
+
<!-- Component content -->
|
|
181
|
+
</div>
|
|
182
|
+
</template>
|
|
183
|
+
|
|
184
|
+
<script setup lang="ts">
|
|
185
|
+
interface ${componentName}Props {
|
|
186
|
+
// Define props here
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
defineProps<${componentName}Props>();
|
|
190
|
+
</script>
|
|
191
|
+
\`\`\``;
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
prompt += `Use scoped CSS for styling:
|
|
195
|
+
- Use <style scoped> for component-specific styles
|
|
196
|
+
- Follow Vue 3 best practices
|
|
197
|
+
- Use <script setup> syntax
|
|
198
|
+
|
|
199
|
+
Example structure:
|
|
200
|
+
\`\`\`vue
|
|
201
|
+
<template>
|
|
202
|
+
<div class="container">
|
|
203
|
+
<!-- Component content -->
|
|
204
|
+
</div>
|
|
205
|
+
</template>
|
|
206
|
+
|
|
207
|
+
<script setup lang="ts">
|
|
208
|
+
interface ${componentName}Props {
|
|
209
|
+
// Define props here
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
defineProps<${componentName}Props>();
|
|
213
|
+
</script>
|
|
214
|
+
|
|
215
|
+
<style scoped>
|
|
216
|
+
.container {
|
|
217
|
+
/* styles */
|
|
218
|
+
}
|
|
219
|
+
</style>
|
|
220
|
+
\`\`\``;
|
|
221
|
+
}
|
|
222
|
+
return prompt;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Generate SwiftUI-specific prompt
|
|
226
|
+
*/
|
|
227
|
+
function generateSwiftUIPrompt(componentName) {
|
|
228
|
+
return `Generate SwiftUI code for iOS/macOS.
|
|
229
|
+
|
|
230
|
+
- Use SwiftUI Views and Modifiers
|
|
231
|
+
- Implement proper spacing with padding, spacing in VStack/HStack
|
|
232
|
+
- Use Color and Font from SwiftUI
|
|
233
|
+
- Follow Apple's Human Interface Guidelines
|
|
234
|
+
- Make the component reusable with proper parameters
|
|
235
|
+
|
|
236
|
+
Example structure:
|
|
237
|
+
\`\`\`swift
|
|
238
|
+
import SwiftUI
|
|
239
|
+
|
|
240
|
+
struct ${componentName}: View {
|
|
241
|
+
// Define properties here
|
|
242
|
+
|
|
243
|
+
var body: some View {
|
|
244
|
+
VStack {
|
|
245
|
+
// Component content
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
#Preview {
|
|
251
|
+
${componentName}()
|
|
252
|
+
}
|
|
253
|
+
\`\`\``;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Generate HTML-specific prompt
|
|
257
|
+
*/
|
|
258
|
+
function generateHTMLPrompt(styling, _componentName) {
|
|
259
|
+
let prompt = `Generate semantic HTML5 code.
|
|
260
|
+
|
|
261
|
+
`;
|
|
262
|
+
if (styling === 'tailwind') {
|
|
263
|
+
prompt += `Use Tailwind CSS for styling:
|
|
264
|
+
- Use Tailwind utility classes
|
|
265
|
+
- Follow responsive design patterns
|
|
266
|
+
- Use semantic HTML5 tags
|
|
267
|
+
|
|
268
|
+
Example structure:
|
|
269
|
+
\`\`\`html
|
|
270
|
+
<div class="...">
|
|
271
|
+
<!-- Component content -->
|
|
272
|
+
</div>
|
|
273
|
+
\`\`\``;
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
prompt += `Use custom CSS for styling:
|
|
277
|
+
- Use semantic HTML5 tags
|
|
278
|
+
- Include CSS in <style> block
|
|
279
|
+
- Follow BEM naming convention
|
|
280
|
+
- Implement responsive design with media queries
|
|
281
|
+
|
|
282
|
+
Example structure:
|
|
283
|
+
\`\`\`html
|
|
284
|
+
<div class="component">
|
|
285
|
+
<!-- Component content -->
|
|
286
|
+
</div>
|
|
287
|
+
|
|
288
|
+
<style>
|
|
289
|
+
.component {
|
|
290
|
+
/* styles */
|
|
291
|
+
}
|
|
292
|
+
</style>
|
|
293
|
+
\`\`\``;
|
|
294
|
+
}
|
|
295
|
+
return prompt;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Get default component name based on framework
|
|
299
|
+
*/
|
|
300
|
+
function getDefaultComponentName(framework) {
|
|
301
|
+
switch (framework) {
|
|
302
|
+
case 'react':
|
|
303
|
+
case 'vue':
|
|
304
|
+
return 'DesignComponent';
|
|
305
|
+
case 'swiftui':
|
|
306
|
+
return 'DesignView';
|
|
307
|
+
case 'html':
|
|
308
|
+
return 'design-component';
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
//# sourceMappingURL=mockup-to-code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mockup-to-code.js","sourceRoot":"","sources":["../../../src/tools/design/mockup-to-code.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sketch-to-code.d.ts","sourceRoot":"","sources":["../../../src/tools/design/sketch-to-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAIrE,eAAO,MAAM,gBAAgB,EAAE,cA4C7B,CAAC"}
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import { tool } from '@opencode-ai/plugin/tool';
|
|
2
|
+
import { GeminiProvider } from '../../providers/gemini.js';
|
|
3
|
+
import { loadImage } from '../../utils/file-handler.js';
|
|
4
|
+
export const sketchToCodeTool = tool({
|
|
5
|
+
description: 'Convert hand-drawn sketches and rough wireframes to component code. Interprets sketchy, imprecise designs and generates production-ready code.',
|
|
6
|
+
args: {
|
|
7
|
+
imagePath: tool.schema.string().describe('Path to the sketch or wireframe image'),
|
|
8
|
+
framework: tool.schema.enum(['react', 'vue', 'swiftui', 'html']).describe('Target framework for code generation'),
|
|
9
|
+
styling: tool.schema.enum(['tailwind', 'css', 'styled-components']).optional().describe('Styling approach (optional, defaults based on framework)'),
|
|
10
|
+
componentName: tool.schema.string().optional().describe('Name for the generated component (optional)'),
|
|
11
|
+
},
|
|
12
|
+
async execute(args, _context) {
|
|
13
|
+
try {
|
|
14
|
+
const { imagePath, framework, styling, componentName } = args;
|
|
15
|
+
// Load the sketch image
|
|
16
|
+
const imageBuffer = await loadImage(imagePath);
|
|
17
|
+
// Build comprehensive prompt for code generation from sketch
|
|
18
|
+
const prompt = buildSketchCodePrompt(framework, styling, componentName);
|
|
19
|
+
// Use Gemini to analyze sketch and generate code
|
|
20
|
+
const gemini = new GeminiProvider();
|
|
21
|
+
const generatedCode = await gemini.analyzeImage(imageBuffer, prompt);
|
|
22
|
+
// Format response
|
|
23
|
+
return `✓ Code generated from sketch: ${imagePath}
|
|
24
|
+
|
|
25
|
+
Framework: ${framework}${styling ? ` with ${styling}` : ''}
|
|
26
|
+
${componentName ? `Component: ${componentName}\n` : ''}
|
|
27
|
+
${generatedCode}
|
|
28
|
+
|
|
29
|
+
Note: The code was generated from a sketch/wireframe. Review and refine the implementation to match your exact requirements.`;
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
33
|
+
if (errorMessage.includes('API key')) {
|
|
34
|
+
return '✗ Error: GEMINI_API_KEY environment variable not set. Please configure your API key.';
|
|
35
|
+
}
|
|
36
|
+
if (errorMessage.includes('ENOENT') || errorMessage.includes('no such file')) {
|
|
37
|
+
return `✗ Error: Image file not found at path: ${args.imagePath}`;
|
|
38
|
+
}
|
|
39
|
+
return `✗ Error generating code from sketch: ${errorMessage}`;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
/**
|
|
44
|
+
* Build framework-specific code generation prompt for sketches
|
|
45
|
+
*/
|
|
46
|
+
function buildSketchCodePrompt(framework, styling, componentName) {
|
|
47
|
+
const name = componentName || getDefaultComponentName(framework);
|
|
48
|
+
// Base prompt specifically for hand-drawn/rough sketches
|
|
49
|
+
let prompt = `Analyze this hand-drawn sketch or rough wireframe and generate clean, production-ready code.
|
|
50
|
+
|
|
51
|
+
Component Name: ${name}
|
|
52
|
+
|
|
53
|
+
IMPORTANT: This is a sketch/wireframe, not a polished design mockup. Interpret the intent:
|
|
54
|
+
1. Boxes and rectangles represent containers/sections
|
|
55
|
+
2. Lines and scribbles represent text content
|
|
56
|
+
3. Circles or rounded shapes may represent buttons, icons, or avatars
|
|
57
|
+
4. Hand-drawn elements should be converted to proper UI components
|
|
58
|
+
5. Rough spacing should be translated to proper layout spacing
|
|
59
|
+
6. Assume standard UI patterns where the sketch is ambiguous
|
|
60
|
+
|
|
61
|
+
Focus on:
|
|
62
|
+
1. Interpreting the layout structure and component hierarchy
|
|
63
|
+
2. Using semantic component types (header, nav, button, card, etc.)
|
|
64
|
+
3. Applying sensible defaults for colors (use neutral/modern palette)
|
|
65
|
+
4. Implementing proper spacing and alignment
|
|
66
|
+
5. Making the design responsive
|
|
67
|
+
6. Following accessibility best practices
|
|
68
|
+
|
|
69
|
+
`;
|
|
70
|
+
// Framework-specific instructions
|
|
71
|
+
switch (framework) {
|
|
72
|
+
case 'react':
|
|
73
|
+
prompt += generateReactPrompt(styling || 'tailwind', name);
|
|
74
|
+
break;
|
|
75
|
+
case 'vue':
|
|
76
|
+
prompt += generateVuePrompt(styling || 'css', name);
|
|
77
|
+
break;
|
|
78
|
+
case 'swiftui':
|
|
79
|
+
prompt += generateSwiftUIPrompt(name);
|
|
80
|
+
break;
|
|
81
|
+
case 'html':
|
|
82
|
+
prompt += generateHTMLPrompt(styling || 'css', name);
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
prompt += `\n\nProvide only the code - no explanations or markdown formatting unless it's part of comments in the code.`;
|
|
86
|
+
return prompt;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Generate React-specific prompt
|
|
90
|
+
*/
|
|
91
|
+
function generateReactPrompt(styling, componentName) {
|
|
92
|
+
let prompt = `Generate React code with TypeScript.
|
|
93
|
+
|
|
94
|
+
`;
|
|
95
|
+
if (styling === 'tailwind') {
|
|
96
|
+
prompt += `Use Tailwind CSS for styling:
|
|
97
|
+
- Use Tailwind utility classes
|
|
98
|
+
- Apply modern, neutral color palette (gray-50 through gray-900, blue for primary actions)
|
|
99
|
+
- Follow responsive design patterns (sm:, md:, lg:, xl:)
|
|
100
|
+
- Implement proper spacing with Tailwind's spacing scale
|
|
101
|
+
- Use rounded corners and shadows for depth where appropriate
|
|
102
|
+
|
|
103
|
+
Example structure:
|
|
104
|
+
\`\`\`tsx
|
|
105
|
+
interface ${componentName}Props {
|
|
106
|
+
// Define props here
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function ${componentName}({ }: ${componentName}Props) {
|
|
110
|
+
return (
|
|
111
|
+
<div className="...">
|
|
112
|
+
{/* Component content */}
|
|
113
|
+
</div>
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
\`\`\``;
|
|
117
|
+
}
|
|
118
|
+
else if (styling === 'styled-components') {
|
|
119
|
+
prompt += `Use styled-components for styling:
|
|
120
|
+
- Create styled components for each major element
|
|
121
|
+
- Use modern, neutral color palette
|
|
122
|
+
- Implement responsive styles with media queries
|
|
123
|
+
- Follow CSS-in-JS best practices
|
|
124
|
+
|
|
125
|
+
Example structure:
|
|
126
|
+
\`\`\`tsx
|
|
127
|
+
import styled from 'styled-components';
|
|
128
|
+
|
|
129
|
+
const Container = styled.div\`
|
|
130
|
+
/* styles */
|
|
131
|
+
\`;
|
|
132
|
+
|
|
133
|
+
interface ${componentName}Props {
|
|
134
|
+
// Define props here
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function ${componentName}({ }: ${componentName}Props) {
|
|
138
|
+
return (
|
|
139
|
+
<Container>
|
|
140
|
+
{/* Component content */}
|
|
141
|
+
</Container>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
\`\`\``;
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
prompt += `Use CSS Modules for styling:
|
|
148
|
+
- Create separate styles object
|
|
149
|
+
- Use className for styling
|
|
150
|
+
- Implement BEM naming convention
|
|
151
|
+
- Include responsive media queries
|
|
152
|
+
- Apply modern, neutral color palette
|
|
153
|
+
|
|
154
|
+
Example structure:
|
|
155
|
+
\`\`\`tsx
|
|
156
|
+
import styles from './${componentName}.module.css';
|
|
157
|
+
|
|
158
|
+
interface ${componentName}Props {
|
|
159
|
+
// Define props here
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export function ${componentName}({ }: ${componentName}Props) {
|
|
163
|
+
return (
|
|
164
|
+
<div className={styles.container}>
|
|
165
|
+
{/* Component content */}
|
|
166
|
+
</div>
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
\`\`\``;
|
|
170
|
+
}
|
|
171
|
+
return prompt;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Generate Vue-specific prompt
|
|
175
|
+
*/
|
|
176
|
+
function generateVuePrompt(styling, componentName) {
|
|
177
|
+
let prompt = `Generate Vue 3 code with TypeScript and Composition API.
|
|
178
|
+
|
|
179
|
+
`;
|
|
180
|
+
if (styling === 'tailwind') {
|
|
181
|
+
prompt += `Use Tailwind CSS for styling:
|
|
182
|
+
- Use Tailwind utility classes in template
|
|
183
|
+
- Apply modern, neutral color palette
|
|
184
|
+
- Follow Vue 3 best practices
|
|
185
|
+
- Use <script setup> syntax
|
|
186
|
+
|
|
187
|
+
Example structure:
|
|
188
|
+
\`\`\`vue
|
|
189
|
+
<template>
|
|
190
|
+
<div class="...">
|
|
191
|
+
<!-- Component content -->
|
|
192
|
+
</div>
|
|
193
|
+
</template>
|
|
194
|
+
|
|
195
|
+
<script setup lang="ts">
|
|
196
|
+
interface ${componentName}Props {
|
|
197
|
+
// Define props here
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
defineProps<${componentName}Props>();
|
|
201
|
+
</script>
|
|
202
|
+
\`\`\``;
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
prompt += `Use scoped CSS for styling:
|
|
206
|
+
- Use <style scoped> for component-specific styles
|
|
207
|
+
- Apply modern, neutral color palette
|
|
208
|
+
- Follow Vue 3 best practices
|
|
209
|
+
- Use <script setup> syntax
|
|
210
|
+
|
|
211
|
+
Example structure:
|
|
212
|
+
\`\`\`vue
|
|
213
|
+
<template>
|
|
214
|
+
<div class="container">
|
|
215
|
+
<!-- Component content -->
|
|
216
|
+
</div>
|
|
217
|
+
</template>
|
|
218
|
+
|
|
219
|
+
<script setup lang="ts">
|
|
220
|
+
interface ${componentName}Props {
|
|
221
|
+
// Define props here
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
defineProps<${componentName}Props>();
|
|
225
|
+
</script>
|
|
226
|
+
|
|
227
|
+
<style scoped>
|
|
228
|
+
.container {
|
|
229
|
+
/* styles */
|
|
230
|
+
}
|
|
231
|
+
</style>
|
|
232
|
+
\`\`\``;
|
|
233
|
+
}
|
|
234
|
+
return prompt;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Generate SwiftUI-specific prompt
|
|
238
|
+
*/
|
|
239
|
+
function generateSwiftUIPrompt(componentName) {
|
|
240
|
+
return `Generate SwiftUI code for iOS/macOS.
|
|
241
|
+
|
|
242
|
+
- Use SwiftUI Views and Modifiers
|
|
243
|
+
- Apply system colors and fonts for a native look
|
|
244
|
+
- Implement proper spacing with padding, spacing in VStack/HStack
|
|
245
|
+
- Follow Apple's Human Interface Guidelines
|
|
246
|
+
- Make the component reusable with proper parameters
|
|
247
|
+
|
|
248
|
+
Example structure:
|
|
249
|
+
\`\`\`swift
|
|
250
|
+
import SwiftUI
|
|
251
|
+
|
|
252
|
+
struct ${componentName}: View {
|
|
253
|
+
// Define properties here
|
|
254
|
+
|
|
255
|
+
var body: some View {
|
|
256
|
+
VStack {
|
|
257
|
+
// Component content
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
#Preview {
|
|
263
|
+
${componentName}()
|
|
264
|
+
}
|
|
265
|
+
\`\`\``;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Generate HTML-specific prompt
|
|
269
|
+
*/
|
|
270
|
+
function generateHTMLPrompt(styling, _componentName) {
|
|
271
|
+
let prompt = `Generate semantic HTML5 code.
|
|
272
|
+
|
|
273
|
+
`;
|
|
274
|
+
if (styling === 'tailwind') {
|
|
275
|
+
prompt += `Use Tailwind CSS for styling:
|
|
276
|
+
- Use Tailwind utility classes
|
|
277
|
+
- Apply modern, neutral color palette
|
|
278
|
+
- Follow responsive design patterns
|
|
279
|
+
- Use semantic HTML5 tags
|
|
280
|
+
|
|
281
|
+
Example structure:
|
|
282
|
+
\`\`\`html
|
|
283
|
+
<div class="...">
|
|
284
|
+
<!-- Component content -->
|
|
285
|
+
</div>
|
|
286
|
+
\`\`\``;
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
prompt += `Use custom CSS for styling:
|
|
290
|
+
- Use semantic HTML5 tags
|
|
291
|
+
- Include CSS in <style> block
|
|
292
|
+
- Follow BEM naming convention
|
|
293
|
+
- Apply modern, neutral color palette
|
|
294
|
+
- Implement responsive design with media queries
|
|
295
|
+
|
|
296
|
+
Example structure:
|
|
297
|
+
\`\`\`html
|
|
298
|
+
<div class="component">
|
|
299
|
+
<!-- Component content -->
|
|
300
|
+
</div>
|
|
301
|
+
|
|
302
|
+
<style>
|
|
303
|
+
.component {
|
|
304
|
+
/* styles */
|
|
305
|
+
}
|
|
306
|
+
</style>
|
|
307
|
+
\`\`\``;
|
|
308
|
+
}
|
|
309
|
+
return prompt;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Get default component name based on framework
|
|
313
|
+
*/
|
|
314
|
+
function getDefaultComponentName(framework) {
|
|
315
|
+
switch (framework) {
|
|
316
|
+
case 'react':
|
|
317
|
+
case 'vue':
|
|
318
|
+
return 'SketchComponent';
|
|
319
|
+
case 'swiftui':
|
|
320
|
+
return 'SketchView';
|
|
321
|
+
case 'html':
|
|
322
|
+
return 'sketch-component';
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
//# sourceMappingURL=sketch-to-code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sketch-to-code.js","sourceRoot":"","sources":["../../../src/tools/design/sketch-to-code.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Architecture Diagram Tool
|
|
3
|
+
*
|
|
4
|
+
* Generates architecture diagrams from text descriptions using Gemini.
|
|
5
|
+
* Supports multiple output formats: PNG (visual), SVG, or Mermaid (text-based).
|
|
6
|
+
*/
|
|
7
|
+
import { type ToolDefinition } from '@opencode-ai/plugin/tool';
|
|
8
|
+
/**
|
|
9
|
+
* Tool definition for generate_architecture_diagram
|
|
10
|
+
*/
|
|
11
|
+
export declare const generateArchitectureDiagramTool: ToolDefinition;
|
|
12
|
+
//# sourceMappingURL=architecture-diagram.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"architecture-diagram.d.ts","sourceRoot":"","sources":["../../../src/tools/docs/architecture-diagram.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAmGrE;;GAEG;AACH,eAAO,MAAM,+BAA+B,EAAE,cAgG5C,CAAC"}
|