MCPcopy Create free account
hub / github.com/MigoXLab/coderio / validationLoop

Function validationLoop

src/nodes/validation/core/validation-loop.ts:198–552  ·  view source on GitHub ↗
(params: ValidationLoopParams)

Source from the content-addressed store, hash-verified

196}
197
198export async function validationLoop(params: ValidationLoopParams): Promise<ValidationLoopResult> {
199 // Ensure dependencies are installed before starting validation loop
200 ensureValidationDependencies();
201
202 const { protocol, figmaThumbnailUrl, outputDir, workspace } = params;
203
204 if (!protocol || !figmaThumbnailUrl || !outputDir || !workspace) {
205 throw new Error('Something wrong in validation loop, missing required parameters...');
206 }
207
208 const config: ValidationLoopConfig = {
209 ...DEFAULT_VALIDATION_LOOP_CONFIG,
210 ...params.config,
211 };
212 const mode: ValidationMode.ReportOnly | ValidationMode.Full = config.mode ?? ValidationMode.Full;
213 const maxIterations = mode === ValidationMode.ReportOnly ? 1 : config.maxIterations;
214 const visualizationTool = new VisualizationTool();
215
216 // Variables to track server state (will be initialized in iteration 1)
217 let currentServerUrl: string | undefined;
218 let serverKey: string | undefined;
219
220 try {
221 // Extract unified validation context from protocol (single traversal)
222 const validationContext = extractValidationContext(protocol);
223 const designOffset: [number, number] = [validationContext.offset.x, validationContext.offset.y];
224 if (Math.abs(designOffset[0]) >= 1 || Math.abs(designOffset[1]) >= 1) {
225 logger.printInfoLog(`Design offset: (${designOffset[0].toFixed(0)}, ${designOffset[1].toFixed(0)} px)`);
226 }
227
228 // Extract component paths from context (already resolved to absolute filesystem paths)
229 const resolvedComponentPaths = extractComponentPaths(validationContext, workspace);
230
231 // Build element registry for compatibility with existing APIs
232 const elementRegistry = toElementMetadataRegistry(validationContext);
233
234 // Download and cache Figma thumbnail once to avoid redundant downloads in each iteration
235 logger.printInfoLog('Downloading Figma thumbnail (will be cached for all iterations)...');
236 const cachedFigmaThumbnailBase64 = await downloadImage(figmaThumbnailUrl, undefined, undefined, true);
237 logger.printSuccessLog('Figma thumbnail cached successfully');
238
239 const iterations: IterationLog[] = [];
240 const componentHistory: ComponentHistory = {};
241 let previousScreenshotPath: string | undefined;
242 let currentMae = -1; // Sentinel value: -1 indicates no measurement yet
243 let currentSae = 0;
244 let lastMisalignedCount = 0;
245 let lastValidationResult: ValidationIterationResult | undefined;
246 // Track paths to last iteration's individual screenshots for report reuse
247 let lastRenderMarkedPath: string | undefined;
248 let lastTargetMarkedPath: string | undefined;
249
250 for (let iteration = 1; iteration <= maxIterations; iteration++) {
251 // Use different logging for reportOnly mode
252 if (mode === ValidationMode.ReportOnly) {
253 logger.printLog(`\n${'='.repeat(60)}`);
254 logger.printLog(`Running validation (report-only mode)`);
255 logger.printLog(`${'='.repeat(60)}`);

Callers 1

runValidationFunction · 0.90

Calls 15

stopDevServerMethod · 0.95
extractValidationContextFunction · 0.90
extractComponentPathsFunction · 0.90
downloadImageFunction · 0.90
launchFunction · 0.90
validatePositionsFunction · 0.90
reportFunction · 0.90
performCommitFunction · 0.85
filterComponentsToFixFunction · 0.85

Tested by

no test coverage detected