@michelabboud/visual-forge-mcp 0.6.0 → 0.7.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 (68) hide show
  1. package/CHANGELOG.md +403 -2
  2. package/README.md +88 -5
  3. package/config/pricing.json +1 -1
  4. package/dist/parser/markdown-parser.d.ts +2 -0
  5. package/dist/parser/markdown-parser.d.ts.map +1 -1
  6. package/dist/parser/markdown-parser.js +23 -10
  7. package/dist/parser/markdown-parser.js.map +1 -1
  8. package/dist/placeholders/placeholder-manager.d.ts +8 -0
  9. package/dist/placeholders/placeholder-manager.d.ts.map +1 -1
  10. package/dist/placeholders/placeholder-manager.js +71 -18
  11. package/dist/placeholders/placeholder-manager.js.map +1 -1
  12. package/dist/providers/base-provider.d.ts +13 -0
  13. package/dist/providers/base-provider.d.ts.map +1 -1
  14. package/dist/providers/base-provider.js +263 -17
  15. package/dist/providers/base-provider.js.map +1 -1
  16. package/dist/providers/gemini/gemini-provider.d.ts.map +1 -1
  17. package/dist/providers/gemini/gemini-provider.js +3 -7
  18. package/dist/providers/gemini/gemini-provider.js.map +1 -1
  19. package/dist/providers/index.d.ts.map +1 -1
  20. package/dist/providers/index.js +5 -1
  21. package/dist/providers/index.js.map +1 -1
  22. package/dist/server/mcp-server.d.ts.map +1 -1
  23. package/dist/server/mcp-server.js +4 -1
  24. package/dist/server/mcp-server.js.map +1 -1
  25. package/dist/utils/filename-sanitizer.d.ts +85 -0
  26. package/dist/utils/filename-sanitizer.d.ts.map +1 -0
  27. package/dist/utils/filename-sanitizer.js +156 -0
  28. package/dist/utils/filename-sanitizer.js.map +1 -0
  29. package/dist/utils/image-metadata-manager.d.ts +151 -0
  30. package/dist/utils/image-metadata-manager.d.ts.map +1 -0
  31. package/dist/utils/image-metadata-manager.js +172 -0
  32. package/dist/utils/image-metadata-manager.js.map +1 -0
  33. package/dist/utils/index-manager.d.ts +38 -0
  34. package/dist/utils/index-manager.d.ts.map +1 -0
  35. package/dist/utils/index-manager.js +110 -0
  36. package/dist/utils/index-manager.js.map +1 -0
  37. package/dist/utils/index.d.ts +5 -0
  38. package/dist/utils/index.d.ts.map +1 -1
  39. package/dist/utils/index.js +5 -0
  40. package/dist/utils/index.js.map +1 -1
  41. package/dist/utils/multi-format-optimizer.d.ts +96 -0
  42. package/dist/utils/multi-format-optimizer.d.ts.map +1 -0
  43. package/dist/utils/multi-format-optimizer.js +423 -0
  44. package/dist/utils/multi-format-optimizer.js.map +1 -0
  45. package/dist/utils/pricing-checker.d.ts.map +1 -1
  46. package/dist/utils/pricing-checker.js +3 -5
  47. package/dist/utils/pricing-checker.js.map +1 -1
  48. package/dist/utils/prompt-enhancer.d.ts +48 -0
  49. package/dist/utils/prompt-enhancer.d.ts.map +1 -0
  50. package/dist/utils/prompt-enhancer.js +169 -0
  51. package/dist/utils/prompt-enhancer.js.map +1 -0
  52. package/dist/utils/quality-validator.d.ts +61 -0
  53. package/dist/utils/quality-validator.d.ts.map +1 -0
  54. package/dist/utils/quality-validator.js +386 -0
  55. package/dist/utils/quality-validator.js.map +1 -0
  56. package/dist/utils/source-metadata.d.ts +56 -0
  57. package/dist/utils/source-metadata.d.ts.map +1 -0
  58. package/dist/utils/source-metadata.js +122 -0
  59. package/dist/utils/source-metadata.js.map +1 -0
  60. package/dist/workflow/workflow-orchestrator.d.ts.map +1 -1
  61. package/dist/workflow/workflow-orchestrator.js +23 -0
  62. package/dist/workflow/workflow-orchestrator.js.map +1 -1
  63. package/dist/workflow/workflow-tools.d.ts.map +1 -1
  64. package/dist/workflow/workflow-tools.js +18 -0
  65. package/dist/workflow/workflow-tools.js.map +1 -1
  66. package/docs/guides/provider-setup.md +543 -0
  67. package/package.json +2 -2
  68. package/scripts/README.md +460 -0
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Prompt Enhancer - Enhances prompts to minimize AI text rendering errors
3
+ * Adds specific instructions to reduce gibberish and improve quality
4
+ */
5
+ import { logger } from './logger.js';
6
+ /**
7
+ * Default enhancement configuration
8
+ */
9
+ const DEFAULT_CONFIG = {
10
+ preventText: true,
11
+ preventLabels: true,
12
+ addQualityInstructions: true,
13
+ addStyleInstructions: true,
14
+ customPrefix: '',
15
+ customSuffix: '',
16
+ };
17
+ /**
18
+ * Text prevention instructions (prevent AI from adding text)
19
+ */
20
+ const TEXT_PREVENTION_INSTRUCTIONS = [
21
+ 'no text or labels',
22
+ 'no watermarks',
23
+ 'no captions',
24
+ 'no written words',
25
+ 'clean visual only',
26
+ ];
27
+ /**
28
+ * Quality enhancement keywords
29
+ */
30
+ const QUALITY_KEYWORDS = [
31
+ 'professional',
32
+ 'high quality',
33
+ 'detailed',
34
+ 'crisp',
35
+ 'clear',
36
+ 'well-defined',
37
+ ];
38
+ /**
39
+ * Style consistency keywords
40
+ */
41
+ const STYLE_KEYWORDS = [
42
+ 'consistent style',
43
+ 'cohesive design',
44
+ 'unified aesthetic',
45
+ ];
46
+ /**
47
+ * Enhance a prompt to minimize text rendering errors
48
+ *
49
+ * @param originalPrompt - The original prompt
50
+ * @param config - Enhancement configuration
51
+ * @returns Enhanced prompt
52
+ */
53
+ export function enhancePrompt(originalPrompt, config = {}) {
54
+ // Merge with defaults
55
+ const fullConfig = {
56
+ ...DEFAULT_CONFIG,
57
+ ...config,
58
+ };
59
+ const parts = [];
60
+ // Add custom prefix
61
+ if (fullConfig.customPrefix) {
62
+ parts.push(fullConfig.customPrefix);
63
+ }
64
+ // Add original prompt
65
+ parts.push(originalPrompt);
66
+ const enhancements = [];
67
+ // Add quality instructions
68
+ if (fullConfig.addQualityInstructions) {
69
+ enhancements.push(...QUALITY_KEYWORDS);
70
+ }
71
+ // Add style instructions
72
+ if (fullConfig.addStyleInstructions) {
73
+ enhancements.push(...STYLE_KEYWORDS);
74
+ }
75
+ // Add text prevention
76
+ if (fullConfig.preventText || fullConfig.preventLabels) {
77
+ enhancements.push(...TEXT_PREVENTION_INSTRUCTIONS);
78
+ }
79
+ // Add custom suffix
80
+ if (fullConfig.customSuffix) {
81
+ enhancements.push(fullConfig.customSuffix);
82
+ }
83
+ // Combine enhancements
84
+ if (enhancements.length > 0) {
85
+ parts.push(enhancements.join(', '));
86
+ }
87
+ const enhancedPrompt = parts.join(', ');
88
+ logger.debug('Prompt enhanced', {
89
+ originalLength: originalPrompt.length,
90
+ enhancedLength: enhancedPrompt.length,
91
+ addedKeywords: enhancements.length,
92
+ });
93
+ return enhancedPrompt;
94
+ }
95
+ /**
96
+ * Enhance prompt specifically for diagrams
97
+ */
98
+ export function enhanceForDiagram(prompt) {
99
+ return enhancePrompt(prompt, {
100
+ preventText: true,
101
+ preventLabels: false, // Diagrams may need labels
102
+ addQualityInstructions: true,
103
+ addStyleInstructions: true,
104
+ customSuffix: 'technical diagram, clean lines, clear structure',
105
+ });
106
+ }
107
+ /**
108
+ * Enhance prompt specifically for illustrations
109
+ */
110
+ export function enhanceForIllustration(prompt) {
111
+ return enhancePrompt(prompt, {
112
+ preventText: true,
113
+ preventLabels: true,
114
+ addQualityInstructions: true,
115
+ addStyleInstructions: true,
116
+ customSuffix: 'artistic illustration, visual storytelling, no text overlay',
117
+ });
118
+ }
119
+ /**
120
+ * Enhance prompt specifically for icons
121
+ */
122
+ export function enhanceForIcon(prompt) {
123
+ return enhancePrompt(prompt, {
124
+ preventText: true,
125
+ preventLabels: true,
126
+ addQualityInstructions: true,
127
+ addStyleInstructions: true,
128
+ customSuffix: 'simple icon, minimalist design, scalable vector style',
129
+ });
130
+ }
131
+ /**
132
+ * Enhance prompt specifically for screenshots
133
+ */
134
+ export function enhanceForScreenshot(prompt) {
135
+ return enhancePrompt(prompt, {
136
+ preventText: false, // Screenshots may contain UI text
137
+ preventLabels: false,
138
+ addQualityInstructions: true,
139
+ addStyleInstructions: true,
140
+ customSuffix: 'realistic UI mockup, modern interface design',
141
+ });
142
+ }
143
+ /**
144
+ * Enhance prompt based on image type
145
+ */
146
+ export function enhanceByType(prompt, imageType) {
147
+ switch (imageType) {
148
+ case 'diagram':
149
+ case 'flowchart':
150
+ case 'architecture':
151
+ return enhanceForDiagram(prompt);
152
+ case 'illustration':
153
+ case 'hero':
154
+ return enhanceForIllustration(prompt);
155
+ case 'icon':
156
+ return enhanceForIcon(prompt);
157
+ case 'screenshot':
158
+ return enhanceForScreenshot(prompt);
159
+ default:
160
+ return enhancePrompt(prompt);
161
+ }
162
+ }
163
+ /**
164
+ * Get default enhancement configuration
165
+ */
166
+ export function getDefaultEnhancementConfig() {
167
+ return { ...DEFAULT_CONFIG };
168
+ }
169
+ //# sourceMappingURL=prompt-enhancer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-enhancer.js","sourceRoot":"","sources":["../../src/utils/prompt-enhancer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Quality Validator - Validates generated images for quality issues
3
+ * Uses OCR (Tesseract.js) to detect text rendering problems
4
+ * Analyzes sharpness, brightness, and other quality metrics
5
+ */
6
+ /**
7
+ * Quality validation configuration
8
+ */
9
+ export interface QualityValidationConfig {
10
+ enableOCR?: boolean;
11
+ maxGibberishRatio?: number;
12
+ minConfidence?: number;
13
+ minSharpness?: number;
14
+ minBrightness?: number;
15
+ maxBrightness?: number;
16
+ minQualityScore?: number;
17
+ }
18
+ /**
19
+ * Quality validation result
20
+ */
21
+ export interface QualityValidationResult {
22
+ passed: boolean;
23
+ score: number;
24
+ sharpness?: {
25
+ value: number;
26
+ passed: boolean;
27
+ threshold: number;
28
+ };
29
+ brightness?: {
30
+ value: number;
31
+ passed: boolean;
32
+ minThreshold: number;
33
+ maxThreshold: number;
34
+ };
35
+ ocr?: {
36
+ text: string;
37
+ confidence: number;
38
+ gibberishRatio: number;
39
+ passed: boolean;
40
+ issues: string[];
41
+ };
42
+ failureReasons: string[];
43
+ recommendations: string[];
44
+ }
45
+ /**
46
+ * Validate image quality
47
+ */
48
+ export declare function validateImageQuality(imagePath: string, config?: QualityValidationConfig): Promise<QualityValidationResult>;
49
+ /**
50
+ * Check if quality validation is available
51
+ */
52
+ export declare function isQualityValidationAvailable(): Promise<{
53
+ sharpAvailable: boolean;
54
+ tesseractAvailable: boolean;
55
+ fullyAvailable: boolean;
56
+ }>;
57
+ /**
58
+ * Get default quality validation configuration
59
+ */
60
+ export declare function getDefaultQualityConfig(): Required<QualityValidationConfig>;
61
+ //# sourceMappingURL=quality-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality-validator.d.ts","sourceRoot":"","sources":["../../src/utils/quality-validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA0DH;;GAEG;AACH,MAAM,WAAW,uBAAuB;IAEtC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IAGvB,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IAGvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IAGd,SAAS,CAAC,EAAE;QACV,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,OAAO,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IAEF,UAAU,CAAC,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,OAAO,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IAEF,GAAG,CAAC,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IAGF,cAAc,EAAE,MAAM,EAAE,CAAC;IAGzB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AA6PD;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,uBAA4B,GACnC,OAAO,CAAC,uBAAuB,CAAC,CAoHlC;AAED;;GAEG;AACH,wBAAsB,4BAA4B,IAAI,OAAO,CAAC;IAC5D,cAAc,EAAE,OAAO,CAAC;IACxB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC,CASD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,QAAQ,CAAC,uBAAuB,CAAC,CAE3E"}
@@ -0,0 +1,386 @@
1
+ /**
2
+ * Quality Validator - Validates generated images for quality issues
3
+ * Uses OCR (Tesseract.js) to detect text rendering problems
4
+ * Analyzes sharpness, brightness, and other quality metrics
5
+ */
6
+ import { logger } from './logger.js';
7
+ // Dynamic import of Sharp and Tesseract
8
+ let sharp = null;
9
+ let tesseract = null; // Use 'any' since tesseract.js might not be installed
10
+ let sharpAvailable = false;
11
+ let tesseractAvailable = false;
12
+ /**
13
+ * Initialize Sharp library
14
+ */
15
+ async function initializeSharp() {
16
+ if (sharp !== null) {
17
+ return sharpAvailable;
18
+ }
19
+ try {
20
+ sharp = (await import('sharp')).default;
21
+ sharpAvailable = true;
22
+ logger.debug('Sharp library loaded for quality validation');
23
+ return true;
24
+ }
25
+ catch (error) {
26
+ sharpAvailable = false;
27
+ logger.warn('Sharp not available - quality validation will be limited', {
28
+ error: error instanceof Error ? error.message : 'Unknown error',
29
+ });
30
+ return false;
31
+ }
32
+ }
33
+ /**
34
+ * Initialize Tesseract library
35
+ */
36
+ async function initializeTesseract() {
37
+ if (tesseract !== null) {
38
+ return tesseractAvailable;
39
+ }
40
+ try {
41
+ // Try to dynamically import tesseract.js (optional dependency)
42
+ // @ts-ignore - tesseract.js is an optional dependency
43
+ const tesseractModule = await import('tesseract.js');
44
+ tesseract = tesseractModule;
45
+ tesseractAvailable = true;
46
+ logger.info('Tesseract.js loaded - OCR text validation enabled');
47
+ return true;
48
+ }
49
+ catch (error) {
50
+ tesseractAvailable = false;
51
+ logger.warn('Tesseract.js not available - OCR validation disabled', {
52
+ error: error instanceof Error ? error.message : 'Unknown error',
53
+ hint: 'Install with: npm install tesseract.js',
54
+ });
55
+ return false;
56
+ }
57
+ }
58
+ /**
59
+ * Default quality validation configuration
60
+ */
61
+ const DEFAULT_CONFIG = {
62
+ enableOCR: true,
63
+ maxGibberishRatio: 0.3,
64
+ minConfidence: 60,
65
+ minSharpness: 50,
66
+ minBrightness: 30,
67
+ maxBrightness: 240,
68
+ minQualityScore: 60,
69
+ };
70
+ /**
71
+ * Detect gibberish in text using heuristics
72
+ */
73
+ function detectGibberish(text) {
74
+ if (!text || text.trim().length === 0) {
75
+ return { isGibberish: false, ratio: 0 };
76
+ }
77
+ const words = text.split(/\s+/).filter(w => w.length > 0);
78
+ if (words.length === 0) {
79
+ return { isGibberish: false, ratio: 0 };
80
+ }
81
+ let gibberishCount = 0;
82
+ // Common gibberish patterns
83
+ const gibberishPatterns = [
84
+ /^[^aeiouAEIOU]{5,}$/, // Too many consonants
85
+ /(.)\1{3,}/, // Repeated characters (aaaa)
86
+ /^[a-zA-Z]{1,2}$/, // Single/double letter words (except common ones)
87
+ /[^a-zA-Z0-9\s\-'.,!?@#$%&*()]/, // Unusual characters
88
+ /^[0-9]+[a-zA-Z]+[0-9]+$/, // Numbers mixed with letters oddly
89
+ ];
90
+ // Common short words that are OK
91
+ const commonShortWords = new Set([
92
+ 'a', 'i', 'an', 'as', 'at', 'be', 'by', 'do', 'go', 'he', 'if', 'in', 'is', 'it',
93
+ 'me', 'my', 'no', 'of', 'on', 'or', 'so', 'to', 'up', 'us', 'we',
94
+ ]);
95
+ for (const word of words) {
96
+ const lowerWord = word.toLowerCase();
97
+ // Skip common short words
98
+ if (commonShortWords.has(lowerWord)) {
99
+ continue;
100
+ }
101
+ // Check for gibberish patterns
102
+ let isGibberishWord = false;
103
+ for (const pattern of gibberishPatterns) {
104
+ if (pattern.test(word)) {
105
+ isGibberishWord = true;
106
+ break;
107
+ }
108
+ }
109
+ // Check vowel ratio (real words usually have 20-60% vowels)
110
+ const vowels = word.match(/[aeiouAEIOU]/g);
111
+ const vowelRatio = vowels ? vowels.length / word.length : 0;
112
+ if (word.length > 3 && (vowelRatio < 0.1 || vowelRatio > 0.8)) {
113
+ isGibberishWord = true;
114
+ }
115
+ if (isGibberishWord) {
116
+ gibberishCount++;
117
+ logger.debug('Detected gibberish word', { word });
118
+ }
119
+ }
120
+ const ratio = gibberishCount / words.length;
121
+ const isGibberish = ratio > 0.3; // More than 30% gibberish
122
+ return { isGibberish, ratio };
123
+ }
124
+ /**
125
+ * Calculate sharpness using Laplacian variance
126
+ */
127
+ async function calculateSharpness(imagePath) {
128
+ if (!sharp) {
129
+ return 0;
130
+ }
131
+ try {
132
+ const image = sharp(imagePath);
133
+ const { data, info } = await image
134
+ .greyscale()
135
+ .raw()
136
+ .toBuffer({ resolveWithObject: true });
137
+ // Calculate Laplacian variance (edge detection)
138
+ const width = info.width;
139
+ const height = info.height;
140
+ let sum = 0;
141
+ let count = 0;
142
+ for (let y = 1; y < height - 1; y++) {
143
+ for (let x = 1; x < width - 1; x++) {
144
+ const idx = y * width + x;
145
+ const center = data[idx];
146
+ const top = data[(y - 1) * width + x];
147
+ const bottom = data[(y + 1) * width + x];
148
+ const left = data[y * width + (x - 1)];
149
+ const right = data[y * width + (x + 1)];
150
+ // Laplacian kernel
151
+ const laplacian = Math.abs(4 * center - top - bottom - left - right);
152
+ sum += laplacian * laplacian;
153
+ count++;
154
+ }
155
+ }
156
+ const variance = sum / count;
157
+ return variance;
158
+ }
159
+ catch (error) {
160
+ logger.warn('Failed to calculate sharpness', {
161
+ error: error instanceof Error ? error.message : 'Unknown error',
162
+ });
163
+ return 0;
164
+ }
165
+ }
166
+ /**
167
+ * Calculate average brightness
168
+ */
169
+ async function calculateBrightness(imagePath) {
170
+ if (!sharp) {
171
+ return 128;
172
+ }
173
+ try {
174
+ const image = sharp(imagePath);
175
+ const { data } = await image
176
+ .greyscale()
177
+ .raw()
178
+ .toBuffer({ resolveWithObject: true });
179
+ const sum = Array.from(data).reduce((acc, val) => acc + val, 0);
180
+ const average = sum / data.length;
181
+ return average;
182
+ }
183
+ catch (error) {
184
+ logger.warn('Failed to calculate brightness', {
185
+ error: error instanceof Error ? error.message : 'Unknown error',
186
+ });
187
+ return 128;
188
+ }
189
+ }
190
+ /**
191
+ * Perform OCR text detection and validation
192
+ */
193
+ async function performOCR(imagePath, config) {
194
+ if (!tesseract || !tesseractAvailable) {
195
+ logger.debug('OCR skipped - Tesseract not available');
196
+ return {
197
+ text: '',
198
+ confidence: 100,
199
+ gibberishRatio: 0,
200
+ passed: true,
201
+ issues: [],
202
+ };
203
+ }
204
+ try {
205
+ logger.debug('Performing OCR text detection', { imagePath });
206
+ const worker = await tesseract.createWorker('eng');
207
+ const { data } = await worker.recognize(imagePath);
208
+ await worker.terminate();
209
+ const detectedText = data.text.trim();
210
+ const avgConfidence = data.confidence;
211
+ logger.debug('OCR completed', {
212
+ textLength: detectedText.length,
213
+ confidence: avgConfidence.toFixed(1),
214
+ });
215
+ const issues = [];
216
+ // Check if text was detected (might indicate unwanted text in image)
217
+ if (detectedText.length === 0) {
218
+ // No text detected - this is usually good for diagrams
219
+ return {
220
+ text: '',
221
+ confidence: 100,
222
+ gibberishRatio: 0,
223
+ passed: true,
224
+ issues: [],
225
+ };
226
+ }
227
+ // If text was detected, validate quality
228
+ const gibberishAnalysis = detectGibberish(detectedText);
229
+ // Low confidence
230
+ if (avgConfidence < config.minConfidence) {
231
+ issues.push(`Low OCR confidence: ${avgConfidence.toFixed(1)}% (min: ${config.minConfidence}%)`);
232
+ }
233
+ // High gibberish ratio
234
+ if (gibberishAnalysis.ratio > config.maxGibberishRatio) {
235
+ issues.push(`High gibberish ratio: ${(gibberishAnalysis.ratio * 100).toFixed(1)}% (max: ${config.maxGibberishRatio * 100}%)`);
236
+ }
237
+ const passed = issues.length === 0;
238
+ if (!passed) {
239
+ logger.warn('OCR quality issues detected', {
240
+ text: detectedText.substring(0, 100),
241
+ confidence: avgConfidence,
242
+ gibberishRatio: gibberishAnalysis.ratio,
243
+ issues,
244
+ });
245
+ }
246
+ return {
247
+ text: detectedText,
248
+ confidence: avgConfidence,
249
+ gibberishRatio: gibberishAnalysis.ratio,
250
+ passed,
251
+ issues,
252
+ };
253
+ }
254
+ catch (error) {
255
+ logger.warn('OCR failed', {
256
+ error: error instanceof Error ? error.message : 'Unknown error',
257
+ });
258
+ // On error, pass validation (don't block generation)
259
+ return {
260
+ text: '',
261
+ confidence: 0,
262
+ gibberishRatio: 0,
263
+ passed: true,
264
+ issues: ['OCR error - validation skipped'],
265
+ };
266
+ }
267
+ }
268
+ /**
269
+ * Validate image quality
270
+ */
271
+ export async function validateImageQuality(imagePath, config = {}) {
272
+ // Merge with defaults
273
+ const fullConfig = {
274
+ ...DEFAULT_CONFIG,
275
+ ...config,
276
+ };
277
+ // Initialize libraries
278
+ await initializeSharp();
279
+ if (fullConfig.enableOCR) {
280
+ await initializeTesseract();
281
+ }
282
+ logger.info('Starting quality validation', {
283
+ imagePath,
284
+ ocrEnabled: fullConfig.enableOCR && tesseractAvailable,
285
+ });
286
+ const failureReasons = [];
287
+ const recommendations = [];
288
+ // Calculate sharpness
289
+ let sharpnessResult;
290
+ if (sharpAvailable) {
291
+ const sharpnessValue = await calculateSharpness(imagePath);
292
+ const sharpnessPassed = sharpnessValue >= fullConfig.minSharpness;
293
+ sharpnessResult = {
294
+ value: sharpnessValue,
295
+ passed: sharpnessPassed,
296
+ threshold: fullConfig.minSharpness,
297
+ };
298
+ if (!sharpnessPassed) {
299
+ failureReasons.push(`Low sharpness: ${sharpnessValue.toFixed(1)} (min: ${fullConfig.minSharpness})`);
300
+ recommendations.push('Image appears blurry - may need higher resolution or better AI model');
301
+ }
302
+ logger.debug('Sharpness calculated', sharpnessResult);
303
+ }
304
+ // Calculate brightness
305
+ let brightnessResult;
306
+ if (sharpAvailable) {
307
+ const brightnessValue = await calculateBrightness(imagePath);
308
+ const brightnessPassed = brightnessValue >= fullConfig.minBrightness &&
309
+ brightnessValue <= fullConfig.maxBrightness;
310
+ brightnessResult = {
311
+ value: brightnessValue,
312
+ passed: brightnessPassed,
313
+ minThreshold: fullConfig.minBrightness,
314
+ maxThreshold: fullConfig.maxBrightness,
315
+ };
316
+ if (!brightnessPassed) {
317
+ if (brightnessValue < fullConfig.minBrightness) {
318
+ failureReasons.push(`Too dark: ${brightnessValue.toFixed(1)} (min: ${fullConfig.minBrightness})`);
319
+ recommendations.push('Image is too dark - adjust prompt or generation parameters');
320
+ }
321
+ else {
322
+ failureReasons.push(`Too bright: ${brightnessValue.toFixed(1)} (max: ${fullConfig.maxBrightness})`);
323
+ recommendations.push('Image is too bright - adjust prompt or generation parameters');
324
+ }
325
+ }
326
+ logger.debug('Brightness calculated', brightnessResult);
327
+ }
328
+ // Perform OCR validation
329
+ let ocrResult;
330
+ if (fullConfig.enableOCR && tesseractAvailable) {
331
+ const ocr = await performOCR(imagePath, fullConfig);
332
+ ocrResult = ocr;
333
+ if (!ocr.passed) {
334
+ failureReasons.push(...ocr.issues);
335
+ recommendations.push('Text rendering issues detected - consider regenerating with enhanced prompt');
336
+ }
337
+ }
338
+ // Calculate overall quality score (0-100)
339
+ let score = 100;
340
+ if (sharpnessResult && !sharpnessResult.passed) {
341
+ score -= 30;
342
+ }
343
+ if (brightnessResult && !brightnessResult.passed) {
344
+ score -= 20;
345
+ }
346
+ if (ocrResult && !ocrResult.passed) {
347
+ score -= 30;
348
+ }
349
+ score = Math.max(0, Math.min(100, score));
350
+ // Overall pass/fail
351
+ const passed = score >= fullConfig.minQualityScore;
352
+ const result = {
353
+ passed,
354
+ score,
355
+ sharpness: sharpnessResult,
356
+ brightness: brightnessResult,
357
+ ocr: ocrResult,
358
+ failureReasons,
359
+ recommendations,
360
+ };
361
+ logger.info('Quality validation complete', {
362
+ passed,
363
+ score,
364
+ failureReasons: failureReasons.length,
365
+ });
366
+ return result;
367
+ }
368
+ /**
369
+ * Check if quality validation is available
370
+ */
371
+ export async function isQualityValidationAvailable() {
372
+ const sharp = await initializeSharp();
373
+ const tesseract = await initializeTesseract();
374
+ return {
375
+ sharpAvailable: sharp,
376
+ tesseractAvailable: tesseract,
377
+ fullyAvailable: sharp && tesseract,
378
+ };
379
+ }
380
+ /**
381
+ * Get default quality validation configuration
382
+ */
383
+ export function getDefaultQualityConfig() {
384
+ return { ...DEFAULT_CONFIG };
385
+ }
386
+ //# sourceMappingURL=quality-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality-validator.js","sourceRoot":"","sources":["../../src/utils/quality-validator.ts"],"names":[],"mappings":"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"}