@@ -1369,6 +1369,10 @@ async function generatePresentation(filePath, manifest, config) {
13691369 console.log(` ✅ All ${semanticValidation.totalComparisons} comparison slide(s) follow correct convention`);
13701370 }
13711371
1372+ // Collect validation errors instead of throwing immediately
1373+ // This allows us to write the presentation file even when validation fails
1374+ const validationErrors = [];
1375+
13721376 // Validate content array lengths (3-5 items)
13731377 // CRITICAL: This validation is intentionally strict and throws an error because
13741378 // slides with too many bullets become unreadable and overflow the layout.
@@ -1381,8 +1385,7 @@ async function generatePresentation(filePath, manifest, config) {
13811385 });
13821386 console.log(` ℹ️ All content arrays MUST have 3-5 items (except title slide)`);
13831387 console.log(` ℹ️ For takeaway slides: use the two-step condensation process`);
1384- console.log(` ℹ️ The presentation was not saved. Fix the generation and try again.`);
1385- throw new Error('Content array validation failed - slides have too many or too few items');
1388+ validationErrors.push('Content array validation failed - slides have too many or too few items');
13861389 } else if (contentValidation.totalSlidesChecked > 0) {
13871390 console.log(` ✅ All ${contentValidation.totalSlidesChecked} content array(s) have 3-5 items`);
13881391 }
@@ -1398,8 +1401,7 @@ async function generatePresentation(filePath, manifest, config) {
13981401 console.log(` - ${issue}`);
13991402 });
14001403 console.log(` ℹ️ Prompt examples MUST use "code" or "codeComparison" slide types, NOT bullet points`);
1401- console.log(` ℹ️ The presentation was not saved. Fix the generation and try again.`);
1402- throw new Error('Prompt validation failed - prompt examples were converted to bullet points instead of code blocks');
1404+ validationErrors.push('Prompt validation failed - prompt examples were converted to bullet points instead of code blocks');
14031405 } else if (promptValidation.hasPromptExamples) {
14041406 console.log(` ✅ All prompt examples preserved as code blocks (${promptValidation.codeSlideCount} code slide(s))`);
14051407 }
@@ -1415,8 +1417,7 @@ async function generatePresentation(filePath, manifest, config) {
14151417 });
14161418 console.log(` ℹ️ All code in slides MUST exist verbatim in the source markdown`);
14171419 console.log(` ℹ️ DO NOT generate hypothetical implementations to demonstrate prompts`);
1418- console.log(` ℹ️ The presentation was not saved. Fix the generation and try again.`);
1419- throw new Error('Code source validation failed - slides contain fabricated code not in source');
1420+ validationErrors.push('Code source validation failed - slides contain fabricated code not in source');
14201421 } else if (codeSourceValidation.codeSlidesChecked > 0) {
14211422 console.log(` ✅ All ${codeSourceValidation.codeSlidesChecked} code slide(s) verified against source`);
14221423 }
@@ -1434,8 +1435,7 @@ async function generatePresentation(filePath, manifest, config) {
14341435 });
14351436 console.log(` ℹ️ All takeaway items MUST be 5 words or fewer for memorability`);
14361437 console.log(` ℹ️ Examples: "Tests ground agent code quality" (5) ✓ | "Tests are critical for agent workflows" (6) ✗`);
1437- console.log(` ℹ️ The presentation was not saved. Fix the generation and try again.`);
1438- throw new Error('Takeaway validation failed - items exceed 5-word limit');
1438+ validationErrors.push('Takeaway validation failed - items exceed 5-word limit');
14391439 } else if (takeawayValidation.totalTakeawaysChecked > 0) {
14401440 console.log(` ✅ All ${takeawayValidation.totalTakeawaysChecked} takeaway item(s) are 5 words or fewer`);
14411441 }
@@ -1453,13 +1453,12 @@ async function generatePresentation(filePath, manifest, config) {
14531453 });
14541454 console.log(` ℹ️ All learning objectives MUST be 5 words or fewer for clarity`);
14551455 console.log(` ℹ️ Examples: "Master active context engineering" (4) ✓ | "Learn how to master active context" (6) ✗`);
1456- console.log(` ℹ️ The presentation was not saved. Fix the generation and try again.`);
1457- throw new Error('Learning objectives validation failed - items exceed 5-word limit');
1456+ validationErrors.push('Learning objectives validation failed - items exceed 5-word limit');
14581457 } else if (objectivesValidation.totalObjectivesChecked > 0) {
14591458 console.log(` ✅ All ${objectivesValidation.totalObjectivesChecked} learning objective(s) are 5 words or fewer`);
14601459 }
14611460
1462- // Write presentation to output file
1461+ // Write presentation to output file (even if validation failed)
14631462 writeFileSync(outputPath, JSON.stringify(presentation, null, 2), 'utf-8');
14641463
14651464 // Copy to static directory for deployment
@@ -1477,10 +1476,16 @@ async function generatePresentation(filePath, manifest, config) {
14771476 generatedAt: new Date().toISOString()
14781477 };
14791478
1480- console.log(` ✅ Generated: ${presentationUrl}`);
1479+ console.log(` ${validationErrors.length > 0 ? '⚠️' : '✅'} Generated: ${presentationUrl}`);
14811480 console.log(` 📊 Slides: ${presentation.slides.length}`);
14821481 console.log(` ⏱️ Duration: ${presentation.metadata.estimatedDuration}`);
14831482
1483+ // Throw validation errors after writing files
1484+ if (validationErrors.length > 0) {
1485+ console.log(` ℹ️ The presentation was saved despite validation failures for inspection.`);
1486+ throw new Error(`Validation failed with ${validationErrors.length} error(s):\n - ${validationErrors.join('\n - ')}`);
1487+ }
1488+
14841489 return outputPath;
14851490
14861491 } catch (error) {
0 commit comments