mcp-hydrocoder-image 1.0.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 (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +454 -0
  3. package/bin/install-skills.js +115 -0
  4. package/dist/api/geminiClient.d.ts +57 -0
  5. package/dist/api/geminiClient.d.ts.map +1 -0
  6. package/dist/api/geminiClient.js +341 -0
  7. package/dist/api/geminiClient.js.map +1 -0
  8. package/dist/api/geminiTextClient.d.ts +44 -0
  9. package/dist/api/geminiTextClient.d.ts.map +1 -0
  10. package/dist/api/geminiTextClient.js +202 -0
  11. package/dist/api/geminiTextClient.js.map +1 -0
  12. package/dist/business/fileManager.d.ts +20 -0
  13. package/dist/business/fileManager.d.ts.map +1 -0
  14. package/dist/business/fileManager.js +76 -0
  15. package/dist/business/fileManager.js.map +1 -0
  16. package/dist/business/inputValidator.d.ts +44 -0
  17. package/dist/business/inputValidator.d.ts.map +1 -0
  18. package/dist/business/inputValidator.js +213 -0
  19. package/dist/business/inputValidator.js.map +1 -0
  20. package/dist/business/responseBuilder.d.ts +21 -0
  21. package/dist/business/responseBuilder.d.ts.map +1 -0
  22. package/dist/business/responseBuilder.js +166 -0
  23. package/dist/business/responseBuilder.js.map +1 -0
  24. package/dist/business/structuredPromptGenerator.d.ts +56 -0
  25. package/dist/business/structuredPromptGenerator.d.ts.map +1 -0
  26. package/dist/business/structuredPromptGenerator.js +218 -0
  27. package/dist/business/structuredPromptGenerator.js.map +1 -0
  28. package/dist/index.d.ts +12 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +30 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/server/errorHandler.d.ts +29 -0
  33. package/dist/server/errorHandler.d.ts.map +1 -0
  34. package/dist/server/errorHandler.js +99 -0
  35. package/dist/server/errorHandler.js.map +1 -0
  36. package/dist/server/mcpServer.d.ts +159 -0
  37. package/dist/server/mcpServer.d.ts.map +1 -0
  38. package/dist/server/mcpServer.js +434 -0
  39. package/dist/server/mcpServer.js.map +1 -0
  40. package/dist/server-main.d.ts +5 -0
  41. package/dist/server-main.d.ts.map +1 -0
  42. package/dist/server-main.js +37 -0
  43. package/dist/server-main.js.map +1 -0
  44. package/dist/types/mcp.d.ts +121 -0
  45. package/dist/types/mcp.d.ts.map +1 -0
  46. package/dist/types/mcp.js +22 -0
  47. package/dist/types/mcp.js.map +1 -0
  48. package/dist/types/result.d.ts +27 -0
  49. package/dist/types/result.d.ts.map +1 -0
  50. package/dist/types/result.js +27 -0
  51. package/dist/types/result.js.map +1 -0
  52. package/dist/utils/config.d.ts +29 -0
  53. package/dist/utils/config.d.ts.map +1 -0
  54. package/dist/utils/config.js +56 -0
  55. package/dist/utils/config.js.map +1 -0
  56. package/dist/utils/errors.d.ts +84 -0
  57. package/dist/utils/errors.d.ts.map +1 -0
  58. package/dist/utils/errors.js +215 -0
  59. package/dist/utils/errors.js.map +1 -0
  60. package/dist/utils/logger.d.ts +80 -0
  61. package/dist/utils/logger.d.ts.map +1 -0
  62. package/dist/utils/logger.js +186 -0
  63. package/dist/utils/logger.js.map +1 -0
  64. package/dist/utils/security.d.ts +50 -0
  65. package/dist/utils/security.d.ts.map +1 -0
  66. package/dist/utils/security.js +116 -0
  67. package/dist/utils/security.js.map +1 -0
  68. package/package.json +89 -0
  69. package/skills/image-generation/SKILL.md +131 -0
@@ -0,0 +1,76 @@
1
+ /**
2
+ * File Manager for handling image file operations
3
+ * Provides functionality for saving images and managing directories
4
+ */
5
+ import { promises as fs, mkdirSync } from 'node:fs';
6
+ import * as path from 'node:path';
7
+ import { Err, Ok } from '../types/result.js';
8
+ import { FileOperationError } from '../utils/errors.js';
9
+ // Constants for file naming and error messages
10
+ const FILE_NAME_PREFIX = 'image';
11
+ const DEFAULT_EXTENSION = '.png';
12
+ const RANDOM_RANGE = 1000;
13
+ const ERROR_MESSAGES = {
14
+ SAVE_FAILED: 'Failed to save image file',
15
+ DIRECTORY_CREATION_FAILED: 'Failed to create directory',
16
+ PERMISSION_SUGGESTION: 'Check output directory permissions and disk space',
17
+ PATH_SUGGESTION: 'Check directory path validity and write permissions',
18
+ };
19
+ /**
20
+ * Ensures that the specified directory exists, creating it if necessary
21
+ * @param dirPath Path to the directory
22
+ * @returns Result indicating success or failure
23
+ */
24
+ function ensureDirectoryExists(dirPath) {
25
+ try {
26
+ // Use mkdirSync with recursive option to create all necessary parent directories
27
+ mkdirSync(dirPath, { recursive: true });
28
+ return Ok(undefined);
29
+ }
30
+ catch (error) {
31
+ return Err(new FileOperationError(`${ERROR_MESSAGES.DIRECTORY_CREATION_FAILED}: ${error instanceof Error ? error.message : 'Unknown error'}`));
32
+ }
33
+ }
34
+ /**
35
+ * Generates a unique filename based on timestamp and random component
36
+ * @returns Generated filename in the format: gemini-image-{timestamp}.png
37
+ */
38
+ function generateFileName() {
39
+ const timestamp = Date.now();
40
+ const random = Math.floor(Math.random() * RANDOM_RANGE);
41
+ return `${FILE_NAME_PREFIX}-${timestamp}-${random}${DEFAULT_EXTENSION}`;
42
+ }
43
+ /**
44
+ * Creates a file manager for image file operations
45
+ * @returns FileManager implementation
46
+ */
47
+ export function createFileManager() {
48
+ return {
49
+ /**
50
+ * Saves image data to the specified file path
51
+ * @param imageData Buffer containing the image data
52
+ * @param outputPath Absolute path where the image should be saved
53
+ * @param format Image format (used for validation)
54
+ * @returns Result containing the saved file path or an error
55
+ */
56
+ async saveImage(imageData, outputPath, _format) {
57
+ try {
58
+ // Ensure the directory exists
59
+ const directory = path.dirname(outputPath);
60
+ const dirResult = ensureDirectoryExists(directory);
61
+ if (!dirResult.success) {
62
+ return Err(dirResult.error);
63
+ }
64
+ // Save the file
65
+ await fs.writeFile(outputPath, imageData);
66
+ return Ok(outputPath);
67
+ }
68
+ catch (error) {
69
+ return Err(new FileOperationError(`${ERROR_MESSAGES.SAVE_FAILED}: ${error instanceof Error ? error.message : 'Unknown error'}`));
70
+ }
71
+ },
72
+ ensureDirectoryExists,
73
+ generateFileName,
74
+ };
75
+ }
76
+ //# sourceMappingURL=fileManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileManager.js","sourceRoot":"","sources":["../../src/business/fileManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AACnD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAEjC,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAEvD,+CAA+C;AAC/C,MAAM,gBAAgB,GAAG,OAAgB,CAAA;AACzC,MAAM,iBAAiB,GAAG,MAAe,CAAA;AACzC,MAAM,YAAY,GAAG,IAAa,CAAA;AAElC,MAAM,cAAc,GAAG;IACrB,WAAW,EAAE,2BAA2B;IACxC,yBAAyB,EAAE,4BAA4B;IACvD,qBAAqB,EAAE,mDAAmD;IAC1E,eAAe,EAAE,qDAAqD;CAC9D,CAAA;AAeV;;;;GAIG;AACH,SAAS,qBAAqB,CAAC,OAAe;IAC5C,IAAI,CAAC;QACH,iFAAiF;QACjF,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACvC,OAAO,EAAE,CAAC,SAAS,CAAC,CAAA;IACtB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,GAAG,CACR,IAAI,kBAAkB,CACpB,GAAG,cAAc,CAAC,yBAAyB,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAC3G,CACF,CAAA;IACH,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,gBAAgB;IACvB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,YAAY,CAAC,CAAA;IACvD,OAAO,GAAG,gBAAgB,IAAI,SAAS,IAAI,MAAM,GAAG,iBAAiB,EAAE,CAAA;AACzE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO;QACL;;;;;;WAMG;QACH,KAAK,CAAC,SAAS,CACb,SAAiB,EACjB,UAAkB,EAClB,OAAgB;YAEhB,IAAI,CAAC;gBACH,8BAA8B;gBAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;gBAC1C,MAAM,SAAS,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAA;gBAClD,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;oBACvB,OAAO,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;gBAC7B,CAAC;gBAED,gBAAgB;gBAChB,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC,CAAA;gBAEzC,OAAO,EAAE,CAAC,UAAU,CAAC,CAAA;YACvB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,GAAG,CACR,IAAI,kBAAkB,CACpB,GAAG,cAAc,CAAC,WAAW,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAC7F,CACF,CAAA;YACH,CAAC;QACH,CAAC;QAED,qBAAqB;QACrB,gBAAgB;KACjB,CAAA;AACH,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Input validation module for MCP server
3
+ * Validates user inputs according to Gemini API and business requirements
4
+ */
5
+ import type { GenerateImageParams } from '../types/mcp.js';
6
+ import type { Result } from '../types/result.js';
7
+ import { InputValidationError } from '../utils/errors.js';
8
+ /**
9
+ * Validates prompt text for length constraints
10
+ */
11
+ export declare function validatePrompt(prompt: string): Result<string, InputValidationError>;
12
+ /**
13
+ * Validates base64 encoded image data
14
+ * @param imageData - Base64 encoded image string
15
+ * @param mimeType - MIME type of the image
16
+ * @returns Result with validated Buffer or error
17
+ */
18
+ export declare function validateBase64Image(imageData?: string, mimeType?: string): Result<Buffer | undefined, InputValidationError>;
19
+ /**
20
+ * Validates an array of base64 encoded images
21
+ * @param images - Array of image objects with data and mimeType
22
+ * @returns Result with success or error
23
+ */
24
+ export declare function validateBase64Images(images: Array<{
25
+ data: string;
26
+ mimeType: string;
27
+ }>): Result<void, InputValidationError>;
28
+ /**
29
+ * Validates an array of input image paths
30
+ * @param paths - Array of image file paths
31
+ * @returns Result with success or error
32
+ */
33
+ export declare function validateImagePaths(paths: string[]): Result<void, InputValidationError>;
34
+ /**
35
+ * Validates input image path
36
+ * @param imagePath - Path to the input image file
37
+ * @returns Result with validated path or error
38
+ */
39
+ export declare function validateImagePath(imagePath?: string): Result<string | undefined, InputValidationError>;
40
+ /**
41
+ * Validates complete GenerateImageParams object
42
+ */
43
+ export declare function validateGenerateImageParams(params: GenerateImageParams): Result<GenerateImageParams, InputValidationError>;
44
+ //# sourceMappingURL=inputValidator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inputValidator.d.ts","sourceRoot":"","sources":["../../src/business/inputValidator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAe,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAEvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAEhD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAiCzD;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAanF;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,CAAC,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAAC,MAAM,GAAG,SAAS,EAAE,oBAAoB,CAAC,CAuDlD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,GAChD,MAAM,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAyBpC;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EAAE,GACd,MAAM,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAuBpC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAAC,MAAM,GAAG,SAAS,EAAE,oBAAoB,CAAC,CA6BlD;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,mBAAmB,GAC1B,MAAM,CAAC,mBAAmB,EAAE,oBAAoB,CAAC,CA2GnD"}
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Input validation module for MCP server
3
+ * Validates user inputs according to Gemini API and business requirements
4
+ */
5
+ import { existsSync } from 'node:fs';
6
+ import { extname } from 'node:path';
7
+ import { IMAGE_QUALITY_VALUES } from '../types/mcp.js';
8
+ import { Err, Ok } from '../types/result.js';
9
+ import { InputValidationError } from '../utils/errors.js';
10
+ // Constants for validation limits
11
+ const PROMPT_MIN_LENGTH = 1;
12
+ const PROMPT_MAX_LENGTH = 4000;
13
+ const MAX_IMAGE_SIZE = 10 * 1024 * 1024; // 10MB in bytes
14
+ const SUPPORTED_MIME_TYPES = ['image/jpeg', 'image/png', 'image/webp', 'image/gif', 'image/bmp'];
15
+ const SUPPORTED_ASPECT_RATIOS = [
16
+ '1:1',
17
+ '1:4',
18
+ '1:8',
19
+ '2:3',
20
+ '3:2',
21
+ '3:4',
22
+ '4:1',
23
+ '4:3',
24
+ '4:5',
25
+ '5:4',
26
+ '8:1',
27
+ '9:16',
28
+ '16:9',
29
+ '21:9',
30
+ ];
31
+ const SUPPORTED_QUALITY_VALUES = IMAGE_QUALITY_VALUES;
32
+ /**
33
+ * Converts bytes to MB with proper formatting
34
+ */
35
+ function formatFileSize(bytes) {
36
+ return (bytes / (1024 * 1024)).toFixed(1);
37
+ }
38
+ /**
39
+ * Validates prompt text for length constraints
40
+ */
41
+ export function validatePrompt(prompt) {
42
+ if (prompt.length < PROMPT_MIN_LENGTH || prompt.length > PROMPT_MAX_LENGTH) {
43
+ return Err(new InputValidationError(`Prompt must be between ${PROMPT_MIN_LENGTH} and ${PROMPT_MAX_LENGTH} characters. Current length: ${prompt.length}`, prompt.length === 0
44
+ ? 'Please provide a descriptive prompt for image generation.'
45
+ : `Please shorten your prompt by ${prompt.length - PROMPT_MAX_LENGTH} characters.`));
46
+ }
47
+ return Ok(prompt);
48
+ }
49
+ /**
50
+ * Validates base64 encoded image data
51
+ * @param imageData - Base64 encoded image string
52
+ * @param mimeType - MIME type of the image
53
+ * @returns Result with validated Buffer or error
54
+ */
55
+ export function validateBase64Image(imageData, mimeType) {
56
+ // If no image data provided, it's valid (optional parameter)
57
+ if (!imageData) {
58
+ return Ok(undefined);
59
+ }
60
+ // Validate MIME type if provided
61
+ if (mimeType && !SUPPORTED_MIME_TYPES.includes(mimeType)) {
62
+ return Err(new InputValidationError(`Unsupported MIME type: ${mimeType}. Supported types: ${SUPPORTED_MIME_TYPES.join(', ')}`, `Please provide an image with one of these MIME types: ${SUPPORTED_MIME_TYPES.join(', ')}`));
63
+ }
64
+ // Check if it's valid base64
65
+ // Remove data URI prefix if present
66
+ const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
67
+ const cleanedData = imageData.replace(/^data:image\/[a-z]+;base64,/, '');
68
+ if (!base64Regex.test(cleanedData)) {
69
+ return Err(new InputValidationError('Invalid base64 format', 'Please provide a valid base64 encoded image string'));
70
+ }
71
+ // Decode and check size
72
+ let buffer;
73
+ try {
74
+ buffer = Buffer.from(cleanedData, 'base64');
75
+ if (buffer.length > MAX_IMAGE_SIZE) {
76
+ const sizeInMB = formatFileSize(buffer.length);
77
+ const limitInMB = formatFileSize(MAX_IMAGE_SIZE);
78
+ return Err(new InputValidationError(`Image size exceeds ${limitInMB}MB limit. Current size: ${sizeInMB}MB`, `Please compress your image or reduce its resolution to stay below ${limitInMB}MB`));
79
+ }
80
+ }
81
+ catch (_error) {
82
+ return Err(new InputValidationError('Failed to decode base64 image', 'Please ensure the image is properly base64 encoded'));
83
+ }
84
+ return Ok(buffer);
85
+ }
86
+ /**
87
+ * Validates an array of base64 encoded images
88
+ * @param images - Array of image objects with data and mimeType
89
+ * @returns Result with success or error
90
+ */
91
+ export function validateBase64Images(images) {
92
+ if (images.length === 0) {
93
+ return Err(new InputValidationError('inputImages array must not be empty', 'Provide at least one image in the inputImages array'));
94
+ }
95
+ for (let i = 0; i < images.length; i++) {
96
+ const img = images[i];
97
+ if (!img)
98
+ continue;
99
+ const result = validateBase64Image(img.data, img.mimeType);
100
+ if (!result.success) {
101
+ return Err(new InputValidationError(`inputImages[${i}]: ${result.error.message}`, result.error.suggestion));
102
+ }
103
+ }
104
+ return Ok(undefined);
105
+ }
106
+ /**
107
+ * Validates an array of input image paths
108
+ * @param paths - Array of image file paths
109
+ * @returns Result with success or error
110
+ */
111
+ export function validateImagePaths(paths) {
112
+ if (paths.length === 0) {
113
+ return Err(new InputValidationError('inputImagePaths array must not be empty', 'Provide at least one file path in the inputImagePaths array'));
114
+ }
115
+ for (let i = 0; i < paths.length; i++) {
116
+ const result = validateImagePath(paths[i]);
117
+ if (!result.success) {
118
+ return Err(new InputValidationError(`inputImagePaths[${i}]: ${result.error.message}`, result.error.suggestion));
119
+ }
120
+ }
121
+ return Ok(undefined);
122
+ }
123
+ /**
124
+ * Validates input image path
125
+ * @param imagePath - Path to the input image file
126
+ * @returns Result with validated path or error
127
+ */
128
+ export function validateImagePath(imagePath) {
129
+ // If no path provided, it's valid (optional parameter)
130
+ if (!imagePath) {
131
+ return Ok(undefined);
132
+ }
133
+ // Check if file exists
134
+ if (!existsSync(imagePath)) {
135
+ return Err(new InputValidationError(`Input image file not found: ${imagePath}`, 'Please provide a valid absolute path to an existing image file'));
136
+ }
137
+ // Check file extension
138
+ const ext = extname(imagePath).toLowerCase();
139
+ const supportedExtensions = ['.jpg', '.jpeg', '.png', '.webp', '.gif', '.bmp'];
140
+ if (!supportedExtensions.includes(ext)) {
141
+ return Err(new InputValidationError(`Unsupported image format: ${ext}. Supported formats: ${supportedExtensions.join(', ')}`, `Please provide an image with one of these extensions: ${supportedExtensions.join(', ')}`));
142
+ }
143
+ return Ok(imagePath);
144
+ }
145
+ /**
146
+ * Validates complete GenerateImageParams object
147
+ */
148
+ export function validateGenerateImageParams(params) {
149
+ // Validate prompt
150
+ const promptResult = validatePrompt(params.prompt);
151
+ if (!promptResult.success) {
152
+ return Err(promptResult.error);
153
+ }
154
+ // Validate input image path if provided
155
+ const imagePathResult = validateImagePath(params.inputImagePath);
156
+ if (!imagePathResult.success) {
157
+ return Err(imagePathResult.error);
158
+ }
159
+ // Validate blendImages parameter
160
+ if (params.blendImages !== undefined && typeof params.blendImages !== 'boolean') {
161
+ return Err(new InputValidationError('blendImages must be a boolean value', 'Use true or false for blendImages parameter to enable/disable multi-image blending'));
162
+ }
163
+ // Validate maintainCharacterConsistency parameter
164
+ if (params.maintainCharacterConsistency !== undefined &&
165
+ typeof params.maintainCharacterConsistency !== 'boolean') {
166
+ return Err(new InputValidationError('maintainCharacterConsistency must be a boolean value', 'Use true or false for maintainCharacterConsistency parameter to enable/disable character consistency'));
167
+ }
168
+ // Validate useWorldKnowledge parameter
169
+ if (params.useWorldKnowledge !== undefined && typeof params.useWorldKnowledge !== 'boolean') {
170
+ return Err(new InputValidationError('useWorldKnowledge must be a boolean value', 'Use true or false for useWorldKnowledge parameter to enable/disable world knowledge integration'));
171
+ }
172
+ // Validate mutual exclusivity of image input methods
173
+ const imageInputCount = [
174
+ params.inputImagePath,
175
+ params.inputImage,
176
+ params.inputImages,
177
+ params.inputImagePaths,
178
+ ].filter(Boolean).length;
179
+ if (imageInputCount > 1) {
180
+ return Err(new InputValidationError('Only one image input method can be used at a time: inputImagePath, inputImage, inputImages, or inputImagePaths', 'Choose one: inputImagePath (single file), inputImage (single base64), inputImagePaths (multiple files), or inputImages (multiple base64)'));
181
+ }
182
+ // Validate inputImages array if provided
183
+ if (params.inputImages) {
184
+ const imagesResult = validateBase64Images(params.inputImages);
185
+ if (!imagesResult.success) {
186
+ return Err(imagesResult.error);
187
+ }
188
+ }
189
+ // Validate inputImagePaths array if provided
190
+ if (params.inputImagePaths) {
191
+ const pathsResult = validateImagePaths(params.inputImagePaths);
192
+ if (!pathsResult.success) {
193
+ return Err(pathsResult.error);
194
+ }
195
+ }
196
+ // Validate input image data if provided
197
+ if (params.inputImage || params.inputImageMimeType) {
198
+ const imageResult = validateBase64Image(params.inputImage, params.inputImageMimeType);
199
+ if (!imageResult.success) {
200
+ return Err(imageResult.error);
201
+ }
202
+ }
203
+ // Validate aspectRatio parameter
204
+ if (params.aspectRatio && !SUPPORTED_ASPECT_RATIOS.includes(params.aspectRatio)) {
205
+ return Err(new InputValidationError(`Invalid aspect ratio: ${params.aspectRatio}. Supported values: ${SUPPORTED_ASPECT_RATIOS.join(', ')}`, `Please use one of the supported aspect ratios: ${SUPPORTED_ASPECT_RATIOS.join(', ')}`));
206
+ }
207
+ // Validate quality parameter
208
+ if (params.quality !== undefined && !SUPPORTED_QUALITY_VALUES.includes(params.quality)) {
209
+ return Err(new InputValidationError(`Invalid quality value: "${params.quality}". Supported values: ${SUPPORTED_QUALITY_VALUES.join(', ')}`, `Please use one of the supported quality values: ${SUPPORTED_QUALITY_VALUES.join(', ')}`));
210
+ }
211
+ return Ok(params);
212
+ }
213
+ //# sourceMappingURL=inputValidator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inputValidator.js","sourceRoot":"","sources":["../../src/business/inputValidator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Response Builder for MCP structured content responses
3
+ * Converts generation results and errors into MCP-compatible response format
4
+ */
5
+ import type { GeneratedImageResult } from '../api/geminiClient.js';
6
+ import type { McpToolResponse } from '../types/mcp.js';
7
+ import { type BaseError } from '../utils/errors.js';
8
+ /**
9
+ * Interface for response builder functionality
10
+ */
11
+ export interface ResponseBuilder {
12
+ buildSuccessResponse(generationResult: GeneratedImageResult, filePath: string): McpToolResponse;
13
+ buildBase64SuccessResponse(generationResult: GeneratedImageResult, filePath: string, base64Data: string): McpToolResponse;
14
+ buildErrorResponse(error: BaseError | Error): McpToolResponse;
15
+ }
16
+ /**
17
+ * Creates a response builder with MCP structured content support
18
+ * @returns ResponseBuilder implementation
19
+ */
20
+ export declare function createResponseBuilder(): ResponseBuilder;
21
+ //# sourceMappingURL=responseBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responseBuilder.d.ts","sourceRoot":"","sources":["../../src/business/responseBuilder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAClE,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,iBAAiB,CAAA;AACzE,OAAO,EACL,KAAK,SAAS,EAOf,MAAM,oBAAoB,CAAA;AAmB3B;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,oBAAoB,CAAC,gBAAgB,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,GAAG,eAAe,CAAA;IAC/F,0BAA0B,CACxB,gBAAgB,EAAE,oBAAoB,EACtC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,eAAe,CAAA;IAClB,kBAAkB,CAAC,KAAK,EAAE,SAAS,GAAG,KAAK,GAAG,eAAe,CAAA;CAC9D;AA+DD;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CA0GvD"}
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Response Builder for MCP structured content responses
3
+ * Converts generation results and errors into MCP-compatible response format
4
+ */
5
+ import * as path from 'node:path';
6
+ import { ConfigError, FileOperationError, GeminiAPIError, InputValidationError, NetworkError, SecurityError, } from '../utils/errors.js';
7
+ // Constants for MIME types and error handling
8
+ const MIME_TYPES = {
9
+ PNG: 'image/png',
10
+ JPEG: 'image/jpeg',
11
+ WEBP: 'image/webp',
12
+ };
13
+ const FILE_EXTENSIONS = {
14
+ PNG: ['.png'],
15
+ JPEG: ['.jpg', '.jpeg'],
16
+ WEBP: ['.webp'],
17
+ };
18
+ const DEFAULT_MIME_TYPE = MIME_TYPES.PNG;
19
+ const UNKNOWN_ERROR_CODE = 'UNKNOWN_ERROR';
20
+ const DEFAULT_ERROR_SUGGESTION = 'Please try again or contact support if the problem persists';
21
+ /**
22
+ * Determines MIME type based on file extension
23
+ * @param filePath Path to the image file
24
+ * @returns MIME type string
25
+ */
26
+ function getMimeTypeFromPath(filePath) {
27
+ const ext = path.extname(filePath).toLowerCase();
28
+ if (FILE_EXTENSIONS.PNG.includes(ext)) {
29
+ return MIME_TYPES.PNG;
30
+ }
31
+ if (FILE_EXTENSIONS.JPEG.includes(ext)) {
32
+ return MIME_TYPES.JPEG;
33
+ }
34
+ if (FILE_EXTENSIONS.WEBP.includes(ext)) {
35
+ return MIME_TYPES.WEBP;
36
+ }
37
+ return DEFAULT_MIME_TYPE;
38
+ }
39
+ /**
40
+ * Converts various error types to structured error format
41
+ * @param error Error to convert
42
+ * @returns Structured error object
43
+ */
44
+ function convertErrorToStructured(error) {
45
+ const baseError = {
46
+ timestamp: new Date().toISOString(),
47
+ };
48
+ if (error instanceof InputValidationError ||
49
+ error instanceof FileOperationError ||
50
+ error instanceof GeminiAPIError ||
51
+ error instanceof NetworkError ||
52
+ error instanceof ConfigError ||
53
+ error instanceof SecurityError) {
54
+ return {
55
+ ...baseError,
56
+ code: error.code,
57
+ message: error.message,
58
+ suggestion: error.suggestion,
59
+ };
60
+ }
61
+ // Handle unknown errors
62
+ return {
63
+ ...baseError,
64
+ code: UNKNOWN_ERROR_CODE,
65
+ message: error.message || 'An unknown error occurred',
66
+ suggestion: DEFAULT_ERROR_SUGGESTION,
67
+ };
68
+ }
69
+ /**
70
+ * Creates a response builder with MCP structured content support
71
+ * @returns ResponseBuilder implementation
72
+ */
73
+ export function createResponseBuilder() {
74
+ return {
75
+ /**
76
+ * Builds a successful structured content response with file path
77
+ * @param generationResult Result from image generation
78
+ * @param filePath Absolute path to the saved image file (required)
79
+ * @returns MCP tool response with structured content containing file path
80
+ */
81
+ buildSuccessResponse(generationResult, filePath) {
82
+ // File-based implementation: Always return file path, never base64
83
+ // This avoids MCP token limit issues (25,000 tokens max)
84
+ const mimeType = getMimeTypeFromPath(filePath);
85
+ const fileName = path.basename(filePath);
86
+ const structuredContent = {
87
+ type: 'resource',
88
+ resource: {
89
+ uri: `file://${filePath}`,
90
+ name: fileName,
91
+ mimeType,
92
+ },
93
+ metadata: {
94
+ model: generationResult.metadata.model,
95
+ processingTime: 0, // Not tracked in simplified version
96
+ contextMethod: 'structured_prompt',
97
+ timestamp: generationResult.metadata.timestamp.toISOString(),
98
+ },
99
+ };
100
+ return {
101
+ content: [
102
+ {
103
+ type: 'text',
104
+ text: JSON.stringify(structuredContent),
105
+ },
106
+ ],
107
+ isError: false,
108
+ };
109
+ },
110
+ /**
111
+ * Builds a successful response that includes base64 image data alongside file path
112
+ * @param generationResult Result from image generation
113
+ * @param filePath Absolute path to the saved image file
114
+ * @param base64Data Base64 encoded image data
115
+ * @returns MCP tool response with both file URI and base64 data
116
+ */
117
+ buildBase64SuccessResponse(generationResult, filePath, base64Data) {
118
+ const mimeType = getMimeTypeFromPath(filePath);
119
+ const fileName = path.basename(filePath);
120
+ const responseData = {
121
+ type: 'resource',
122
+ resource: {
123
+ uri: `file://${filePath}`,
124
+ name: fileName,
125
+ mimeType,
126
+ },
127
+ base64Data,
128
+ metadata: {
129
+ model: generationResult.metadata.model,
130
+ processingTime: 0,
131
+ contextMethod: 'structured_prompt',
132
+ timestamp: generationResult.metadata.timestamp.toISOString(),
133
+ },
134
+ };
135
+ return {
136
+ content: [
137
+ {
138
+ type: 'text',
139
+ text: JSON.stringify(responseData),
140
+ },
141
+ ],
142
+ isError: false,
143
+ };
144
+ },
145
+ /**
146
+ * Builds an error response in structured content format
147
+ * @param error Error that occurred during processing
148
+ * @returns MCP tool response with structured error
149
+ */
150
+ buildErrorResponse(error) {
151
+ const structuredError = {
152
+ error: convertErrorToStructured(error),
153
+ };
154
+ return {
155
+ content: [
156
+ {
157
+ type: 'text',
158
+ text: JSON.stringify(structuredError),
159
+ },
160
+ ],
161
+ isError: true,
162
+ };
163
+ },
164
+ };
165
+ }
166
+ //# sourceMappingURL=responseBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responseBuilder.js","sourceRoot":"","sources":["../../src/business/responseBuilder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Structured Prompt Generator
3
+ * Uses Gemini Flash to generate optimized prompts for image generation
4
+ * Applies 7 best practices and 3 feature perspectives through intelligent selection
5
+ */
6
+ import type { GeminiTextClient } from '../api/geminiTextClient.js';
7
+ import type { Result } from '../types/result.js';
8
+ /**
9
+ * Feature flags for image generation
10
+ */
11
+ export interface FeatureFlags {
12
+ maintainCharacterConsistency?: boolean;
13
+ blendImages?: boolean;
14
+ useWorldKnowledge?: boolean;
15
+ useGoogleSearch?: boolean;
16
+ }
17
+ /**
18
+ * Result of structured prompt generation
19
+ */
20
+ export interface StructuredPromptResult {
21
+ originalPrompt: string;
22
+ structuredPrompt: string;
23
+ selectedPractices: string[];
24
+ }
25
+ /**
26
+ * Interface for structured prompt generation
27
+ */
28
+ export interface StructuredPromptGenerator {
29
+ generateStructuredPrompt(userPrompt: string, features?: FeatureFlags, inputImageData?: string, // Optional base64-encoded image for context
30
+ purpose?: string): Promise<Result<StructuredPromptResult, Error>>;
31
+ }
32
+ /**
33
+ * Implementation of StructuredPromptGenerator using Gemini Flash
34
+ */
35
+ export declare class StructuredPromptGeneratorImpl implements StructuredPromptGenerator {
36
+ private readonly geminiTextClient;
37
+ constructor(geminiTextClient: GeminiTextClient);
38
+ generateStructuredPrompt(userPrompt: string, features?: FeatureFlags, inputImageData?: string, purpose?: string): Promise<Result<StructuredPromptResult, Error>>;
39
+ /**
40
+ * Build complete prompt with all optimization context
41
+ */
42
+ private buildCompletePrompt;
43
+ /**
44
+ * Build enhanced feature context based on flags with explicit requirements
45
+ */
46
+ private buildEnhancedFeatureContext;
47
+ /**
48
+ * Infer which best practices were selected based on the generated prompt
49
+ */
50
+ private inferSelectedPractices;
51
+ }
52
+ /**
53
+ * Factory function to create StructuredPromptGenerator
54
+ */
55
+ export declare function createStructuredPromptGenerator(geminiTextClient: GeminiTextClient): StructuredPromptGenerator;
56
+ //# sourceMappingURL=structuredPromptGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structuredPromptGenerator.d.ts","sourceRoot":"","sources":["../../src/business/structuredPromptGenerator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAClE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AA+ChD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,4BAA4B,CAAC,EAAE,OAAO,CAAA;IACtC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,cAAc,EAAE,MAAM,CAAA;IACtB,gBAAgB,EAAE,MAAM,CAAA;IACxB,iBAAiB,EAAE,MAAM,EAAE,CAAA;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,wBAAwB,CACtB,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,YAAY,EACvB,cAAc,CAAC,EAAE,MAAM,EAAE,4CAA4C;IACrE,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC,CAAA;CAClD;AAED;;GAEG;AACH,qBAAa,6BAA8B,YAAW,yBAAyB;IACjE,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBAAhB,gBAAgB,EAAE,gBAAgB;IAEzD,wBAAwB,CAC5B,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,YAAiB,EAC3B,cAAc,CAAC,EAAE,MAAM,EACvB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;IAgDjD;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAyC3B;;OAEG;IACH,OAAO,CAAC,2BAA2B;IA4BnC;;OAEG;IACH,OAAO,CAAC,sBAAsB;CAkF/B;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAC7C,gBAAgB,EAAE,gBAAgB,GACjC,yBAAyB,CAE3B"}