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.
Files changed (179) hide show
  1. package/.ralph-events.json +151 -0
  2. package/.ralph-last-branch +1 -0
  3. package/.ralph-monitor-state.json +7 -0
  4. package/.ralph-monitor.pid +1 -0
  5. package/.ralph-timing.json +26 -0
  6. package/README.md +708 -0
  7. package/dist/index.d.ts +18 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +21 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/platforms/android.d.ts +94 -0
  12. package/dist/platforms/android.d.ts.map +1 -0
  13. package/dist/platforms/android.js +123 -0
  14. package/dist/platforms/android.js.map +1 -0
  15. package/dist/platforms/ios.d.ts +51 -0
  16. package/dist/platforms/ios.d.ts.map +1 -0
  17. package/dist/platforms/ios.js +149 -0
  18. package/dist/platforms/ios.js.map +1 -0
  19. package/dist/platforms/macos.d.ts +33 -0
  20. package/dist/platforms/macos.d.ts.map +1 -0
  21. package/dist/platforms/macos.js +50 -0
  22. package/dist/platforms/macos.js.map +1 -0
  23. package/dist/platforms/watchos.d.ts +36 -0
  24. package/dist/platforms/watchos.d.ts.map +1 -0
  25. package/dist/platforms/watchos.js +113 -0
  26. package/dist/platforms/watchos.js.map +1 -0
  27. package/dist/platforms/web.d.ts +64 -0
  28. package/dist/platforms/web.d.ts.map +1 -0
  29. package/dist/platforms/web.js +96 -0
  30. package/dist/platforms/web.js.map +1 -0
  31. package/dist/providers/gemini.d.ts +41 -0
  32. package/dist/providers/gemini.d.ts.map +1 -0
  33. package/dist/providers/gemini.js +177 -0
  34. package/dist/providers/gemini.js.map +1 -0
  35. package/dist/tools/analyze/compare.d.ts +12 -0
  36. package/dist/tools/analyze/compare.d.ts.map +1 -0
  37. package/dist/tools/analyze/compare.js +83 -0
  38. package/dist/tools/analyze/compare.js.map +1 -0
  39. package/dist/tools/analyze/mockup.d.ts +12 -0
  40. package/dist/tools/analyze/mockup.d.ts.map +1 -0
  41. package/dist/tools/analyze/mockup.js +88 -0
  42. package/dist/tools/analyze/mockup.js.map +1 -0
  43. package/dist/tools/analyze/screenshot.d.ts +12 -0
  44. package/dist/tools/analyze/screenshot.d.ts.map +1 -0
  45. package/dist/tools/analyze/screenshot.js +61 -0
  46. package/dist/tools/analyze/screenshot.js.map +1 -0
  47. package/dist/tools/app-assets/app-icon.d.ts +9 -0
  48. package/dist/tools/app-assets/app-icon.d.ts.map +1 -0
  49. package/dist/tools/app-assets/app-icon.js +133 -0
  50. package/dist/tools/app-assets/app-icon.js.map +1 -0
  51. package/dist/tools/app-assets/device-mockup.d.ts +9 -0
  52. package/dist/tools/app-assets/device-mockup.d.ts.map +1 -0
  53. package/dist/tools/app-assets/device-mockup.js +139 -0
  54. package/dist/tools/app-assets/device-mockup.js.map +1 -0
  55. package/dist/tools/app-assets/launch-images.d.ts +3 -0
  56. package/dist/tools/app-assets/launch-images.d.ts.map +1 -0
  57. package/dist/tools/app-assets/launch-images.js +171 -0
  58. package/dist/tools/app-assets/launch-images.js.map +1 -0
  59. package/dist/tools/app-assets/resize-devices.d.ts +14 -0
  60. package/dist/tools/app-assets/resize-devices.d.ts.map +1 -0
  61. package/dist/tools/app-assets/resize-devices.js +296 -0
  62. package/dist/tools/app-assets/resize-devices.js.map +1 -0
  63. package/dist/tools/app-assets/screenshots.d.ts +14 -0
  64. package/dist/tools/app-assets/screenshots.d.ts.map +1 -0
  65. package/dist/tools/app-assets/screenshots.js +186 -0
  66. package/dist/tools/app-assets/screenshots.js.map +1 -0
  67. package/dist/tools/core/edit-image.d.ts +12 -0
  68. package/dist/tools/core/edit-image.d.ts.map +1 -0
  69. package/dist/tools/core/edit-image.js +102 -0
  70. package/dist/tools/core/edit-image.js.map +1 -0
  71. package/dist/tools/core/generate-image.d.ts +12 -0
  72. package/dist/tools/core/generate-image.d.ts.map +1 -0
  73. package/dist/tools/core/generate-image.js +96 -0
  74. package/dist/tools/core/generate-image.js.map +1 -0
  75. package/dist/tools/core/restore-image.d.ts +12 -0
  76. package/dist/tools/core/restore-image.d.ts.map +1 -0
  77. package/dist/tools/core/restore-image.js +104 -0
  78. package/dist/tools/core/restore-image.js.map +1 -0
  79. package/dist/tools/design/mockup-to-code.d.ts +3 -0
  80. package/dist/tools/design/mockup-to-code.d.ts.map +1 -0
  81. package/dist/tools/design/mockup-to-code.js +311 -0
  82. package/dist/tools/design/mockup-to-code.js.map +1 -0
  83. package/dist/tools/design/sketch-to-code.d.ts +3 -0
  84. package/dist/tools/design/sketch-to-code.d.ts.map +1 -0
  85. package/dist/tools/design/sketch-to-code.js +325 -0
  86. package/dist/tools/design/sketch-to-code.js.map +1 -0
  87. package/dist/tools/docs/architecture-diagram.d.ts +12 -0
  88. package/dist/tools/docs/architecture-diagram.d.ts.map +1 -0
  89. package/dist/tools/docs/architecture-diagram.js +179 -0
  90. package/dist/tools/docs/architecture-diagram.js.map +1 -0
  91. package/dist/tools/docs/readme-banner.d.ts +6 -0
  92. package/dist/tools/docs/readme-banner.d.ts.map +1 -0
  93. package/dist/tools/docs/readme-banner.js +108 -0
  94. package/dist/tools/docs/readme-banner.js.map +1 -0
  95. package/dist/tools/docs/sequence-diagram.d.ts +12 -0
  96. package/dist/tools/docs/sequence-diagram.d.ts.map +1 -0
  97. package/dist/tools/docs/sequence-diagram.js +161 -0
  98. package/dist/tools/docs/sequence-diagram.js.map +1 -0
  99. package/dist/tools/docs/social-preview.d.ts +11 -0
  100. package/dist/tools/docs/social-preview.d.ts.map +1 -0
  101. package/dist/tools/docs/social-preview.js +111 -0
  102. package/dist/tools/docs/social-preview.js.map +1 -0
  103. package/dist/tools/video/extend-video.d.ts +14 -0
  104. package/dist/tools/video/extend-video.d.ts.map +1 -0
  105. package/dist/tools/video/extend-video.js +39 -0
  106. package/dist/tools/video/extend-video.js.map +1 -0
  107. package/dist/tools/video/generate-video.d.ts +14 -0
  108. package/dist/tools/video/generate-video.d.ts.map +1 -0
  109. package/dist/tools/video/generate-video.js +39 -0
  110. package/dist/tools/video/generate-video.js.map +1 -0
  111. package/dist/tools/video/image-to-video.d.ts +15 -0
  112. package/dist/tools/video/image-to-video.d.ts.map +1 -0
  113. package/dist/tools/video/image-to-video.js +42 -0
  114. package/dist/tools/video/image-to-video.js.map +1 -0
  115. package/dist/tools/video/storyboard-video.d.ts +91 -0
  116. package/dist/tools/video/storyboard-video.d.ts.map +1 -0
  117. package/dist/tools/video/storyboard-video.js +230 -0
  118. package/dist/tools/video/storyboard-video.js.map +1 -0
  119. package/dist/utils/ffmpeg.d.ts +30 -0
  120. package/dist/utils/ffmpeg.d.ts.map +1 -0
  121. package/dist/utils/ffmpeg.js +205 -0
  122. package/dist/utils/ffmpeg.js.map +1 -0
  123. package/dist/utils/file-handler.d.ts +7 -0
  124. package/dist/utils/file-handler.d.ts.map +1 -0
  125. package/dist/utils/file-handler.js +10 -0
  126. package/dist/utils/file-handler.js.map +1 -0
  127. package/dist/utils/image-processing.d.ts +7 -0
  128. package/dist/utils/image-processing.d.ts.map +1 -0
  129. package/dist/utils/image-processing.js +10 -0
  130. package/dist/utils/image-processing.js.map +1 -0
  131. package/docs/PLUGIN-VERIFICATION.md +182 -0
  132. package/logs/notifications.jsonl +46 -0
  133. package/package.json +61 -0
  134. package/prd.json +216 -0
  135. package/progress.txt +145 -0
  136. package/ralph-report.html +297 -0
  137. package/src/index.ts +23 -0
  138. package/src/platforms/android/.gitkeep +0 -0
  139. package/src/platforms/ios/.gitkeep +0 -0
  140. package/src/platforms/web/.gitkeep +0 -0
  141. package/src/providers/.gitkeep +0 -0
  142. package/src/providers/gemini.ts +288 -0
  143. package/src/tools/core/.gitkeep +0 -0
  144. package/src/tools/platform/.gitkeep +0 -0
  145. package/src/tools/video/extend-video.ts +71 -0
  146. package/src/tools/video/generate-video.ts +70 -0
  147. package/src/tools/video/image-to-video.ts +76 -0
  148. package/src/tools/video/storyboard-video.ts +325 -0
  149. package/src/utils/.gitkeep +0 -0
  150. package/src/utils/ffmpeg.ts +266 -0
  151. package/src/utils/file-handler.ts +10 -0
  152. package/src/utils/image-processing.ts +10 -0
  153. package/templates/.gitkeep +0 -0
  154. package/test-analyze-screenshot.ts +50 -0
  155. package/test-app-icons.ts +55 -0
  156. package/test-cat-sunset.ts +30 -0
  157. package/test-full-plugin.ts +88 -0
  158. package/test-icon-gen.ts +30 -0
  159. package/test-output/test-edit.png +0 -0
  160. package/test-output/test-generate.png +0 -0
  161. package/test-output/test-video.mp4 +0 -0
  162. package/test-plugin-load.js +45 -0
  163. package/test-princess-emma-continue.ts +35 -0
  164. package/test-princess-emma-full.ts +38 -0
  165. package/test-princess-emma-short.ts +32 -0
  166. package/test-princess-emma-with-reference.ts +34 -0
  167. package/test-princess-emma.ts +38 -0
  168. package/test-product-ad.ts +66 -0
  169. package/test-ralph-droid.ts +30 -0
  170. package/test-social-preview.ts +61 -0
  171. package/test-veo31-live.ts +187 -0
  172. package/test-video-gen.ts +40 -0
  173. package/test-video-veo.ts +73 -0
  174. package/test-zurich-video.ts +64 -0
  175. package/tests/.gitkeep +0 -0
  176. package/tests/providers/gemini.test.ts +388 -0
  177. package/tests/utils/ffmpeg.test.ts +328 -0
  178. package/tests/video/storyboard.test.ts +469 -0
  179. package/tsconfig.json +25 -0
