@@ -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