Skip to content

Commit dcc08fe

Browse files
ofriwclaude
andcommitted
Add audit script for presentation content validation
Standalone utility to check all presentations for 3-5 item violations πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 945dc43 commit dcc08fe

File tree

1 file changed

+147
-0
lines changed

1 file changed

+147
-0
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* Audit all presentations for content array violations (3-5 items rule)
5+
*/
6+
7+
import { readFileSync } from 'fs';
8+
import { join, dirname } from 'path';
9+
import { fileURLToPath } from 'url';
10+
11+
const __filename = fileURLToPath(import.meta.url);
12+
const __dirname = dirname(__filename);
13+
14+
const MIN_ITEMS = 3;
15+
const MAX_ITEMS = 5;
16+
17+
function auditPresentation(filePath) {
18+
const content = readFileSync(filePath, 'utf-8');
19+
const presentation = JSON.parse(content);
20+
const violations = [];
21+
22+
// Check slides with content arrays
23+
const slidesWithContent = presentation.slides.filter(slide => {
24+
if (slide.type === 'title') return false;
25+
return slide.content && Array.isArray(slide.content);
26+
});
27+
28+
for (const slide of slidesWithContent) {
29+
const contentLength = slide.content.length;
30+
if (contentLength < MIN_ITEMS || contentLength > MAX_ITEMS) {
31+
violations.push({
32+
slide: slide.title || slide.type,
33+
type: slide.type,
34+
count: contentLength,
35+
items: slide.content
36+
});
37+
}
38+
}
39+
40+
// Check comparison slides (left/right content)
41+
const comparisonSlides = presentation.slides.filter(s =>
42+
s.type === 'comparison' || s.type === 'marketingReality'
43+
);
44+
45+
for (const slide of comparisonSlides) {
46+
const leftContent = slide.left?.content || slide.metaphor?.content;
47+
const rightContent = slide.right?.content || slide.reality?.content;
48+
49+
if (leftContent && Array.isArray(leftContent)) {
50+
const leftLength = leftContent.length;
51+
if (leftLength < MIN_ITEMS || leftLength > MAX_ITEMS) {
52+
violations.push({
53+
slide: `${slide.title} (LEFT)`,
54+
type: slide.type,
55+
count: leftLength,
56+
items: leftContent
57+
});
58+
}
59+
}
60+
61+
if (rightContent && Array.isArray(rightContent)) {
62+
const rightLength = rightContent.length;
63+
if (rightLength < MIN_ITEMS || rightLength > MAX_ITEMS) {
64+
violations.push({
65+
slide: `${slide.title} (RIGHT)`,
66+
type: slide.type,
67+
count: rightLength,
68+
items: rightContent
69+
});
70+
}
71+
}
72+
}
73+
74+
return {
75+
title: presentation.metadata?.title || 'Unknown',
76+
violations,
77+
totalSlides: presentation.slides.length
78+
};
79+
}
80+
81+
function main() {
82+
const presentationsDir = join(__dirname, '../website/static/presentations');
83+
const files = [
84+
'intro.json',
85+
'methodology/lesson-3-high-level-methodology.json',
86+
'methodology/lesson-4-prompting-101.json',
87+
'methodology/lesson-5-grounding.json',
88+
'practical-techniques/lesson-6-project-onboarding.json',
89+
'practical-techniques/lesson-7-planning-execution.json',
90+
'practical-techniques/lesson-8-tests-as-guardrails.json',
91+
'practical-techniques/lesson-9-reviewing-code.json',
92+
'practical-techniques/lesson-10-debugging.json',
93+
'understanding-the-tools/lesson-1-intro.json',
94+
'understanding-the-tools/lesson-2-understanding-agents.json'
95+
];
96+
97+
console.log('πŸ“Š Auditing presentations for content array violations (3-5 items rule)\n');
98+
99+
const results = [];
100+
let totalViolations = 0;
101+
102+
for (const file of files) {
103+
const filePath = join(presentationsDir, file);
104+
try {
105+
const result = auditPresentation(filePath);
106+
results.push({ file, ...result });
107+
108+
if (result.violations.length > 0) {
109+
totalViolations += result.violations.length;
110+
console.log(`❌ ${file}`);
111+
console.log(` Title: ${result.title}`);
112+
result.violations.forEach(v => {
113+
console.log(` - "${v.slide}" (${v.type}): ${v.count} items`);
114+
if (v.count <= 8) {
115+
v.items.forEach(item => {
116+
const truncated = item.length > 60 ? item.substring(0, 57) + '...' : item;
117+
console.log(` β€’ ${truncated}`);
118+
});
119+
}
120+
});
121+
console.log('');
122+
}
123+
} catch (error) {
124+
console.log(`⚠️ ${file}: Error reading file - ${error.message}\n`);
125+
}
126+
}
127+
128+
// Summary
129+
console.log('═══════════════════════════════════════════════════════════');
130+
const violatingFiles = results.filter(r => r.violations.length > 0);
131+
132+
if (violatingFiles.length === 0) {
133+
console.log('βœ… All presentations pass validation!');
134+
} else {
135+
console.log(`\nπŸ“‹ SUMMARY:\n`);
136+
console.log(`Total files audited: ${results.length}`);
137+
console.log(`Files with violations: ${violatingFiles.length}`);
138+
console.log(`Total violations: ${totalViolations}\n`);
139+
console.log('Files needing regeneration:');
140+
violatingFiles.forEach(r => {
141+
console.log(` - ${r.file} (${r.violations.length} violation(s))`);
142+
});
143+
}
144+
console.log('═══════════════════════════════════════════════════════════');
145+
}
146+
147+
main();

0 commit comments

Comments
Β (0)