Skip to content

Commit 22dc728

Browse files
ofriwclaude
andcommitted
Add validation for 3-5 content items per slide
- Add two-step takeaway condensation process to prompt - Implement validateContentArrayLengths() function - Enforce 3-5 item constraint with build failure - Check both regular and comparison slide content 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent c2e16dc commit 22dc728

File tree

1 file changed

+115
-1
lines changed

1 file changed

+115
-1
lines changed

scripts/generate-presentation.js

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -566,14 +566,31 @@ INCORRECT: Putting the better option on the left will show it with RED ✗ styli
566566
]
567567
}
568568
569+
KEY TAKEAWAYS GENERATION (TWO-STEP PROCESS):
570+
571+
When creating the "takeaway" slide at the end of the presentation:
572+
573+
STEP 1: First, review the lesson and mentally list ALL significant takeaways
574+
- Identify every important concept, pattern, or insight from the lesson
575+
- Don't filter yet—just enumerate everything worth remembering
576+
577+
STEP 2: Then, condense to the 3-5 MOST critical takeaways
578+
- Prioritize by impact and generality (what will matter most in production?)
579+
- Combine related points into higher-level insights when possible
580+
- Remove redundant or overly specific points
581+
- Ensure each takeaway is actionable and memorable
582+
583+
IMPORTANT: The final takeaway slide MUST have exactly 3-5 items, even if the source material lists more.
584+
Quality over quantity—choose the most impactful insights.
585+
569586
CRITICAL REQUIREMENTS:
570587
571588
1. The output MUST be valid JSON - no preamble, no explanation, just the JSON object
572589
2. Write the JSON directly to the file: ${outputPath}
573590
3. Include 8-15 slides (no more, no less)
574591
4. Every slide MUST have speakerNotes with all fields
575592
5. Code examples must be actual code from the lesson, not pseudocode
576-
6. Content arrays must have 3-5 items (except title slide)
593+
6. Content arrays MUST have 3-5 items (except title slide) - THIS IS STRICTLY ENFORCED
577594
7. PROMPT EXAMPLES: Use "code" or "codeComparison" slide types, NEVER bullet points
578595
579596
BEFORE YOU GENERATE - CHECKLIST:
@@ -842,6 +859,85 @@ function validateComparisonSemantics(presentation) {
842859
};
843860
}
844861

862+
/**
863+
* Validate that content arrays have 3-5 items maximum
864+
* @param {object} presentation - Generated presentation object
865+
* @returns {object} Validation result with issues
866+
*/
867+
function validateContentArrayLengths(presentation) {
868+
const issues = [];
869+
const MIN_ITEMS = 3;
870+
const MAX_ITEMS = 5;
871+
872+
// Slide types that must have content arrays with 3-5 items
873+
const slidesWithContent = presentation.slides.filter(slide => {
874+
// Skip title slide (different rules)
875+
if (slide.type === 'title') return false;
876+
877+
// Check slides with content arrays
878+
return slide.content && Array.isArray(slide.content);
879+
});
880+
881+
for (const slide of slidesWithContent) {
882+
const contentLength = slide.content.length;
883+
884+
if (contentLength < MIN_ITEMS || contentLength > MAX_ITEMS) {
885+
issues.push({
886+
slide: slide.title || slide.type,
887+
type: slide.type,
888+
count: contentLength,
889+
reason: contentLength < MIN_ITEMS
890+
? `Only ${contentLength} item(s), need at least ${MIN_ITEMS}`
891+
: `Has ${contentLength} item(s), maximum is ${MAX_ITEMS}`
892+
});
893+
}
894+
}
895+
896+
// Check comparison slides (left/right content)
897+
const comparisonSlides = presentation.slides.filter(s =>
898+
s.type === 'comparison' || s.type === 'marketingReality'
899+
);
900+
901+
for (const slide of comparisonSlides) {
902+
const leftContent = slide.left?.content || slide.metaphor?.content;
903+
const rightContent = slide.right?.content || slide.reality?.content;
904+
905+
if (leftContent && Array.isArray(leftContent)) {
906+
const leftLength = leftContent.length;
907+
if (leftLength < MIN_ITEMS || leftLength > MAX_ITEMS) {
908+
issues.push({
909+
slide: `${slide.title} (LEFT)`,
910+
type: slide.type,
911+
count: leftLength,
912+
reason: leftLength < MIN_ITEMS
913+
? `Only ${leftLength} item(s), need at least ${MIN_ITEMS}`
914+
: `Has ${leftLength} item(s), maximum is ${MAX_ITEMS}`
915+
});
916+
}
917+
}
918+
919+
if (rightContent && Array.isArray(rightContent)) {
920+
const rightLength = rightContent.length;
921+
if (rightLength < MIN_ITEMS || rightLength > MAX_ITEMS) {
922+
issues.push({
923+
slide: `${slide.title} (RIGHT)`,
924+
type: slide.type,
925+
count: rightLength,
926+
reason: rightLength < MIN_ITEMS
927+
? `Only ${rightLength} item(s), need at least ${MIN_ITEMS}`
928+
: `Has ${rightLength} item(s), maximum is ${MAX_ITEMS}`
929+
});
930+
}
931+
}
932+
}
933+
934+
return {
935+
valid: issues.length === 0,
936+
issues,
937+
totalSlidesChecked: slidesWithContent.length + comparisonSlides.length
938+
};
939+
}
940+
845941
/**
846942
* Validate that prompt examples are preserved as code blocks
847943
* @param {string} content - Parsed markdown content
@@ -987,6 +1083,24 @@ async function generatePresentation(filePath, manifest, config) {
9871083
console.log(` ✅ All ${semanticValidation.totalComparisons} comparison slide(s) follow correct convention`);
9881084
}
9891085

1086+
// Validate content array lengths (3-5 items)
1087+
// CRITICAL: This validation is intentionally strict and throws an error because
1088+
// slides with too many bullets become unreadable and overflow the layout.
1089+
// The two-step condensation process in the prompt should prevent this.
1090+
const contentValidation = validateContentArrayLengths(presentation);
1091+
if (!contentValidation.valid) {
1092+
console.log(` ❌ BUILD FAILURE: ${contentValidation.issues.length} content array violation(s):`);
1093+
contentValidation.issues.forEach(issue => {
1094+
console.log(` - Slide "${issue.slide}" (${issue.type}): ${issue.reason}`);
1095+
});
1096+
console.log(` ℹ️ All content arrays MUST have 3-5 items (except title slide)`);
1097+
console.log(` ℹ️ For takeaway slides: use the two-step condensation process`);
1098+
console.log(` ℹ️ The presentation was not saved. Fix the generation and try again.`);
1099+
throw new Error('Content array validation failed - slides have too many or too few items');
1100+
} else if (contentValidation.totalSlidesChecked > 0) {
1101+
console.log(` ✅ All ${contentValidation.totalSlidesChecked} content array(s) have 3-5 items`);
1102+
}
1103+
9901104
// Validate prompt examples are preserved as code
9911105
// CRITICAL: This validation is intentionally strict and throws an error because
9921106
// prompt examples are core educational content that must be preserved exactly.

0 commit comments

Comments
 (0)