@@ -0,0 +1,179 @@
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 { tool } from '@opencode-ai/plugin/tool';
8
+ import { GeminiProvider } from '../../providers/gemini.js';
9
+ import { saveImage, getOutputDir } from '../../utils/file-handler.js';
10
+ /**
11
+ * Tool args schema
12
+ */
13
+ const architectureDiagramArgs = {
14
+ description: tool.schema.string()
15
+ .describe('Description of the architecture to diagram (components, relationships, data flows)'),
16
+ style: tool.schema.enum(['boxes', 'cloud', 'technical'])
17
+ .optional()
18
+ .describe('Visual style for the diagram. Options: boxes (clean box diagrams), cloud (cloud architecture), technical (detailed technical). Defaults to "technical"'),
19
+ format: tool.schema.enum(['png', 'svg', 'mermaid'])
20
+ .optional()
21
+ .describe('Output format. Options: png (image via Gemini), svg (vector image), mermaid (text-based diagram code). Defaults to "png"'),
22
+ outputPath: tool.schema.string()
23
+ .optional()
24
+ .describe('Custom output directory path. Defaults to "./generated-assets"')
25
+ };
26
+ /**
27
+ * Generate Mermaid diagram code from description
28
+ */
29
+ function generateMermaidDiagram(description) {
30
+ // For mermaid format, return a basic template with the description
31
+ // In a real scenario, you might use Gemini to analyze the description
32
+ // and generate proper Mermaid syntax
33
+ const firstLine = description.split('\n')[0] || description;
34
+ const truncatedFirstLine = firstLine.slice(0, 50);
35
+ return `\`\`\`mermaid
36
+ graph TB
37
+ %% Architecture Diagram: ${truncatedFirstLine}...
38
+
39
+ A[Component A] --> B[Component B]
40
+ B --> C[Component C]
41
+ C --> D[Component D]
42
+ A --> D
43
+
44
+ %% Note: This is a template diagram.
45
+ %% For detailed diagrams, use the 'png' or 'svg' format option.
46
+ %% Description provided: ${description}
47
+ \`\`\`
48
+
49
+ **Instructions:**
50
+ 1. Copy the Mermaid code above
51
+ 2. Paste it into a Mermaid renderer (GitHub, Mermaid Live Editor, etc.)
52
+ 3. Customize the diagram based on your architecture requirements
53
+
54
+ **Description provided:** ${description}
55
+ `;
56
+ }
57
+ /**
58
+ * Build prompt for Gemini based on style
59
+ */
60
+ function buildArchitecturePrompt(description, style) {
61
+ const basePrompt = `Create a professional architecture diagram based on the following description:\n\n${description}\n\n`;
62
+ const stylePrompts = {
63
+ boxes: `Style: Clean box diagram with:
64
+ - Simple rectangular boxes for components
65
+ - Clear, labeled arrows showing relationships and data flow
66
+ - Minimal colors (use white/light gray boxes with black text)
67
+ - Clean, professional layout with good spacing
68
+ - Component names clearly visible
69
+ - Connection labels showing data/control flow`,
70
+ cloud: `Style: Cloud architecture diagram with:
71
+ - Cloud-native visual elements (rounded shapes, cloud icons)
72
+ - Layer separation (presentation, application, data, infrastructure)
73
+ - Cloud service icons or placeholders
74
+ - Modern gradient colors (blues, grays, whites)
75
+ - Clear service boundaries and regions
76
+ - Network connections between services`,
77
+ technical: `Style: Detailed technical diagram with:
78
+ - Component boxes with technology stack labels
79
+ - Ports and interfaces clearly marked
80
+ - Protocol labels on connections (HTTP, TCP, etc.)
81
+ - Database and storage symbols
82
+ - Network layers and boundaries
83
+ - Security zones if applicable
84
+ - Detailed annotations and technical specifications`
85
+ };
86
+ const styleGuide = stylePrompts[style] || stylePrompts.technical;
87
+ return `${basePrompt}${styleGuide}
88
+
89
+ Requirements:
90
+ - Professional quality suitable for technical documentation
91
+ - Clear visual hierarchy
92
+ - All components and connections labeled
93
+ - Readable at standard document sizes
94
+ - High contrast for clarity`;
95
+ }
96
+ /**
97
+ * Tool definition for generate_architecture_diagram
98
+ */
99
+ export const generateArchitectureDiagramTool = tool({
100
+ description: 'Generate architecture diagrams from text descriptions. Supports multiple styles (boxes, cloud, technical) and formats (PNG, SVG, Mermaid).',
101
+ args: architectureDiagramArgs,
102
+ async execute(args, _context) {
103
+ try {
104
+ const { description, style = 'technical', format = 'png', outputPath } = args;
105
+ // Handle Mermaid format separately (no Gemini needed)
106
+ if (format === 'mermaid') {
107
+ const mermaidCode = generateMermaidDiagram(description);
108
+ return [
109
+ '✓ Generated Mermaid diagram code',
110
+ '',
111
+ mermaidCode,
112
+ '',
113
+ 'Note: Mermaid diagrams are text-based and can be rendered in:',
114
+ ' • GitHub markdown files',
115
+ ' • Mermaid Live Editor (https://mermaid.live)',
116
+ ' • Documentation tools that support Mermaid',
117
+ '',
118
+ 'For visual diagrams, use format: "png" or "svg"'
119
+ ].join('\n');
120
+ }
121
+ // For PNG/SVG formats, use Gemini
122
+ const provider = new GeminiProvider();
123
+ const outputDir = outputPath || getOutputDir();
124
+ // Build architecture-specific prompt
125
+ const prompt = buildArchitecturePrompt(description, style);
126
+ // Generate diagram using Gemini
127
+ // Note: Gemini generates images, SVG support would require post-processing
128
+ // For now, we'll generate PNG for both png and svg formats
129
+ const imageBuffers = await provider.generateImage(prompt, {
130
+ aspectRatio: '16:9', // Wide format for architecture diagrams
131
+ count: 1
132
+ });
133
+ const buffer = imageBuffers[0];
134
+ if (!buffer) {
135
+ throw new Error('Failed to generate architecture diagram');
136
+ }
137
+ // Save the diagram
138
+ const filename = format === 'svg' ? 'architecture-diagram' : 'architecture-diagram';
139
+ const filepath = await saveImage(buffer, outputDir, filename, 0);
140
+ // SVG note if requested
141
+ const formatNote = format === 'svg'
142
+ ? '\n\nNote: Generated as PNG. For true SVG, consider using Mermaid format or converting with external tools.'
143
+ : '';
144
+ return [
145
+ '✓ Successfully generated architecture diagram',
146
+ '',
147
+ `Saved to: ${filepath}`,
148
+ '',
149
+ `Style: ${style}`,
150
+ `Format: ${format}`,
151
+ `Description: ${description.slice(0, 100)}${description.length > 100 ? '...' : ''}`,
152
+ formatNote
153
+ ].join('\n');
154
+ }
155
+ catch (error) {
156
+ if (error instanceof Error) {
157
+ if (error.message.includes('GEMINI_API_KEY')) {
158
+ return [
159
+ '✗ Error: Gemini API key not found',
160
+ '',
161
+ 'Please set your GEMINI_API_KEY environment variable.',
162
+ 'Get your API key at: https://makersuite.google.com/app/apikey',
163
+ '',
164
+ 'Alternative: Use format "mermaid" for text-based diagrams (no API key required)'
165
+ ].join('\n');
166
+ }
167
+ return [
168
+ '✗ Architecture diagram generation failed',
169
+ '',
170
+ `Error: ${error.message}`,
171
+ '',
172
+ 'Please check your description and try again.'
173
+ ].join('\n');
174
+ }
175
+ return '✗ Architecture diagram generation failed with an unknown error';
176
+ }
177
+ }
178
+ });
179
+ //# sourceMappingURL=architecture-diagram.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"architecture-diagram.js","sourceRoot":"","sources":["../../../src/tools/docs/architecture-diagram.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type ToolDefinition } from '@opencode-ai/plugin/tool';
2
+ /**
3
+ * Tool definition for generate_readme_banner
4
+ */
5
+ export declare const generateReadmeBannerTool: ToolDefinition;
6
+ //# sourceMappingURL=readme-banner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readme-banner.d.ts","sourceRoot":"","sources":["../../../src/tools/docs/readme-banner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAwErE;;GAEG;AACH,eAAO,MAAM,wBAAwB,EAAE,cAwDZ,CAAC"}
@@ -0,0 +1,108 @@
1
+ import { tool } from '@opencode-ai/plugin/tool';
2
+ import { GeminiProvider } from '../../providers/gemini.js';
3
+ import { saveImage, getOutputDir } from '../../utils/file-handler.js';
4
+ /**
5
+ * Tool args schema
6
+ */
7
+ const readmeBannerArgs = {
8
+ projectName: tool.schema
9
+ .string()
10
+ .describe('The name of the project'),
11
+ tagline: tool.schema
12
+ .string()
13
+ .optional()
14
+ .describe('Optional tagline or description for the project'),
15
+ style: tool.schema
16
+ .enum(['gradient', 'minimal', 'tech'])
17
+ .optional()
18
+ .describe('Visual style for the banner: gradient (modern colorful), minimal (clean simple), tech (developer-focused). Default: gradient'),
19
+ outputPath: tool.schema
20
+ .string()
21
+ .optional()
22
+ .describe('Custom output path for the banner'),
23
+ };
24
+ /**
25
+ * Build a style-specific prompt for README banner generation
26
+ */
27
+ function buildBannerPrompt(projectName, tagline, style) {
28
+ const basePrompt = `Create a professional README banner for the project "${projectName}"${tagline ? ` with the tagline: "${tagline}"` : ''}. `;
29
+ const stylePrompts = {
30
+ gradient: `Use a modern gradient background (purple to blue or teal to cyan).
31
+ Include the project name in large, bold, white text centered on the banner.
32
+ ${tagline ? `Add the tagline in smaller text below the project name.` : ''}
33
+ Make it eye-catching and suitable for GitHub README files.
34
+ Use smooth gradients, subtle geometric shapes, and modern typography.`,
35
+ minimal: `Use a clean, minimal design with a white or very light gray background.
36
+ Display the project name in a bold, sans-serif font in dark gray or black.
37
+ ${tagline ? `Add the tagline in a lighter weight font below the project name.` : ''}
38
+ Keep the design simple and professional with lots of whitespace.
39
+ No decorative elements - focus on typography and clarity.`,
40
+ tech: `Create a technical, developer-focused banner with a dark background (dark blue or charcoal).
41
+ Include subtle code-like elements (brackets, slashes, dots) as decorative accents.
42
+ Display the project name in a monospace or technical font in bright green, cyan, or white.
43
+ ${tagline ? `Add the tagline in a complementary color below the project name.` : ''}
44
+ Use grid patterns, terminal aesthetics, or circuit board motifs for a tech feel.
45
+ Make it appealing to developers and technical audiences.`,
46
+ };
47
+ const styleGuide = stylePrompts[style] || stylePrompts.gradient;
48
+ return `${basePrompt}${styleGuide}
49
+
50
+ Requirements:
51
+ - Banner size should be wide (2:1 aspect ratio, ideal for GitHub)
52
+ - High quality, professional appearance
53
+ - Text must be clearly readable
54
+ - Centered composition
55
+ - Suitable for use at the top of README.md files`;
56
+ }
57
+ /**
58
+ * Tool definition for generate_readme_banner
59
+ */
60
+ export const generateReadmeBannerTool = tool({
61
+ description: 'Generate a professional README banner image for your project with customizable styles (gradient, minimal, tech). Creates 1280x640 images optimized for GitHub.',
62
+ args: readmeBannerArgs,
63
+ async execute(args, _context) {
64
+ try {
65
+ const projectName = args.projectName;
66
+ const tagline = args.tagline || '';
67
+ const style = args.style || 'gradient';
68
+ const outputPath = args.outputPath;
69
+ const provider = new GeminiProvider();
70
+ // Build style-specific prompt
71
+ const prompt = buildBannerPrompt(projectName, tagline, style);
72
+ // Generate 1280x640 banner (2:1 aspect ratio, standard for GitHub)
73
+ // Use 16:9 as closest available aspect ratio to 2:1 for wide banners
74
+ const images = await provider.generateImage(prompt, {
75
+ aspectRatio: '16:9',
76
+ count: 1,
77
+ });
78
+ if (images.length === 0) {
79
+ return '❌ Failed to generate README banner';
80
+ }
81
+ const buffer = images[0];
82
+ if (!buffer) {
83
+ return '❌ Failed to generate README banner';
84
+ }
85
+ // Save the banner
86
+ const outputDir = outputPath || getOutputDir();
87
+ const filename = `${projectName.toLowerCase().replace(/\s+/g, '-')}-banner`;
88
+ const savedPath = await saveImage(buffer, outputDir, filename, 0);
89
+ return `✅ README banner generated successfully!
90
+ Style: ${style}
91
+ Size: 1280x640 (optimized for GitHub)
92
+ Saved to: ${savedPath}
93
+
94
+ Add to your README.md:
95
+ ![${projectName}](${savedPath})`;
96
+ }
97
+ catch (error) {
98
+ if (error instanceof Error) {
99
+ if (error.message.includes('API key')) {
100
+ return '❌ Gemini API key not configured. Set GEMINI_API_KEY environment variable.';
101
+ }
102
+ return `❌ Error generating README banner: ${error.message}`;
103
+ }
104
+ return '❌ Unknown error generating README banner';
105
+ }
106
+ },
107
+ });
108
+ //# sourceMappingURL=readme-banner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readme-banner.js","sourceRoot":"","sources":["../../../src/tools/docs/readme-banner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Sequence Diagram Tool
3
+ *
4
+ * Generates sequence diagrams from text descriptions using Gemini.
5
+ * Supports multiple output formats: PNG (visual) or Mermaid (text-based).
6
+ */
7
+ import { type ToolDefinition } from '@opencode-ai/plugin/tool';
8
+ /**
9
+ * Tool definition for generate_sequence_diagram
10
+ */
11
+ export declare const generateSequenceDiagramTool: ToolDefinition;
12
+ //# sourceMappingURL=sequence-diagram.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sequence-diagram.d.ts","sourceRoot":"","sources":["../../../src/tools/docs/sequence-diagram.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAqGpE;;GAEG;AACH,eAAO,MAAM,2BAA2B,EAAE,cAoExC,CAAA"}
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Sequence Diagram Tool
3
+ *
4
+ * Generates sequence diagrams from text descriptions using Gemini.
5
+ * Supports multiple output formats: PNG (visual) or Mermaid (text-based).
6
+ */
7
+ import { tool } from '@opencode-ai/plugin/tool';
8
+ import { GeminiProvider } from '../../providers/gemini.js';
9
+ import { saveImage, getOutputDir } from '../../utils/file-handler.js';
10
+ /**
11
+ * Tool args schema
12
+ */
13
+ const sequenceDiagramArgs = {
14
+ description: tool.schema
15
+ .string()
16
+ .describe('Description of the sequence/interaction flow to diagram'),
17
+ format: tool.schema
18
+ .enum(['png', 'mermaid'])
19
+ .optional()
20
+ .describe('Output format: png (visual image) or mermaid (text-based code). Default: png'),
21
+ outputPath: tool.schema
22
+ .string()
23
+ .optional()
24
+ .describe('Custom output path for the generated diagram'),
25
+ };
26
+ /**
27
+ * Generate Mermaid sequence diagram code
28
+ */
29
+ function generateMermaidSequence(description) {
30
+ // Extract first line or first sentence for title
31
+ const firstLine = description.split('\n')[0] || description;
32
+ const truncatedFirstLine = firstLine.slice(0, 50);
33
+ return `\`\`\`mermaid
34
+ sequenceDiagram
35
+ title ${truncatedFirstLine}...
36
+
37
+ %% Define participants
38
+ participant User
39
+ participant System
40
+ participant Service
41
+ participant Database
42
+
43
+ %% Sequence flow - customize based on your description
44
+ User->>System: Request
45
+ activate System
46
+ System->>Service: Process Request
47
+ activate Service
48
+ Service->>Database: Query Data
49
+ activate Database
50
+ Database-->>Service: Return Data
51
+ deactivate Database
52
+ Service-->>System: Processed Result
53
+ deactivate Service
54
+ System-->>User: Response
55
+ deactivate System
56
+
57
+ %% Notes and customization:
58
+ %% - Replace participant names with actual actors from: ${description}
59
+ %% - Add more participants as needed
60
+ %% - Use ->> for synchronous calls, -->> for responses
61
+ %% - Use activate/deactivate for execution blocks
62
+ %% - Add 'alt', 'opt', 'loop' for control flow
63
+ %% - Example alt: alt condition
64
+ %% ...
65
+ %% else other condition
66
+ %% ...
67
+ %% end
68
+ \`\`\`
69
+
70
+ **Instructions:**
71
+ 1. Copy the Mermaid code above
72
+ 2. Paste it into a Mermaid renderer (GitHub, Mermaid Live Editor, etc.)
73
+ 3. Customize the diagram based on your sequence flow requirements
74
+
75
+ **Description provided:** ${description}
76
+ `;
77
+ }
78
+ /**
79
+ * Build prompt for Gemini
80
+ */
81
+ function buildSequencePrompt(description) {
82
+ const basePrompt = `Create a professional sequence diagram showing the following interaction flow:\n\n${description}\n\n`;
83
+ const requirements = `Requirements:
84
+ - Clear swimlanes for each actor/system/component
85
+ - Arrows showing message flow with descriptive labels
86
+ - Time flows from top to bottom
87
+ - Include activation boxes where actors are processing
88
+ - Use different line styles for synchronous (solid) vs asynchronous (dashed) calls
89
+ - Add return messages where appropriate
90
+ - Include alt/opt/loop frames for conditional/optional/repeated flows
91
+ - Clean, professional appearance suitable for technical documentation
92
+ - Use a neutral color palette (blues, grays) with good contrast
93
+ - Label all interactions clearly
94
+ - Show any error/exception flows if relevant
95
+
96
+ Style: Technical sequence diagram following UML conventions`;
97
+ return `${basePrompt}${requirements}`;
98
+ }
99
+ /**
100
+ * Tool definition for generate_sequence_diagram
101
+ */
102
+ export const generateSequenceDiagramTool = tool({
103
+ description: 'Generate a sequence diagram showing interaction flows between actors/systems. Supports visual (PNG) and text-based (Mermaid) formats for documentation.',
104
+ args: sequenceDiagramArgs,
105
+ async execute(args, _context) {
106
+ try {
107
+ const { description, format = 'png', outputPath } = args;
108
+ // Handle Mermaid format (no API key needed)
109
+ if (format === 'mermaid') {
110
+ const mermaidCode = generateMermaidSequence(description);
111
+ // Save to file if outputPath provided
112
+ if (outputPath) {
113
+ const fs = await import('fs/promises');
114
+ await fs.writeFile(outputPath, mermaidCode, 'utf-8');
115
+ return `✓ Mermaid sequence diagram generated and saved to ${outputPath}\n\nYou can render this diagram on GitHub, in documentation, or using Mermaid Live Editor (https://mermaid.live).`;
116
+ }
117
+ // Return code directly
118
+ return `✓ Mermaid sequence diagram generated:\n\n${mermaidCode}\n\nYou can render this diagram on GitHub, in documentation, or using Mermaid Live Editor (https://mermaid.live).`;
119
+ }
120
+ // Handle PNG format (requires Gemini API)
121
+ const gemini = new GeminiProvider();
122
+ const prompt = buildSequencePrompt(description);
123
+ // Generate sequence diagram image with 16:9 aspect ratio
124
+ const images = await gemini.generateImage(prompt, {
125
+ aspectRatio: '16:9',
126
+ count: 1,
127
+ });
128
+ if (!images || images.length === 0) {
129
+ return '✗ Failed to generate sequence diagram image. No images returned from API.';
130
+ }
131
+ const imageBuffer = images[0];
132
+ if (!imageBuffer) {
133
+ return '✗ Failed to generate sequence diagram image. Image data is missing.';
134
+ }
135
+ // Save the diagram
136
+ let savePath;
137
+ if (outputPath) {
138
+ const fs = await import('fs/promises');
139
+ const path = await import('path');
140
+ await fs.mkdir(path.dirname(outputPath), { recursive: true });
141
+ await fs.writeFile(outputPath, imageBuffer);
142
+ savePath = outputPath;
143
+ }
144
+ else {
145
+ const outputDir = getOutputDir();
146
+ savePath = await saveImage(imageBuffer, outputDir, 'sequence-diagram', 0);
147
+ }
148
+ return `✓ Sequence diagram generated and saved to ${savePath}`;
149
+ }
150
+ catch (error) {
151
+ if (error instanceof Error) {
152
+ if (error.message.includes('API key')) {
153
+ return '✗ Gemini API key not found. Set GEMINI_API_KEY environment variable or use format="mermaid" for text-based diagrams.';
154
+ }
155
+ return `✗ Failed to generate sequence diagram: ${error.message}`;
156
+ }
157
+ return '✗ An unexpected error occurred while generating the sequence diagram.';
158
+ }
159
+ },
160
+ });
161
+ //# sourceMappingURL=sequence-diagram.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sequence-diagram.js","sourceRoot":"","sources":["../../../src/tools/docs/sequence-diagram.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { type ToolDefinition } from '@opencode-ai/plugin/tool';
2
+ /**
3
+ * Generate Social Preview (Open Graph) Image Tool
4
+ *
5
+ * Creates 1200x630 Open Graph images for social media sharing (Facebook, Twitter, LinkedIn).
6
+ * These images appear when your project is shared on social platforms.
7
+ *
8
+ * Open Graph standard size: 1200x630 pixels (1.91:1 aspect ratio)
9
+ */
10
+ export declare const generateSocialPreview: ToolDefinition;
11
+ //# sourceMappingURL=social-preview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"social-preview.d.ts","sourceRoot":"","sources":["../../../src/tools/docs/social-preview.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAiBrE;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,EAAE,cA2DlC,CAAC"}
@@ -0,0 +1,111 @@
1
+ import { tool } from '@opencode-ai/plugin/tool';
2
+ import { GeminiProvider } from '../../providers/gemini.js';
3
+ import { saveImage, getOutputDir } from '../../utils/file-handler.js';
4
+ const socialPreviewArgs = {
5
+ projectName: tool.schema.string().describe('The name of the project'),
6
+ description: tool.schema.string().optional().describe('A brief description or tagline for the project'),
7
+ style: tool.schema
8
+ .enum(['gradient', 'minimal', 'bold'])
9
+ .optional()
10
+ .describe("Visual style for the preview: 'gradient' (colorful modern), 'minimal' (clean simple), or 'bold' (high-contrast attention-grabbing)"),
11
+ outputPath: tool.schema
12
+ .string()
13
+ .optional()
14
+ .describe('Optional custom output path for the social preview image'),
15
+ };
16
+ /**
17
+ * Generate Social Preview (Open Graph) Image Tool
18
+ *
19
+ * Creates 1200x630 Open Graph images for social media sharing (Facebook, Twitter, LinkedIn).
20
+ * These images appear when your project is shared on social platforms.
21
+ *
22
+ * Open Graph standard size: 1200x630 pixels (1.91:1 aspect ratio)
23
+ */
24
+ export const generateSocialPreview = tool({
25
+ description: 'Generate a social media preview (Open Graph) image for project sharing',
26
+ args: socialPreviewArgs,
27
+ execute: async (args, _context) => {
28
+ try {
29
+ // Extract arguments with defaults
30
+ const projectName = args.projectName;
31
+ const description = args.description || '';
32
+ const style = args.style || 'gradient';
33
+ const customOutputPath = args.outputPath;
34
+ // Initialize Gemini provider
35
+ const gemini = new GeminiProvider();
36
+ // Build the generation prompt based on style
37
+ const prompt = buildSocialPreviewPrompt(projectName, description, style);
38
+ // Generate the social preview image (1200x630 = 1.91:1, use 16:9 as closest Gemini option)
39
+ const imageBuffers = await gemini.generateImage(prompt, {
40
+ aspectRatio: '16:9', // Closest to 1.91:1
41
+ count: 1,
42
+ });
43
+ if (imageBuffers.length === 0) {
44
+ return '❌ Failed to generate social preview image';
45
+ }
46
+ const buffer = imageBuffers[0];
47
+ if (!buffer) {
48
+ return '❌ Failed to generate social preview image';
49
+ }
50
+ // Save the image
51
+ const outputDir = customOutputPath || getOutputDir();
52
+ const filename = `${projectName.toLowerCase().replace(/\s+/g, '-')}-social-preview`;
53
+ const savedPath = await saveImage(buffer, outputDir, filename, 0);
54
+ // Return success message with usage instructions
55
+ return `✅ Generated ${style} style social preview (1200x630) at: ${savedPath}
56
+
57
+ 📝 Add this to your HTML <head>:
58
+ \`\`\`html
59
+ <meta property="og:image" content="${savedPath}" />
60
+ <meta property="og:title" content="${projectName}" />
61
+ <meta property="og:description" content="${description || 'Your project description'}" />
62
+ <meta name="twitter:card" content="summary_large_image" />
63
+ \`\`\``;
64
+ }
65
+ catch (error) {
66
+ if (error instanceof Error && error.message.includes('API key')) {
67
+ return '❌ GEMINI_API_KEY environment variable is not set. Please configure your API key.';
68
+ }
69
+ return `❌ Error generating social preview: ${error instanceof Error ? error.message : String(error)}`;
70
+ }
71
+ },
72
+ });
73
+ /**
74
+ * Build style-specific generation prompt for social preview images
75
+ */
76
+ function buildSocialPreviewPrompt(projectName, description, style) {
77
+ const basePrompt = `Create a professional social media preview image (Open Graph) for a project called "${projectName}"${description ? ` with the description: "${description}"` : ''}.`;
78
+ const styleGuide = {
79
+ gradient: `
80
+ Use a modern gradient background (purple-to-blue, teal-to-cyan, or orange-to-pink).
81
+ Display the project name prominently in bold white text (large, sans-serif font).
82
+ ${description ? 'Show the description below in smaller white text.' : ''}
83
+ Add subtle geometric shapes or abstract elements in the background.
84
+ Create depth with overlapping gradients and soft shadows.
85
+ Professional, modern, eye-catching design suitable for social media.`,
86
+ minimal: `
87
+ Use a clean white or very light gray background.
88
+ Display the project name in bold, large black text (modern sans-serif).
89
+ ${description ? 'Show the description below in smaller dark gray text.' : ''}
90
+ Embrace whitespace - keep the design simple and uncluttered.
91
+ Add a single accent color (blue, teal, or purple) as a subtle line or dot.
92
+ Minimalist, professional, clean aesthetic.`,
93
+ bold: `
94
+ Use a high-contrast design with vibrant colors.
95
+ Dark background (navy blue, deep purple, or black) with bright accent colors.
96
+ Display the project name in extra-bold, large white or yellow text.
97
+ ${description ? 'Show the description in bright white text below.' : ''}
98
+ Add dramatic lighting effects, glows, or neon-style elements.
99
+ Create a strong visual impact - this should grab attention immediately.
100
+ Bold, modern, energetic design.`,
101
+ }[style];
102
+ return `${basePrompt}${styleGuide}
103
+
104
+ Requirements:
105
+ - Image must be in landscape orientation (wider than tall) at approximately 1200x630 pixels ratio
106
+ - Text must be large and highly readable even at small sizes
107
+ - Composition should be centered and balanced
108
+ - Professional quality suitable for social media sharing (Facebook, Twitter, LinkedIn)
109
+ - Design should work well as a thumbnail preview`;
110
+ }
111
+ //# sourceMappingURL=social-preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"social-preview.js","sourceRoot":"","sources":["../../../src/tools/docs/social-preview.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface ExtendVideoOptions {
2
+ videoPath: string;
3
+ prompt: string;
4
+ aspectRatio?: '16:9' | '9:16';
5
+ resolution?: '720p' | '1080p';
6
+ outputPath?: string;
7
+ apiKey: string;
8
+ }
9
+ export interface ExtendVideoResult {
10
+ videoPath: string;
11
+ generationTime: number;
12
+ }
13
+ export declare function extendVideo(options: ExtendVideoOptions): Promise<ExtendVideoResult>;
14
+ //# sourceMappingURL=extend-video.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extend-video.d.ts","sourceRoot":"","sources":["../../../src/tools/video/extend-video.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,iBAAiB,CAAC,CAiD5B"}